diff --git a/.github/workflows/java-sample-app-ecr-deploy.yml b/.github/workflows/java-sample-app-ecr-deploy.yml index 9a6f0e9f0..c9822e2bb 100644 --- a/.github/workflows/java-sample-app-ecr-deploy.yml +++ b/.github/workflows/java-sample-app-ecr-deploy.yml @@ -1,6 +1,10 @@ ## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. ## SPDX-License-Identifier: Apache-2.0 +# This workflow is for building and uploading the Java sample application to ECR. +# Java 11 will be built and uploaded to all regions to be used by the canary while +# other versions (8, 17, 21, 22) will be uploaded to us-east-1 for the purpose of +# testing ADOT Java name: Sample App Deployment - Java ECR on: workflow_dispatch: # be able to run the workflow on demand @@ -9,8 +13,12 @@ permissions: id-token: write contents: read +env: + E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }} + E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} + jobs: - upload-main-service-image: + java-v11-main: strategy: fail-fast: false matrix: @@ -27,31 +35,29 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: ${{ secrets.E2E_IAD_TEST_ACCOUNT_ARN }} + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: us-east-1 - name: Retrieve account uses: aws-actions/aws-secretsmanager-get-secrets@v1 with: - secret-ids: + secret-ids: | ACCOUNT_ID, region-account/${{ matrix.aws-region }} + JAVA_MAIN_SAMPLE_APP_IMAGE, e2e-test/java-main-sample-app-image - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.E2E_TEST_ROLE_ARN }} + role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: ${{ matrix.aws-region }} - - name: Update ECR URI - working-directory: sample-apps/springboot + - name: Build and Upload Main Service Image + working-directory: sample-apps/java/springboot-main-service run: | - sed -i 's#":"#"${{ env.ACCOUNT_ID }}.dkr.ecr.${{ matrix.aws-region }}.amazonaws.com/${{ secrets.APP_SIGNALS_E2E_FE_SA_IMG }}:latest"#g' build.gradle.kts - - - name: Upload Main Service Image - working-directory: sample-apps/springboot - run: gradle jib + sed -i 's#"{{ECR_IMAGE_URI}}"#"${{ env.E2E_TEST_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/${{ env.JAVA_MAIN_SAMPLE_APP_IMAGE }}:v11"#g' build.gradle.kts + gradle jib -P javaVersion=11 - upload-remote-service-image: + java-v11-remote: strategy: fail-fast: false matrix: @@ -68,27 +74,88 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: ${{ secrets.E2E_IAD_TEST_ACCOUNT_ARN }} + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: us-east-1 - name: Retrieve account uses: aws-actions/aws-secretsmanager-get-secrets@v1 with: - secret-ids: + secret-ids: | ACCOUNT_ID, region-account/${{ matrix.aws-region }} + JAVA_REMOTE_SAMPLE_APP_IMAGE, e2e-test/java-remote-sample-app-image - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.E2E_TEST_ROLE_ARN }} + role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: ${{ matrix.aws-region }} - - name: Update ECR URI - working-directory: sample-apps/springboot-remote-service + - name: Build and Upload Remote Service Image + working-directory: sample-apps/java/springboot-remote-service + run: | + sed -i 's#"{{ECR_IMAGE_URI}}"#"${{ env.E2E_TEST_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/${{ env.JAVA_REMOTE_SAMPLE_APP_IMAGE }}:v11"#g' build.gradle.kts + gradle jib -P javaVersion=11 + + java-main: + strategy: + fail-fast: false + matrix: + java-version: [ '8', '17', '21', '22' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java-version }} + check-latest: true + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: us-east-1 + + - name: Retrieve account + uses: aws-actions/aws-secretsmanager-get-secrets@v2 + with: + secret-ids: | + JAVA_MAIN_SAMPLE_APP_IMAGE, e2e-test/java-main-sample-app-image + + - name: Build and Upload Main Service Image + working-directory: sample-apps/java/springboot-main-service run: | - sed -i 's#":"#"${{ env.ACCOUNT_ID }}.dkr.ecr.${{ matrix.aws-region }}.amazonaws.com/${{ secrets.APP_SIGNALS_E2E_RE_SA_IMG }}:latest"#g' build.gradle.kts + sed -i 's#"{{ECR_IMAGE_URI}}"#"${{ env.E2E_TEST_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/${{ env.JAVA_MAIN_SAMPLE_APP_IMAGE }}:v${{ matrix.java-version }}"#g' build.gradle.kts + gradle jib -P javaVersion=${{ matrix.java-version }} + + java-remote: + strategy: + fail-fast: false + matrix: + java-version: [ '8', '17', '21', '22' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java-version }} + check-latest: true - - name: Upload Remote Service Image - working-directory: sample-apps/springboot-remote-service - run: gradle jib + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: us-east-1 + - name: Retrieve account + uses: aws-actions/aws-secretsmanager-get-secrets@v2 + with: + secret-ids: | + JAVA_REMOTE_SAMPLE_APP_IMAGE, e2e-test/java-remote-sample-app-image + + - name: Build and Upload Remote Service Image + working-directory: sample-apps/java/springboot-remote-service + run: | + sed -i 's#"{{ECR_IMAGE_URI}}"#"${{ env.E2E_TEST_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/${{ env.JAVA_REMOTE_SAMPLE_APP_IMAGE }}:v${{ matrix.java-version }}"#g' build.gradle.kts + gradle jib -P javaVersion=${{ matrix.java-version }} diff --git a/.github/workflows/java-sample-app-s3-deploy.yml b/.github/workflows/java-sample-app-s3-deploy.yml index c5e1ad1a1..371ed91e5 100644 --- a/.github/workflows/java-sample-app-s3-deploy.yml +++ b/.github/workflows/java-sample-app-s3-deploy.yml @@ -1,6 +1,8 @@ ## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. ## SPDX-License-Identifier: Apache-2.0 +# This workflow is for building and uploading the Java sample application to S3 bucket. Java 11 will be built and uploaded to all regions to be used by the canary while other versions (8, 17, 21, 22) +# will be uploaded to us-east-1 for the purpose of testing ADOT Java name: Sample App Deployment - Java S3 on: workflow_dispatch: # be able to run the workflow on demand @@ -9,15 +11,19 @@ permissions: id-token: write contents: read +env: + E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }} + E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} + jobs: - upload-main-service-jar: + java-v11-main: strategy: fail-fast: false matrix: aws-region: [ 'af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1', 'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1', 'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1', - 'us-east-1','us-east-2', 'us-west-1', 'us-west-2' ] + 'us-east-1','us-east-2','us-west-1','us-west-2' ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,7 +33,7 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: ${{ secrets.E2E_IAD_TEST_ACCOUNT_ARN }} + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: us-east-1 - name: Retrieve account @@ -39,25 +45,23 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.E2E_TEST_ROLE_ARN }} + role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: ${{ matrix.aws-region }} - - name: Build Main Jar - working-directory: sample-apps/springboot - run: gradle build - - - name: Upload to S3 - working-directory: sample-apps/springboot - run: aws s3api put-object --bucket ${{ secrets.APP_SIGNALS_E2E_EC2_JAR }}-prod-${{ matrix.aws-region }} --body ./build/libs/springboot-*-SNAPSHOT.jar --key main-service.jar + - name: Build and Upload Main Jar + working-directory: sample-apps/java/springboot-main-service + run: | + gradle build -P javaVersion=11 + aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body ./build/libs/springboot-*-SNAPSHOT.jar --key java-main-service-v11.jar - upload-remote-service-jar: + java-v11-remote: strategy: fail-fast: false matrix: - aws-region: [ 'af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1', - 'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1', - 'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1', - 'us-east-1','us-east-2','us-west-1', 'us-west-2' ] + aws-region: [ 'af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1', + 'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1', + 'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1', + 'us-east-1','us-east-2','us-west-1','us-west-2' ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -67,7 +71,7 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: ${{ secrets.E2E_IAD_TEST_ACCOUNT_ARN }} + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: us-east-1 - name: Retrieve account @@ -79,14 +83,81 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.E2E_TEST_ROLE_ARN }} + role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} aws-region: ${{ matrix.aws-region }} - - name: Build Main Jar - working-directory: sample-apps/springboot-remote-service - run: gradle build + - name: Build and Upload Main Jar + working-directory: sample-apps/java/springboot-remote-service + run: | + gradle build -P javaVersion=11 + aws s3api put-object --bucket aws-appsignals-sample-app-prod-${{ matrix.aws-region }} --body build/libs/springboot-remote-service-*-SNAPSHOT.jar --key java-remote-service-v11.jar + + java-main: + strategy: + fail-fast: false + matrix: + java-version: [ '8', '17', '21', '22' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java-version }} + check-latest: true + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: us-east-1 + + - name: Build and Upload Main Jar + working-directory: sample-apps/java/springboot-main-service + run: | + # For Java 8, springboot must be lower than version 3 + # For Java 11,17,21, they are compatible with both springboot version + # For Java 22 and above, springboot must be version 3 or higher + if [ "${{ matrix.java-version }}" = "22" ]; then + sed -i 's/id("org.springframework.boot")/id("org.springframework.boot") version "3.3.4"/' build.gradle.kts + cat build.gradle.kts + fi + + gradle build -P javaVersion=${{ matrix.java-version }} + aws s3api put-object --bucket aws-appsignals-sample-app-prod-us-east-1 --body ./build/libs/springboot-*-SNAPSHOT.jar --key java-main-service-v${{ matrix.java-version }}.jar + + java-remote: + strategy: + fail-fast: false + matrix: + java-version: [ '8', '17', '21', '22' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java-version }} + check-latest: true + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: us-east-1 + + - name: Build and Upload Remote Jar + working-directory: sample-apps/java/springboot-remote-service + run: | + # For Java 8, springboot must be lower than version 3 + # For Java 11,17,21, they are compatible with both springboot version + # For Java 22 and above, springboot must be version 3 or higher + if [ "${{ matrix.java-version }}" = "22" ]; then + sed -i 's/id("org.springframework.boot")/id("org.springframework.boot") version "3.3.4"/' build.gradle.kts + cat build.gradle.kts + fi + + gradle build -P javaVersion=${{ matrix.java-version }} + aws s3api put-object --bucket aws-appsignals-sample-app-prod-us-east-1 --body ./build/libs/springboot-remote-service-*-SNAPSHOT.jar --key java-remote-service-v${{ matrix.java-version }}.jar - - name: Upload to S3 - working-directory: sample-apps/springboot-remote-service - run: aws s3api put-object --bucket ${{ secrets.APP_SIGNALS_E2E_EC2_JAR }}-prod-${{ matrix.aws-region }} --body build/libs/springboot-remote-service-*-SNAPSHOT.jar --key remote-service.jar diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917..a4b76b953 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930..0aaefbcaf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426..f5feea6d6 100755 --- a/gradlew +++ b/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/gradlew.bat b/gradlew.bat index 93e3f59f1..9d21a2183 100644 --- a/gradlew.bat +++ b/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 ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +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 @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +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 diff --git a/sample-apps/java/settings.gradle.kts b/sample-apps/java/settings.gradle.kts new file mode 100644 index 000000000..7415fafcb --- /dev/null +++ b/sample-apps/java/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + plugins { + id("com.google.cloud.tools.jib") version "3.4.0" + id("org.springframework.boot") version "2.7.17" + } +} + +dependencyResolutionManagement { + repositories { + mavenCentral() + mavenLocal() + + maven { + setUrl("https://oss.sonatype.org/content/repositories/snapshots") + } + } +} + +buildCache { + local { + isEnabled = true + } +} + +include(":springboot-main-service") +include(":springboot-remote-service") \ No newline at end of file diff --git a/sample-apps/springboot/build.gradle.kts b/sample-apps/java/springboot-main-service/build.gradle.kts similarity index 74% rename from sample-apps/springboot/build.gradle.kts rename to sample-apps/java/springboot-main-service/build.gradle.kts index c14ede174..844098e6c 100644 --- a/sample-apps/springboot/build.gradle.kts +++ b/sample-apps/java/springboot-main-service/build.gradle.kts @@ -13,6 +13,13 @@ * permissions and limitations under the License. */ +val javaVersion = if (project.hasProperty("javaVersion")) { + project.property("javaVersion").toString() +} else { + "11" +} +val javaVersionRefactored = JavaVersion.toVersion(javaVersion) + plugins { java application @@ -23,8 +30,8 @@ plugins { group = "com.amazon.sampleapp" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_11 +java.sourceCompatibility = javaVersionRefactored +java.targetCompatibility = javaVersionRefactored repositories { mavenCentral() @@ -38,13 +45,17 @@ dependencies { implementation("software.amazon.awssdk:s3") implementation("software.amazon.awssdk:sts") implementation("com.mysql:mysql-connector-j:8.4.0") + implementation ("org.apache.httpcomponents:httpclient:4.5.13") } jib { + from { + image = "openjdk:$javaVersion-jdk" + } + // Replace this value with the ECR Image URI to { - image = ":" + image = "{{ECR_IMAGE_URI}}" } - container { mainClass = "com.amazon.sampleapp.FrontendService" ports = listOf("8080") diff --git a/sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendService.java b/sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendService.java similarity index 84% rename from sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendService.java rename to sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendService.java index 7cc24822c..d217dc403 100644 --- a/sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendService.java +++ b/sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendService.java @@ -15,7 +15,8 @@ package com.amazon.sampleapp; -import java.net.http.HttpClient; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -25,8 +26,8 @@ public class FrontendService { @Bean - public HttpClient httpClient() { - return HttpClient.newHttpClient(); + public CloseableHttpClient httpClient() { + return HttpClients.createDefault(); } @Bean diff --git a/sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendServiceController.java b/sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendServiceController.java similarity index 64% rename from sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendServiceController.java rename to sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendServiceController.java index 9cff0e830..4daa713fb 100644 --- a/sample-apps/springboot/src/main/java/com/amazon/sampleapp/FrontendServiceController.java +++ b/sample-apps/java/springboot-main-service/src/main/java/com/amazon/sampleapp/FrontendServiceController.java @@ -17,9 +17,6 @@ import io.opentelemetry.api.trace.Span; import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; @@ -29,7 +26,12 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; - +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; import org.apache.tomcat.util.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +47,7 @@ @Controller public class FrontendServiceController { private static final Logger logger = LoggerFactory.getLogger(FrontendServiceController.class); - private final HttpClient httpClient; + private final CloseableHttpClient httpClient; private final S3Client s3; private AtomicBoolean shouldSendLocalRootClientCall = new AtomicBoolean(false); @@ -54,26 +56,26 @@ private void runLocalRootClientCallRecurringService() { // run the service ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); Runnable runnableTask = - () -> { - if (shouldSendLocalRootClientCall.get()) { - shouldSendLocalRootClientCall.set(false); - HttpRequest request = - HttpRequest.newBuilder() - .uri(URI.create("http://local-root-client-call")) - .GET() - .build(); - try { - HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); - } catch (Exception e) { - } - } - }; + () -> { + if (shouldSendLocalRootClientCall.get()) { + shouldSendLocalRootClientCall.set(false); + HttpGet request = new HttpGet("http://local-root-client-call"); + try (CloseableHttpResponse response = httpClient.execute(request)) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + logger.info(EntityUtils.toString(entity)); + } + } catch (Exception e) { + logger.error("Error in recurring task: {}", e.getMessage()); + } + } + }; // Run with initial 0.1s delay, every 1 second executorService.scheduleAtFixedRate(runnableTask, 100, 1000, TimeUnit.MILLISECONDS); } @Autowired - public FrontendServiceController(HttpClient httpClient, S3Client s3) { + public FrontendServiceController(CloseableHttpClient httpClient, S3Client s3) { this.httpClient = httpClient; this.s3 = s3; } @@ -89,39 +91,30 @@ public String healthcheck() { @ResponseBody public String awssdkCall(@RequestParam(name = "testingId", required = false) String testingId) { String bucketName = "e2e-test-bucket-name"; - // Add a unique test ID to bucketname to associate buckets to specific test runs if (testingId != null) { bucketName += "-" + testingId; } GetBucketLocationRequest bucketLocationRequest = - GetBucketLocationRequest.builder().bucket(bucketName).build(); + GetBucketLocationRequest.builder().bucket(bucketName).build(); try { s3.getBucketLocation(bucketLocationRequest); } catch (Exception e) { - // bucketName does not exist, so this is expected. - logger.error("Error occurred when trying to get bucket location of: " + bucketName); - logger.error("Could not retrieve http request:" + e.getLocalizedMessage()); + logger.error("Error occurred when trying to get bucket location of: " + bucketName, e); } return getXrayTraceId(); } - // test http instrumentation (java client) + // test http instrumentation (Apache HttpClient for Java 8) @GetMapping("/outgoing-http-call") @ResponseBody public String httpCall() { - HttpRequest request = - HttpRequest.newBuilder().uri(URI.create("https://www.amazon.com")).GET().build(); - - try { - HttpResponse response = - httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - int statusCode = response.statusCode(); - + HttpGet request = new HttpGet("https://www.amazon.com"); + try (CloseableHttpResponse response = httpClient.execute(request)) { + int statusCode = response.getStatusLine().getStatusCode(); logger.info("outgoing-http-call status code: " + statusCode); } catch (Exception e) { - logger.error("Could not complete http request:" + e.getMessage()); + logger.error("Could not complete HTTP request: {}", e.getMessage()); } - return getXrayTraceId(); } @@ -129,25 +122,15 @@ public String httpCall() { @GetMapping("/remote-service") @ResponseBody public String downstreamService(@RequestParam("ip") String ip) { - // Ensure IP doesn't have extra slashes anywhere ip = ip.replace("/", ""); - HttpRequest request = - HttpRequest.newBuilder() - .uri(URI.create("http://" + ip + ":8080/healthcheck")) - .GET() - .build(); - - try { - HttpResponse response = - httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - int statusCode = response.statusCode(); - + HttpGet request = new HttpGet("http://" + ip + ":8080/healthcheck"); + try (CloseableHttpResponse response = httpClient.execute(request)) { + int statusCode = response.getStatusLine().getStatusCode(); logger.info("Remote service call status code: " + statusCode); return getXrayTraceId(); } catch (Exception e) { - logger.error("Could not complete http request to remote service:" + e.getMessage()); + logger.error("Could not complete HTTP request to remote service: {}", e.getMessage()); } - return getXrayTraceId(); } @@ -157,13 +140,6 @@ public String downstreamService(@RequestParam("ip") String ip) { public String asyncService() { logger.info("Client-call received"); shouldSendLocalRootClientCall.set(true); - // This API is used to trigger the http://local-root-client-call call on running on the executor - // recurring service, which will generate a local root client span. The E2E testing will attempt - // to validate the span - // generated by the /local-root-client-call, not this /client-call API call. Therefore, the - // traceId of this API call is not needed and we return an invalid traceId to indicate that the - // call was received but to not use this - // traceId. return "{\"traceId\": \"1-00000000-000000000000000000000000\"}"; } @@ -173,19 +149,17 @@ public String asyncService() { public String mysql() { logger.info("mysql received"); final String rdsMySQLClusterPassword = new String(new Base64().decode(System.getenv("RDS_MYSQL_CLUSTER_PASSWORD").getBytes())); - try { Connection connection = DriverManager.getConnection( - System.getenv().get("RDS_MYSQL_CLUSTER_CONNECTION_URL"), - System.getenv().get("RDS_MYSQL_CLUSTER_USERNAME"), + System.getenv("RDS_MYSQL_CLUSTER_CONNECTION_URL"), + System.getenv("RDS_MYSQL_CLUSTER_USERNAME"), rdsMySQLClusterPassword); Statement statement = connection.createStatement(); statement.executeQuery("SELECT * FROM tables LIMIT 1;"); } catch (SQLException e) { - logger.error("Could not complete SQL request:{}", e.getMessage()); + logger.error("Could not complete SQL request: {}", e.getMessage()); throw new RuntimeException(e); } - return getXrayTraceId(); } @@ -193,7 +167,6 @@ public String mysql() { private String getXrayTraceId() { String traceId = Span.current().getSpanContext().getTraceId(); String xrayTraceId = "1-" + traceId.substring(0, 8) + "-" + traceId.substring(8); - return String.format("{\"traceId\": \"%s\"}", xrayTraceId); } } diff --git a/sample-apps/springboot-remote-service/build.gradle.kts b/sample-apps/java/springboot-remote-service/build.gradle.kts similarity index 70% rename from sample-apps/springboot-remote-service/build.gradle.kts rename to sample-apps/java/springboot-remote-service/build.gradle.kts index a652cc928..a5f45619c 100644 --- a/sample-apps/springboot-remote-service/build.gradle.kts +++ b/sample-apps/java/springboot-remote-service/build.gradle.kts @@ -13,6 +13,13 @@ * permissions and limitations under the License. */ +val javaVersion = if (project.hasProperty("javaVersion")) { + project.property("javaVersion").toString() +} else { + "11" +} +val javaVersionRefactored = JavaVersion.toVersion(javaVersion) + plugins { java application @@ -23,8 +30,8 @@ plugins { group = "com.amazon.sampleapp" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_11 +java.sourceCompatibility = javaVersionRefactored +java.targetCompatibility = javaVersionRefactored repositories { mavenCentral() @@ -33,11 +40,16 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-logging") + implementation ("org.apache.httpcomponents:httpclient:4.5.13") } jib { + from { + image = "openjdk:$javaVersion-jdk" + } + // Replace this value with the ECR Image URI to { - image = ":" + image = "{{ECR_IMAGE_URI}}" } container { mainClass = "com.amazon.sampleapp.RemoteService" diff --git a/sample-apps/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteService.java b/sample-apps/java/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteService.java similarity index 100% rename from sample-apps/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteService.java rename to sample-apps/java/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteService.java diff --git a/sample-apps/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteServiceController.java b/sample-apps/java/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteServiceController.java similarity index 100% rename from sample-apps/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteServiceController.java rename to sample-apps/java/springboot-remote-service/src/main/java/com/amazon/sampleapp/RemoteServiceController.java diff --git a/settings.gradle.kts b/settings.gradle.kts index 87957e1d8..154781a6d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -26,8 +26,6 @@ buildCache { // End to end tests include(":validator") -include(":sample-apps:springboot") -include(":sample-apps:springboot-remote-service") //id("com.diffplug.spotless") version "6.22.0" //id("com.github.ben-manes.versions") version "0.50.0"