diff --git a/.github/workflows/commit-stage.yml b/.github/workflows/commit-stage.yml index 459fb10..df7bed3 100644 --- a/.github/workflows/commit-stage.yml +++ b/.github/workflows/commit-stage.yml @@ -12,7 +12,6 @@ jobs: runs-on: ubuntu-24.04 permissions: contents: read - security-events: write steps: - name: Checkout source code uses: actions/checkout@v4 @@ -27,6 +26,7 @@ jobs: cd 06-knative/basic/book-service chmod +x gradlew ./gradlew build + package: name: Package and Publish if: ${{ github.ref == 'refs/heads/main' }} @@ -35,27 +35,148 @@ jobs: permissions: contents: read packages: write - security-events: write + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + - name: Checkout source code uses: actions/checkout@v4 - - name: Set up Java - uses: actions/setup-java@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Pack + uses: buildpacks/github-actions/setup-pack@v5.0.0 with: - java-version: 22 - distribution: temurin - cache: gradle - - name: Build container image - run: | - cd 06-knative/basic/book-service - chmod +x gradlew - ./gradlew bootBuildImage \ - --imageName ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }} - - name: Authenticate with the container registry + pack-version: 0.34.2 + + - name: Login to container registry uses: docker/login-action@v3 with: + username: ${{ github.actor }} + password: ${{ secrets.IMAGE_PUSH_TOKEN }} registry: ${{ env.REGISTRY }} + + - name: Build and publish OCI image + run: | + pack build ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ + --builder docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny \ + --buildpack gcr.io/paketo-buildpacks/java \ + --env BP_JVM_VERSION=22 \ + --path 06-knative/basic/book-service \ + --platform ${{ matrix.platform }} \ + --report-output-dir ./report.toml \ + --publish + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest=$(grep 'digest' report.toml | sed 's/.*= "\(.*\)"/\1/') + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.IMAGE_NAME }}-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + needs: [ package ] + runs-on: ubuntu-24.04 + permissions: + attestations: write + contents: read + id-token: write + packages: write + outputs: + image-digest: ${{ steps.image-info.outputs.digest }} + image-name: ${{ steps.image-info.outputs.name }} + steps: + + - name: Prepare + run: | + timestamp=$(date +%Y%m%d-%H%M%S) + echo "TIMESTAMP=${timestamp}" >> $GITHUB_ENV + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-${{ env.IMAGE_NAME }}-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.5.0 + + - name: Generate Docker meta information + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + labels: | + org.opencontainers.image.licenses=Apache-2.0 + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.version=${{ github.sha }} + org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} + tags: | + type=raw,value=${{ env.TIMESTAMP }},enable={{is_default_branch}} + type=raw,value=latest,enable={{is_default_branch}} + type=sha,format=long + + - name: Login to container registry + uses: docker/login-action@v3 + with: username: ${{ github.actor }} password: ${{ secrets.IMAGE_PUSH_TOKEN }} - - name: Publish container image - run: docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }} + registry: ${{ env.REGISTRY }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.meta.outputs.version }} + + - name: Setup Arkade + uses: alexellis/setup-arkade@v2 + + - name: Install crane + uses: alexellis/arkade-get@master + with: + crane: v0.19.2 + + - name: Get OCI image digest + id: image-info + run: | + image_digest=$(crane digest ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.meta.outputs.version }}) + echo $image_digest + echo "IMAGE_DIGEST=${image_digest}" >> $GITHUB_ENV + + - name: Sign image + run: | + cosign sign --yes ${{ env.REGISTRY }}/${{ env.IMAGE }}@${{ env.IMAGE_DIGEST }} + + - name: Generate SLSA Build Attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE }} + subject-digest: ${{ env.IMAGE_DIGEST }} + push-to-registry: true + github-token: ${{ secrets.push-token }} diff --git a/01-java/basic/book-service/build.gradle b/01-java/basic/book-service/build.gradle index f6ce1b3..b6e9d6f 100644 --- a/01-java/basic/book-service/build.gradle +++ b/01-java/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { diff --git a/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/01-java/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/01-java/basic/book-service/gradlew b/01-java/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/01-java/basic/book-service/gradlew +++ b/01-java/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/01-java/basic/book-service/gradlew.bat b/01-java/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/01-java/basic/book-service/gradlew.bat +++ b/01-java/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/01-java/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/01-java/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/01-java/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/01-java/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/01-java/live-reload/book-service/build.gradle b/01-java/live-reload/book-service/build.gradle index 9e9c56f..e6b6134 100644 --- a/01-java/live-reload/book-service/build.gradle +++ b/01-java/live-reload/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -24,7 +24,7 @@ dependencies { developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { diff --git a/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar b/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar and b/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties b/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/01-java/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/01-java/live-reload/book-service/gradlew b/01-java/live-reload/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/01-java/live-reload/book-service/gradlew +++ b/01-java/live-reload/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/01-java/live-reload/book-service/gradlew.bat b/01-java/live-reload/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/01-java/live-reload/book-service/gradlew.bat +++ b/01-java/live-reload/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/01-java/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/01-java/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..6b2a055 100644 --- a/01-java/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/01-java/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -1,7 +1,5 @@ package com.thomasvitale.bookservice; -import java.util.List; - import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -9,6 +7,8 @@ import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerResponse; +import java.util.List; + @SpringBootApplication public class BookServiceApplication { @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/02-container-image/README.md b/02-container-image/README.md index a441796..474fb1c 100644 --- a/02-container-image/README.md +++ b/02-container-image/README.md @@ -19,7 +19,7 @@ Then, package the application as a JAR. Explore the three different Dockerfiles with different levels of optimizations in terms of performance and security. You can build a container image as follows. ```shell -docker build -f Dockerfile_v3 -t book-service . +docker build -f Dockerfile_v3 -t book-service . --load ``` You can run the application on Docker as follows. @@ -38,17 +38,11 @@ cd buildpacks/book-service You can use the [`pack`](https://buildpacks.io/docs/tools/pack/) CLI from the Cloud Native Buildpacks project to package the application as a container image. -```shell -pack build book-service --builder docker.io/paketobuildpacks/builder-jammy-tiny --env BP_JVM_VERSION=21 -``` - -On ARM64 machines, use the following. - ```shell pack build book-service \ --builder docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny \ - --buildpack gcr.io/paketo-buildpacks/java:beta \ - --env BP_JVM_VERSION=21 + --buildpack gcr.io/paketo-buildpacks/java \ + --env BP_JVM_VERSION=22 ``` For Spring Boot projects, Buildpacks integration is provided directly by the Spring Boot plugins for [Maven](https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/#build-image) and [Gradle](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#build-image), so you don't need to install any additional tool. @@ -63,7 +57,7 @@ Either way, you can run the application as follows. docker compose up -d ``` -You can also debug the application from your IDE. Check out the configuration in the `docker-compose.yml` file, where the debug mode is enabled via convenient Buildpacks environment variables. Then, configure your IDE with a remote debugger on port `9090` and try out debugging the application while running as a container. +You can also debug the application from your IDE. Check out the configuration in the `compose.yml` file, where the debug mode is enabled via convenient Buildpacks environment variables. Then, configure your IDE with a remote debugger on port `9090` and try out debugging the application while running as a container. ## Live Reload diff --git a/02-container-image/basic/book-service/Dockerfile_v1 b/02-container-image/basic/book-service/Dockerfile_v1 index d6b6f56..ecd44a3 100644 --- a/02-container-image/basic/book-service/Dockerfile_v1 +++ b/02-container-image/basic/book-service/Dockerfile_v1 @@ -1,4 +1,4 @@ -FROM eclipse-temurin:21 +FROM eclipse-temurin:22-jre WORKDIR /workspace ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar diff --git a/02-container-image/basic/book-service/Dockerfile_v2 b/02-container-image/basic/book-service/Dockerfile_v2 index a87ceac..6687893 100644 --- a/02-container-image/basic/book-service/Dockerfile_v2 +++ b/02-container-image/basic/book-service/Dockerfile_v2 @@ -1,13 +1,13 @@ -FROM eclipse-temurin:21 AS builder +FROM eclipse-temurin:22-jre AS builder WORKDIR /workspace ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -RUN java -Djarmode=layertools -jar app.jar extract +RUN java -Djarmode=tools -jar app.jar extract --layers --destination app -FROM eclipse-temurin:21 +FROM eclipse-temurin:22-jre WORKDIR /workspace -COPY --from=builder workspace/dependencies/ ./ -COPY --from=builder workspace/spring-boot-loader/ ./ -COPY --from=builder workspace/snapshot-dependencies/ ./ -COPY --from=builder workspace/application/ ./ -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +COPY --from=builder workspace/app/dependencies/ ./ +COPY --from=builder workspace/app/spring-boot-loader/ ./ +COPY --from=builder workspace/app/snapshot-dependencies/ ./ +COPY --from=builder workspace/app/application/ ./ +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/02-container-image/basic/book-service/Dockerfile_v3 b/02-container-image/basic/book-service/Dockerfile_v3 index d65b039..f091df9 100644 --- a/02-container-image/basic/book-service/Dockerfile_v3 +++ b/02-container-image/basic/book-service/Dockerfile_v3 @@ -1,15 +1,15 @@ -FROM eclipse-temurin:21-jre AS builder +FROM eclipse-temurin:22-jre AS builder WORKDIR /workspace ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -RUN java -Djarmode=layertools -jar app.jar extract +RUN java -Djarmode=tools -jar app.jar extract --layers --destination app -FROM eclipse-temurin:21-jre +FROM eclipse-temurin:22-jre RUN useradd spring USER spring WORKDIR /workspace -COPY --from=builder workspace/dependencies/ ./ -COPY --from=builder workspace/spring-boot-loader/ ./ -COPY --from=builder workspace/snapshot-dependencies/ ./ -COPY --from=builder workspace/application/ ./ -ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file +COPY --from=builder workspace/app/dependencies/ ./ +COPY --from=builder workspace/app/spring-boot-loader/ ./ +COPY --from=builder workspace/app/snapshot-dependencies/ ./ +COPY --from=builder workspace/app/application/ ./ +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/02-container-image/basic/book-service/build.gradle b/02-container-image/basic/book-service/build.gradle index 721cbb6..64a0ebb 100644 --- a/02-container-image/basic/book-service/build.gradle +++ b/02-container-image/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { diff --git a/02-container-image/basic/book-service/docker-compose.yml b/02-container-image/basic/book-service/compose.yml similarity index 100% rename from 02-container-image/basic/book-service/docker-compose.yml rename to 02-container-image/basic/book-service/compose.yml diff --git a/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/02-container-image/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/02-container-image/basic/book-service/gradlew b/02-container-image/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/02-container-image/basic/book-service/gradlew +++ b/02-container-image/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/02-container-image/basic/book-service/gradlew.bat b/02-container-image/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/02-container-image/basic/book-service/gradlew.bat +++ b/02-container-image/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/02-container-image/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/02-container-image/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/02-container-image/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/02-container-image/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/02-container-image/buildpacks/book-service/build.gradle b/02-container-image/buildpacks/book-service/build.gradle index 3298dd3..b4e5374 100644 --- a/02-container-image/buildpacks/book-service/build.gradle +++ b/02-container-image/buildpacks/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,12 +34,8 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" - buildpacks = [ "gcr.io/paketo-buildpacks/java:beta" ] - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-tiny" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" } diff --git a/02-container-image/buildpacks/book-service/docker-compose.yml b/02-container-image/buildpacks/book-service/compose.yml similarity index 100% rename from 02-container-image/buildpacks/book-service/docker-compose.yml rename to 02-container-image/buildpacks/book-service/compose.yml diff --git a/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.jar b/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.jar and b/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.properties b/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/02-container-image/buildpacks/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/02-container-image/buildpacks/book-service/gradlew b/02-container-image/buildpacks/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/02-container-image/buildpacks/book-service/gradlew +++ b/02-container-image/buildpacks/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/02-container-image/buildpacks/book-service/gradlew.bat b/02-container-image/buildpacks/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/02-container-image/buildpacks/book-service/gradlew.bat +++ b/02-container-image/buildpacks/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/02-container-image/buildpacks/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/02-container-image/buildpacks/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/02-container-image/buildpacks/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/02-container-image/buildpacks/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/02-container-image/live-reload/book-service/build.gradle b/02-container-image/live-reload/book-service/build.gradle index 8ca0c08..7270c73 100644 --- a/02-container-image/live-reload/book-service/build.gradle +++ b/02-container-image/live-reload/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,12 +34,8 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" - buildpacks = [ "gcr.io/paketo-buildpacks/java:beta" ] - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-tiny" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" environment = ["BP_LIVE_RELOAD_ENABLED": "true"] diff --git a/02-container-image/live-reload/book-service/docker-compose.yml b/02-container-image/live-reload/book-service/compose.yml similarity index 100% rename from 02-container-image/live-reload/book-service/docker-compose.yml rename to 02-container-image/live-reload/book-service/compose.yml diff --git a/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar b/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar and b/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties b/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/02-container-image/live-reload/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/02-container-image/live-reload/book-service/gradlew b/02-container-image/live-reload/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/02-container-image/live-reload/book-service/gradlew +++ b/02-container-image/live-reload/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/02-container-image/live-reload/book-service/gradlew.bat b/02-container-image/live-reload/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/02-container-image/live-reload/book-service/gradlew.bat +++ b/02-container-image/live-reload/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/02-container-image/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/02-container-image/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/02-container-image/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/02-container-image/live-reload/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/03-kubernetes/basic/book-service/build.gradle b/03-kubernetes/basic/book-service/build.gradle index 3298dd3..b4e5374 100644 --- a/03-kubernetes/basic/book-service/build.gradle +++ b/03-kubernetes/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,12 +34,8 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" - buildpacks = [ "gcr.io/paketo-buildpacks/java:beta" ] - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-tiny" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" } diff --git a/03-kubernetes/basic/book-service/docker-compose.yml b/03-kubernetes/basic/book-service/compose.yml similarity index 100% rename from 03-kubernetes/basic/book-service/docker-compose.yml rename to 03-kubernetes/basic/book-service/compose.yml diff --git a/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/03-kubernetes/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/03-kubernetes/basic/book-service/gradlew b/03-kubernetes/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/03-kubernetes/basic/book-service/gradlew +++ b/03-kubernetes/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/03-kubernetes/basic/book-service/gradlew.bat b/03-kubernetes/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/03-kubernetes/basic/book-service/gradlew.bat +++ b/03-kubernetes/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/03-kubernetes/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/03-kubernetes/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/03-kubernetes/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/03-kubernetes/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/04-tilt/README.md b/04-tilt/README.md index cedb1f1..fa41b32 100644 --- a/04-tilt/README.md +++ b/04-tilt/README.md @@ -34,6 +34,7 @@ custom_build( # Name of the container image ref = 'book-service', # Command to build the container image + # On Windows, replace $EXPECTED_REF with %EXPECTED_REF% command = './gradlew bootBuildImage --imageName $EXPECTED_REF', # Files to watch that trigger a new build deps = [ 'build.gradle', './build/classes/java/main', './build/resources/main' ], diff --git a/04-tilt/basic/book-service/Tiltfile b/04-tilt/basic/book-service/Tiltfile index a39e4c2..84bdb04 100644 --- a/04-tilt/basic/book-service/Tiltfile +++ b/04-tilt/basic/book-service/Tiltfile @@ -3,6 +3,7 @@ custom_build( # Name of the container image ref = 'book-service', # Command to build the container image + # On Windows, replace $EXPECTED_REF with %EXPECTED_REF% command = './gradlew bootBuildImage --imageName $EXPECTED_REF', # Files to watch that trigger a new build deps = ['build.gradle', './bin/main'], diff --git a/04-tilt/basic/book-service/build.gradle b/04-tilt/basic/book-service/build.gradle index b456df4..7270c73 100644 --- a/04-tilt/basic/book-service/build.gradle +++ b/04-tilt/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,11 +34,9 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/dashaun/builder:base" - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-base" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" + environment = ["BP_LIVE_RELOAD_ENABLED": "true"] } diff --git a/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/04-tilt/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/04-tilt/basic/book-service/gradlew b/04-tilt/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/04-tilt/basic/book-service/gradlew +++ b/04-tilt/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/04-tilt/basic/book-service/gradlew.bat b/04-tilt/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/04-tilt/basic/book-service/gradlew.bat +++ b/04-tilt/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/04-tilt/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/04-tilt/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/04-tilt/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/04-tilt/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/04-tilt/basic/docker-compose.yml b/04-tilt/basic/compose.yml similarity index 100% rename from 04-tilt/basic/docker-compose.yml rename to 04-tilt/basic/compose.yml diff --git a/04-tilt/basic/music-service/Tiltfile b/04-tilt/basic/music-service/Tiltfile index 8cda79c..b750ff5 100644 --- a/04-tilt/basic/music-service/Tiltfile +++ b/04-tilt/basic/music-service/Tiltfile @@ -3,6 +3,7 @@ custom_build( # Name of the container image ref = 'music-service', # Command to build the container image + # On Windows, replace $EXPECTED_REF with %EXPECTED_REF% command = './gradlew bootBuildImage --imageName $EXPECTED_REF', # Files to watch that trigger a new build deps = ['build.gradle', './bin/main'], diff --git a/04-tilt/basic/music-service/build.gradle b/04-tilt/basic/music-service/build.gradle index de7332f..f4897e3 100644 --- a/04-tilt/basic/music-service/build.gradle +++ b/04-tilt/basic/music-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,12 +34,9 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/dashaun/builder:base" - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-base" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] - imageName = "book-service" + imageName = "music-service" environment = ["BP_LIVE_RELOAD_ENABLED": "true"] } diff --git a/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.jar b/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.jar and b/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.properties b/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.properties +++ b/04-tilt/basic/music-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/04-tilt/basic/music-service/gradlew b/04-tilt/basic/music-service/gradlew index 1aa94a4..f5feea6 100755 --- a/04-tilt/basic/music-service/gradlew +++ b/04-tilt/basic/music-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/04-tilt/basic/music-service/gradlew.bat b/04-tilt/basic/music-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/04-tilt/basic/music-service/gradlew.bat +++ b/04-tilt/basic/music-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/04-tilt/basic/music-service/src/main/java/com/thomasvitale/musicservice/MusicServiceApplication.java b/04-tilt/basic/music-service/src/main/java/com/thomasvitale/musicservice/MusicServiceApplication.java index 12dd546..f0cbba1 100644 --- a/04-tilt/basic/music-service/src/main/java/com/thomasvitale/musicservice/MusicServiceApplication.java +++ b/04-tilt/basic/music-service/src/main/java/com/thomasvitale/musicservice/MusicServiceApplication.java @@ -19,7 +19,7 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body(List.of( new Music("Måneskin"), new Music("Guns n' Roses"), new Music("Led Zeppelin") diff --git a/05-skaffold/README.md b/05-skaffold/README.md index 59bfe83..38cc696 100644 --- a/05-skaffold/README.md +++ b/05-skaffold/README.md @@ -33,7 +33,7 @@ The Skaffold setup in the `skaffold.yml` file is tuned to work with Visual Studi If you use IntelliJ IDEA, refer to the [official documentation](https://www.jetbrains.com/help/idea/spring-boot.html#application-update-policies) to enable live reload in the IDE. You also need to update the `skaffold.yml` file and change the folders monitored by Skaffold for the live reload functionality. For more information on how it works, refer to the Paketo [official documentation](https://paketo.io/docs/howto/java/#enable-process-reloading). ```yaml -apiVersion: skaffold/v4beta10 +apiVersion: skaffold/v4beta11 kind: Config metadata: name: book-service @@ -41,11 +41,11 @@ build: artifacts: - image: book-service buildpacks: - # Change to docker.io/paketobuildpacks/builder-jammy-base on ARM64 - builder: docker.io/dashaun/builder:base - trustBuilder: true + builder: docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny + buildpacks: + - gcr.io/paketo-buildpacks/java env: - - BP_JVM_VERSION=21 + - BP_JVM_VERSION=22 - BP_LIVE_RELOAD_ENABLED=true dependencies: paths: diff --git a/05-skaffold/basic/book-service/build.gradle b/05-skaffold/basic/book-service/build.gradle index b456df4..b4e5374 100644 --- a/05-skaffold/basic/book-service/build.gradle +++ b/05-skaffold/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,11 +34,8 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/dashaun/builder:base" - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-base" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" } diff --git a/05-skaffold/basic/book-service/docker-compose.yml b/05-skaffold/basic/book-service/compose.yml similarity index 100% rename from 05-skaffold/basic/book-service/docker-compose.yml rename to 05-skaffold/basic/book-service/compose.yml diff --git a/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/05-skaffold/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/05-skaffold/basic/book-service/gradlew b/05-skaffold/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/05-skaffold/basic/book-service/gradlew +++ b/05-skaffold/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/05-skaffold/basic/book-service/gradlew.bat b/05-skaffold/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/05-skaffold/basic/book-service/gradlew.bat +++ b/05-skaffold/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/05-skaffold/basic/book-service/skaffold.yml b/05-skaffold/basic/book-service/skaffold.yml index d1b8abe..ca3d28e 100644 --- a/05-skaffold/basic/book-service/skaffold.yml +++ b/05-skaffold/basic/book-service/skaffold.yml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v4beta10 +apiVersion: skaffold/v4beta11 kind: Config metadata: name: book-service @@ -6,11 +6,11 @@ build: artifacts: - image: book-service buildpacks: - # Change to docker.io/paketobuildpacks/builder-jammy-base on ARM64 - builder: docker.io/dashaun/builder:base - trustBuilder: true + builder: docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny + buildpacks: + - gcr.io/paketo-buildpacks/java env: - - BP_JVM_VERSION=21 + - BP_JVM_VERSION=22 - BP_LIVE_RELOAD_ENABLED=true dependencies: paths: @@ -29,5 +29,4 @@ build: manifests: rawYaml: - config/deployment.yml - - config/ingress.yml - config/service.yml diff --git a/05-skaffold/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/05-skaffold/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/05-skaffold/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/05-skaffold/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/06-knative/README.md b/06-knative/README.md index bae3f69..e3dd176 100644 --- a/06-knative/README.md +++ b/06-knative/README.md @@ -14,7 +14,7 @@ Navigate to the `basic` folder. cd basic/book-service ``` -Then, you can containerize and publish the application image to a container registry. I have already done that and the image is available on my GitHub Container Registry: `ghcr.io/thomasvitale/devex/book-service-arm64`. You can use it to deploy the application on Knative from a YAML manifest. Update `config/knative.yml` with your own image, then run the following command. +Then, you can containerize and publish the application image to a container registry. I have already done that and the image is available on my GitHub Container Registry: `ghcr.io/thomasvitale/devex/book-service`. You can use it to deploy the application on Knative from a YAML manifest. Update `config/knative.yml` with your own image, then run the following command. ```shell kapp deploy -a book-service -f config -y diff --git a/06-knative/basic/book-service/build.gradle b/06-knative/basic/book-service/build.gradle index 3298dd3..b4e5374 100644 --- a/06-knative/basic/book-service/build.gradle +++ b/06-knative/basic/book-service/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' } group = 'com.thomasvitale' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion = JavaLanguageVersion.of(22) } } @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'org.springframework:spring-webflux' } tasks.named('test') { @@ -34,12 +34,8 @@ tasks.named('jar') { } tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" - buildpacks = [ "gcr.io/paketo-buildpacks/java:beta" ] - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-tiny" - } + builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" + buildpacks = [ "gcr.io/paketo-buildpacks/java" ] imageName = "book-service" } diff --git a/06-knative/basic/book-service/docker-compose.yml b/06-knative/basic/book-service/compose.yml similarity index 100% rename from 06-knative/basic/book-service/docker-compose.yml rename to 06-knative/basic/book-service/compose.yml diff --git a/06-knative/basic/book-service/config/kservice.yml b/06-knative/basic/book-service/config/kservice.yml index aad763b..60e507b 100644 --- a/06-knative/basic/book-service/config/kservice.yml +++ b/06-knative/basic/book-service/config/kservice.yml @@ -7,6 +7,6 @@ spec: spec: containers: - name: book-service - image: ghcr.io/thomasvitale/devex/book-service-arm64 + image: ghcr.io/thomasvitale/devex/book-service ports: - containerPort: 8080 diff --git a/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.jar and b/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.jar differ diff --git a/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.properties index b82aa23..9355b41 100644 --- a/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ b/06-knative/basic/book-service/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/06-knative/basic/book-service/gradlew b/06-knative/basic/book-service/gradlew index 1aa94a4..f5feea6 100755 --- a/06-knative/basic/book-service/gradlew +++ b/06-knative/basic/book-service/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/06-knative/basic/book-service/gradlew.bat b/06-knative/basic/book-service/gradlew.bat index 25da30d..9d21a21 100644 --- a/06-knative/basic/book-service/gradlew.bat +++ b/06-knative/basic/book-service/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/06-knative/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/06-knative/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java index 8f08414..ec2d80a 100644 --- a/06-knative/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ b/06-knative/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java @@ -19,8 +19,8 @@ public static void main(String[] args) { @Bean RouterFunction routerFunction() { return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( + .GET("/", _ -> ServerResponse.ok().body("Welcome to the BookService!")) + .GET("/books", _ -> ServerResponse.ok().body(List.of( new Book("The Hobbit"), new Book("The Lord of the Rings"), new Book("His Dark Materials") diff --git a/07-telepresence/README.md b/07-telepresence/README.md deleted file mode 100644 index 5c2031a..0000000 --- a/07-telepresence/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# 07 - Telepresence - -Let's explore how to develop applications on the local JVM while taking advantage of all the services provided by a Kubernetes cluster. We'll use a local cluster provisioned with [`kind`](https://kind.sigs.k8s.io). For this example, you need to install [Telepresence](https://www.telepresence.io/docs/latest/install). - -> **Warning** -> Telepresence support for ARM64 architectures is not stable and not really working from version 2.6 and onwards. I recommend choosing other tools like [mirrord](https://mirrord.dev) over Telepresence in that case. If you want to test it anyway, use version 2.5.8. - -```shell -cd .. -./create-cluster.sh -``` - -## Basic - -Navigate to the `basic` folder. - -```shell -cd 07-telepresence/basic/book-service -``` - -Package the application as a container image. - -```shell -./gradlew bootBuildImage -``` - -Then load the image to the local cluster. - -```shell -kind load docker-image book-service --name devex-cluster -``` - -Finally, deploy the application as follows with [`kubectl`](https://kubectl.docs.kubernetes.io). - -```shell -kubectl apply -f config -``` - -At this point, you can use Telepresence to proxy traffic directed to the Book Service application to your local machine. First, start the Telepresence daemon. - -```shell -telepresence connect -``` - -Then, start proxying traffic to Book Service. - -```shell -telepresence intercept book-service --port 8080:http -``` - -You can now run Book Service locally as follows. - -```shell -./gradlew bootRun -``` - -With Telepresence, you can call the application from the Kubernetes Ingress rather than directly on your local machine. That means the application will benefit from any integration and configuration applied to the cluster (for example, HTTPS, connections to backing services, databases, security, and more). - -```shell -http localhost/books -``` - -## Clean-up - -When you're done, stop Telepresence. - -```shell -telepresence quit -``` - -Then, delete the cluster as follows. - -```shell -cd ../../.. -./destroy-cluster.sh -``` - -## Issues with ARM64 - -There are issues with Telepresence 2.6+ on ARM64 machines. Use the old version 2.5.8 if you really want to test it. - -```shell -sudo curl -fL https://app.getambassador.io/download/tel2/darwin/arm64/2.5.8/telepresence -o /usr/local/bin/telepresence -``` - -More information: https://github.com/telepresenceio/telepresence/issues/2596 diff --git a/07-telepresence/basic/book-service/.gitignore b/07-telepresence/basic/book-service/.gitignore deleted file mode 100644 index c2065bc..0000000 --- a/07-telepresence/basic/book-service/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/07-telepresence/basic/book-service/build.gradle b/07-telepresence/basic/book-service/build.gradle deleted file mode 100644 index 019f1e0..0000000 --- a/07-telepresence/basic/book-service/build.gradle +++ /dev/null @@ -1,46 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '3.2.5' - id 'io.spring.dependency-management' version '1.1.4' -} - -group = 'com.thomasvitale' -version = '0.0.1-SNAPSHOT' - -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-actuator' - implementation 'org.springframework.boot:spring-boot-starter-web' - developmentOnly 'org.springframework.boot:spring-boot-devtools' - - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-starter-webflux' -} - -tasks.named('test') { - useJUnitPlatform() -} - -tasks.named('jar') { - enabled = false -} - -tasks.named('bootBuildImage') { - if (System.getProperty( "os.arch" ).toLowerCase().startsWith('aarch')) { - builder = "docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny" - buildpacks = [ "gcr.io/paketo-buildpacks/java:beta" ] - } else { - builder = "docker.io/paketobuildpacks/builder-jammy-tiny" - } - - imageName = "book-service" -} diff --git a/07-telepresence/basic/book-service/config/deployment.yml b/07-telepresence/basic/book-service/config/deployment.yml deleted file mode 100644 index f313a0a..0000000 --- a/07-telepresence/basic/book-service/config/deployment.yml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: book-service - labels: - app: book-service -spec: - replicas: 1 - selector: - matchLabels: - app: book-service - template: - metadata: - labels: - app: book-service - spec: - containers: - - name: book-service - image: book-service - imagePullPolicy: IfNotPresent - securityContext: - runAsUser: 1001 - lifecycle: - preStop: - exec: - command: [ "sh", "-c", "sleep 5" ] - ports: - - containerPort: 8080 - resources: - requests: - cpu: "0.2" - memory: "1Gi" - limits: - memory: "1Gi" diff --git a/07-telepresence/basic/book-service/config/ingress.yml b/07-telepresence/basic/book-service/config/ingress.yml deleted file mode 100644 index dd3b962..0000000 --- a/07-telepresence/basic/book-service/config/ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: book-ingress -spec: - rules: - - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: book-service - port: - number: 80 diff --git a/07-telepresence/basic/book-service/config/service.yml b/07-telepresence/basic/book-service/config/service.yml deleted file mode 100644 index abd44b5..0000000 --- a/07-telepresence/basic/book-service/config/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: book-service - labels: - app: book-service -spec: - type: ClusterIP - selector: - app: book-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 8080 diff --git a/07-telepresence/basic/book-service/docker-compose.yml b/07-telepresence/basic/book-service/docker-compose.yml deleted file mode 100644 index 6a1577c..0000000 --- a/07-telepresence/basic/book-service/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -services: - book-service: - container_name: book-service - image: book-service - ports: - - "8080:8080" - - "9090:9090" - environment: - BPL_DEBUG_ENABLED: "true" - BPL_DEBUG_PORT: 9090 diff --git a/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.jar b/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e644113..0000000 Binary files a/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.properties b/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index b82aa23..0000000 --- a/07-telepresence/basic/book-service/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/07-telepresence/basic/book-service/gradlew b/07-telepresence/basic/book-service/gradlew deleted file mode 100755 index 1aa94a4..0000000 --- a/07-telepresence/basic/book-service/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/07-telepresence/basic/book-service/gradlew.bat b/07-telepresence/basic/book-service/gradlew.bat deleted file mode 100644 index 25da30d..0000000 --- a/07-telepresence/basic/book-service/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/07-telepresence/basic/book-service/settings.gradle b/07-telepresence/basic/book-service/settings.gradle deleted file mode 100644 index 42071fb..0000000 --- a/07-telepresence/basic/book-service/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = '07-basic-book-service' diff --git a/07-telepresence/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java b/07-telepresence/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java deleted file mode 100644 index 8f08414..0000000 --- a/07-telepresence/basic/book-service/src/main/java/com/thomasvitale/bookservice/BookServiceApplication.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.thomasvitale.bookservice; - -import java.util.List; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.web.servlet.function.RouterFunction; -import org.springframework.web.servlet.function.RouterFunctions; -import org.springframework.web.servlet.function.ServerResponse; - -@SpringBootApplication -public class BookServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(BookServiceApplication.class, args); - } - - @Bean - RouterFunction routerFunction() { - return RouterFunctions.route() - .GET("/", request -> ServerResponse.ok().body("Welcome to the BookService!")) - .GET("/books", request -> ServerResponse.ok().body(List.of( - new Book("The Hobbit"), - new Book("The Lord of the Rings"), - new Book("His Dark Materials") - ))) - .build(); - } - -} - -record Book(String title){} diff --git a/07-telepresence/basic/book-service/src/main/resources/application.yml b/07-telepresence/basic/book-service/src/main/resources/application.yml deleted file mode 100644 index 8b13789..0000000 --- a/07-telepresence/basic/book-service/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/07-telepresence/basic/book-service/src/test/java/com/thomasvitale/bookservice/BookServiceApplicationTests.java b/07-telepresence/basic/book-service/src/test/java/com/thomasvitale/bookservice/BookServiceApplicationTests.java deleted file mode 100644 index 96cce6b..0000000 --- a/07-telepresence/basic/book-service/src/test/java/com/thomasvitale/bookservice/BookServiceApplicationTests.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.thomasvitale.bookservice; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.test.web.reactive.server.WebTestClient; - -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class BookServiceApplicationTests { - - @Autowired - WebTestClient webTestClient; - - @Test - void whenRootThenWelcomeMessage() { - webTestClient - .get() - .uri("/") - .exchange() - .expectStatus().isOk() - .expectBody(String.class).isEqualTo("Welcome to the BookService!"); - } - - @Test - void whenGetBooksThenReturnList() { - webTestClient - .get() - .uri("/books") - .exchange() - .expectStatus().isOk() - .expectBodyList(Book.class).hasSize(3); - } - -} diff --git a/08-argocd/README.md b/08-argocd/README.md deleted file mode 100644 index 5cb3f15..0000000 --- a/08-argocd/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# 08 - Argo CD - -Let's see how to use Argo CD to automatically provision temproary environments whenever a new pull request is created on a GitHub repository. We'll use a local cluster provisioned with [`kind`](https://kind.sigs.k8s.io). - -For this example, you need to install the [Argo CD CLI](https://argo-cd.readthedocs.io/en/stable/getting_started/#2-download-argo-cd-cli). - -```shell -cd .. -./create-cluster.sh -``` - -## Argo CD - -You can install Argo CD with [`kapp`](https://carvel.dev/kapp/docs/latest/install). - -```shell -kubectl create namespace argocd -kapp deploy -a argo -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -y -``` - -Next, use the port forwarding functionality in Kubernetes to expose the Argo CD Server to your local machine. - -```shell -kubectl port-forward svc/argocd-server -n argocd 3000:443 -``` - -In a new Terminal window, retrieve the password used to access Argo CD. - -```shell -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo -``` - -Finally, you can access the Argo CD GUI at http://localhost:3000 and login with username `admin` and the password you retrieved in the previous step. - -In order to configure Argo CD to monitor a GitHub repository for pull request, we need to create a Secret in Kubernetes with a token. The token can be created from your GitHub account: _Settings > Developer settings > Personal access tokens_. Make sure the token has the following scopes: `repo`. - -```shell -kubectl create secret generic github-token --from-literal=token= -n argocd -``` - -Then, update the `applicationset.yml` file to point to a GitHub repository of yours and -apply it to the cluster. - -```shell -kubectl apply -f applicationset.yml -``` - -At this point, whenever you open a pull request to that repository, Argo CD will automatically deploy the application to the Kubernetes cluster (assuming the image has been built and published to a container registry). - -You can verify the result from the Argo CD GUI. - -Once the pull request is merged or closed, Argo CD will automatically undeploy the application. For example, try closing the pull request on GitHub and notice how the application disappears from the Argo CD GUI. - -## Clean-up - -When you're done, delete the cluster as follows. - -```shell -cd ../ -./destroy-cluster.sh -``` diff --git a/08-argocd/applicationset.yml b/08-argocd/applicationset.yml deleted file mode 100644 index 3544ea3..0000000 --- a/08-argocd/applicationset.yml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: music-service - namespace: argocd -spec: - generators: - - pullRequest: - github: - owner: thomasvitale - repo: music-service - tokenRef: - secretName: github-token - key: token - requeueAfterSeconds: 5 - template: - metadata: - name: 'music-service-{{branch}}-{{number}}' - spec: - project: default - source: - repoURL: https://github.com/ThomasVitale/music-service.git - targetRevision: '{{head_sha}}' - path: config/ - destination: - server: https://kubernetes.default.svc - namespace: '{{branch}}' - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true diff --git a/README.md b/README.md index 2b6525c..6dee5d8 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ The approach works with any Java application, but we'll use Spring Boot for our * Cloud Native Buildpacks * Knative * Tilt -* Skaffold -* Telepresence -* Argo CD. +* Skaffold. For each tool/strategy there is a dedicated folder within which you'll find instructions on how to setup your environment. @@ -17,7 +15,7 @@ For each tool/strategy there is a dedicated folder within which you'll find inst Running through the examples will require you to have the following installed on your machine: -* [Java 21](https://adoptium.net/en-GB/temurin/releases) +* [Java 22](https://adoptium.net/en-GB/temurin/releases) * [Podman](https://podman-desktop.io) or [Docker](https://www.docker.com) * [kubectl](https://kubectl.docs.kubernetes.io) * [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)