Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/java-lambda-canary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
## SPDX-License-Identifier: Apache-2.0

## This workflow aims to run the Application Signals Java end-to-end tests as a canary to
## test the artifacts for Application Signals enablement on Lambda.
name: Java Lambda Enablement Canary Testing
on:
schedule:
- cron: '20,45 * * * *' # run the workflow at 20th and 45th minute of every hour
workflow_dispatch: # be able to run the workflow on demand

permissions:
id-token: write
contents: read

jobs:
github:
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']
uses: ./.github/workflows/java-lambda-retry.yml
secrets: inherit
with:
aws-region: ${{ matrix.aws-region }}
caller-workflow-name: 'appsignals-java-e2e-lambda-canary-test'
57 changes: 57 additions & 0 deletions .github/workflows/java-lambda-retry.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
## SPDX-License-Identifier: Apache-2.0

# This is a reusable workflow for running the Java Lambda Canary with retries.
# It is meant to be called from another workflow.
# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview
name: Java Lambda Default Retry
on:
workflow_call:
inputs:
aws-region:
required: true
type: string
caller-workflow-name:
required: true
type: string

permissions:
id-token: write
contents: read

jobs:
java-lambda-attempt-1:
uses: ./.github/workflows/java-lambda-test.yml
secrets: inherit
with:
aws-region: ${{ inputs.aws-region }}
caller-workflow-name: ${{ inputs.caller-workflow-name }}

java-lambda-attempt-2:
needs: [ java-lambda-attempt-1 ]
if: ${{ needs.java-lambda-attempt-1.outputs.job-started != 'true' }}
uses: ./.github/workflows/java-lambda-test.yml
secrets: inherit
with:
aws-region: ${{ inputs.aws-region }}
caller-workflow-name: ${{ inputs.caller-workflow-name }}

publish-metric-attempt-1:
needs: [ java-lambda-attempt-1, java-lambda-attempt-2 ]
if: always()
uses: ./.github/workflows/enablement-test-publish-result.yml
secrets: inherit
with:
aws-region: ${{ inputs.aws-region }}
caller-workflow-name: ${{ inputs.caller-workflow-name }}
validation-result: ${{ needs.java-lambda-attempt-1.outputs.validation-result || needs.java-lambda-attempt-2.outputs.validation-result }}

publish-metric-attempt-2:
needs: [ java-lambda-attempt-1, java-lambda-attempt-2, publish-metric-attempt-1 ]
if: ${{ always() && needs.publish-metric-attempt-1.outputs.job-started != 'true' }}
uses: ./.github/workflows/enablement-test-publish-result.yml
secrets: inherit
with:
aws-region: ${{ inputs.aws-region }}
caller-workflow-name: ${{ inputs.caller-workflow-name }}
validation-result: ${{ needs.java-lambda-attempt-1.outputs.validation-result || needs.java-lambda-attempt-2.outputs.validation-result }}
231 changes: 231 additions & 0 deletions .github/workflows/java-lambda-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
## SPDX-License-Identifier: Apache-2.0

# This is a reusable workflow for running the Java Enablement Canary test for Application Signals on Lambda.
# It is meant to be called from another workflow.
# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview
name: Java Lambda Default Use Case
on:
workflow_call:
inputs:
aws-region:
required: true
type: string
caller-workflow-name:
required: true
type: string
outputs:
job-started:
value: ${{ jobs.java-lambda-default.outputs.job-started }}
validation-result:
value: ${{ jobs.java-lambda-default.outputs.validation-result }}

permissions:
id-token: write
contents: read

env:
E2E_TEST_AWS_REGION: ${{ inputs.aws-region }}
CALLER_WORKFLOW_NAME: ${{ inputs.caller-workflow-name }}
E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }}
E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }}
METRIC_NAMESPACE: ApplicationSignals
LOG_GROUP_NAME: /aws/application-signals/data
SAMPLE_APP_ZIP: s3://aws-appsignals-sample-app-prod-${{ inputs.aws-region }}/java-lambda-function.zip
TEST_RESOURCES_FOLDER: ${GITHUB_WORKSPACE}
STAGING_S3_BUCKET: ${{ secrets.STAGING_BUCKET_NAME }}
IS_CANARY: false

jobs:
java-lambda-default:
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
job-started: ${{ steps.job-started.outputs.job-started }}
validation-result: ${{ steps.validation-result.outputs.validation-result }}
steps:
- name: Check if the job started
id: job-started
run: echo "job-started=true" >> $GITHUB_OUTPUT

- uses: actions/checkout@v4
with:
repository: 'aws-observability/aws-application-signals-test-framework'
ref: ${{ env.CALLER_WORKFLOW_NAME == 'main-build' && 'main' || github.ref }}
fetch-depth: 0

# We initialize Gradlew Daemon early on during the workflow because sometimes initialization
# fails due to transient issues. If it fails here, then we will try again later before the validators
- name: Initiate Gradlew Daemon
id: initiate-gradlew
uses: ./.github/workflows/actions/execute_and_retry
continue-on-error: true
with:
command: "./gradlew :validator:build"
cleanup: "./gradlew clean"
max_retry: 3
sleep_time: 60

- name: Generate testing id
run: echo TESTING_ID="${{ github.run_id }}-${{ github.run_number }}-${RANDOM}" >> $GITHUB_ENV

- 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@v1
with:
secret-ids:
ACCOUNT_ID, region-account/${{ env.E2E_TEST_AWS_REGION }}

- name: Configure AWS Credentials
if: ${{ github.event.repository.name == 'aws-application-signals-test-framework' }}
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }}
aws-region: ${{ env.E2E_TEST_AWS_REGION }}

- name: Set Lambda Layer artifact directory path
run: echo ARTIFACTS_DIR="${{ github.workspace }}/lambda_artifacts" >> $GITHUB_ENV

- name: Download Lambda Layer and Function artifacts for E2E Test
if: ${{ env.CALLER_WORKFLOW_NAME != 'appsignals-java-e2e-lambda-canary-test' }}
run: |
aws s3 cp s3://${{ env.STAGING_S3_BUCKET }}/adot-java-lambda-layer-${{ github.run_id }}.zip ${{ env.ARTIFACTS_DIR }}/layer.zip
aws s3 cp ${{ env.SAMPLE_APP_ZIP }} ${{ env.ARTIFACTS_DIR }}/java-function.zip

- name: Set Canary Environment Variable
if: ${{ env.CALLER_WORKFLOW_NAME == 'appsignals-java-e2e-lambda-canary-test' }}
run: |
echo IS_CANARY=true >> $GITHUB_ENV |
aws s3 cp ${{ env.SAMPLE_APP_ZIP }} ${{ env.ARTIFACTS_DIR }}/javafunction.zip

- name: Set up terraform
uses: ./.github/workflows/actions/execute_and_retry
with:
command: "wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg"
post-command: 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
&& sudo apt update && sudo apt install terraform'
sleep_time: 60

- name: Initiate Terraform
uses: ./.github/workflows/actions/execute_and_retry
with:
command: "cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/java/lambda/lambda && terraform init && terraform validate"
cleanup: "rm -rf .terraform && rm -rf .terraform.lock.hcl"
max_retry: 6
sleep_time: 60

- name: Get terraform Lambda function name
shell: bash
run: |
echo TERRAFORM_LAMBDA_FUNCTION_NAME="AdotLambdaJavaSampleApp-${{ github.run_id }}"|
tee --append $GITHUB_ENV

- name: Apply terraform
uses: ./.github/workflows/actions/execute_and_retry
with:
command: 'cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/java/lambda/lambda && terraform apply -auto-approve
-var="sdk_layer_name=AWSOpenTelemetryDistroJava-${{ github.run_id }}"
-var="function_name=${{env.TERRAFORM_LAMBDA_FUNCTION_NAME}}"
-var="layer_artifacts_directory=${{ env.ARTIFACTS_DIR }}"
-var="region=${{ env.E2E_TEST_AWS_REGION }}"
-var="is_canary=${{ env.IS_CANARY }}"'
max_retry: 6
sleep_time: 60

- name: Extract endpoint
id: extract-endpoint
shell: bash
run: cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/java/lambda/lambda && echo API_GATEWAY_URL=$(terraform output -raw api-gateway-url) >> $GITHUB_ENV

- name: Send request to endpoint
shell: bash
run: sleep 30s; curl -sS ${{ env.API_GATEWAY_URL }}

- name: Initiate Gradlew Daemon
if: steps.initiate-gradlew == 'failure'
uses: ./.github/workflows/actions/execute_and_retry
continue-on-error: true
with:
command: "./gradlew :validator:build"
cleanup: "./gradlew clean"
max_retry: 3
sleep_time: 60

- name: Validate generated traces
id: trace-validation
# will be removed after data quality bug fixed
continue-on-error: true
run: ./gradlew validator:run --args='-c java/lambda/trace-validation.yml
--testing-id ${{ env.TESTING_ID }}
--endpoint http://${{ env.API_GATEWAY_URL }}
--region ${{ inputs.aws-region }}
--account-id ${{ env.ACCOUNT_ID }}
--metric-namespace ${{ env.METRIC_NAMESPACE }}
--log-group ${{ env.LOG_GROUP_NAME }}
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
--rollup'

# Validation for pulse telemetry data
- name: Validate generated EMF logs
id: log-validation
if: (success() || steps.trace-validation.outcome == 'failure') && !cancelled()
# will be removed after data quality bug fixed
continue-on-error: true
run: ./gradlew validator:run --args='-c java/lambda/log-validation.yml
--testing-id ${{ env.TESTING_ID }}
--endpoint http://${{ env.API_GATEWAY_URL }}
--region ${{ inputs.aws-region }}
--account-id ${{ env.ACCOUNT_ID }}
--metric-namespace ${{ env.METRIC_NAMESPACE }}
--log-group ${{ env.LOG_GROUP_NAME }}
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
--rollup'

- name: Validate generated metrics
id: metric-validation
# will be removed after data quality bug fixed
continue-on-error: true
if: (success() || steps.trace-validation.outcome == 'failure' || steps.log-validation.outcome == 'failure') && !cancelled()
run: ./gradlew validator:run --args='-c java/lambda/metric-validation.yml
--testing-id ${{ env.TESTING_ID }}
--endpoint http://${{ env.API_GATEWAY_URL }}
--region ${{ inputs.aws-region }}
--account-id ${{ env.ACCOUNT_ID }}
--metric-namespace ${{ env.METRIC_NAMESPACE }}
--log-group ${{ env.LOG_GROUP_NAME }}
--service-name ${{ env.TERRAFORM_LAMBDA_FUNCTION_NAME }}
--rollup'

- name: Refresh AWS Credentials
if: ${{ github.event.repository.name == 'aws-application-signals-test-framework' }}
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }}
aws-region: ${{ env.E2E_TEST_AWS_REGION }}

- name: Save test results
if: always()
id: validation-result
run: |
if [ "${{ steps.log-validation.outcome }}" = "success" ] && [ "${{ steps.metric-validation.outcome }}" = "success" ] && [ "${{ steps.trace-validation.outcome }}" = "success" ]; then
echo "validation-result=success" >> $GITHUB_OUTPUT
else
echo "validation-result=failure" >> $GITHUB_OUTPUT
fi

# Clean up Procedures
- name: Terraform destroy
if: always()
continue-on-error: true
run: |
cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/java/lambda/lambda && terraform destroy -auto-approve \
-var="sdk_layer_name=AWSOpenTelemetryDistroJava-${{ github.run_id }}" \
-var="function_name=${{env.TERRAFORM_LAMBDA_FUNCTION_NAME}}" \
-var="layer_artifacts_directory=${{ env.ARTIFACTS_DIR }}" \
-var="region=${{ env.E2E_TEST_AWS_REGION }}" \
-var="is_canary=${{ env.IS_CANARY }}"
67 changes: 67 additions & 0 deletions terraform/java/lambda/api-gateway-proxy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
resource "aws_api_gateway_rest_api" "lambda_api_proxy" {
name = var.name
}

resource "aws_api_gateway_resource" "lambda_api_proxy" {
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
parent_id = aws_api_gateway_rest_api.lambda_api_proxy.root_resource_id
path_part = "{proxy+}"
}

resource "aws_api_gateway_method" "lambda_api_proxy" {
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
resource_id = aws_api_gateway_resource.lambda_api_proxy.id
http_method = "ANY"
authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_api" {
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
resource_id = aws_api_gateway_method.lambda_api_proxy.resource_id
http_method = aws_api_gateway_method.lambda_api_proxy.http_method

integration_http_method = "POST"
type = "AWS_PROXY"
uri = var.function_invoke_arn
}

resource "aws_api_gateway_method" "lambda_api_proxy_root" {
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
resource_id = aws_api_gateway_rest_api.lambda_api_proxy.root_resource_id
http_method = "ANY"
authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_api_root" {
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
resource_id = aws_api_gateway_method.lambda_api_proxy_root.resource_id
http_method = aws_api_gateway_method.lambda_api_proxy_root.http_method

integration_http_method = "POST"
type = "AWS_PROXY"
uri = var.function_invoke_arn
}

resource "aws_api_gateway_deployment" "lambda_api_proxy" {
depends_on = [
aws_api_gateway_integration.lambda_api,
aws_api_gateway_integration.lambda_api_root,
]

rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
}

resource "aws_api_gateway_stage" "test" {
stage_name = "default"
rest_api_id = aws_api_gateway_rest_api.lambda_api_proxy.id
deployment_id = aws_api_gateway_deployment.lambda_api_proxy.id
xray_tracing_enabled = var.enable_xray_tracing
}

resource "aws_lambda_permission" "lambda_api_allow_gateway" {
action = "lambda:InvokeFunction"
function_name = var.function_name
qualifier = var.function_qualifier
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.lambda_api_proxy.execution_arn}/*/*"
}
3 changes: 3 additions & 0 deletions terraform/java/lambda/api-gateway-proxy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "api_gateway_url" {
value = aws_api_gateway_stage.test.invoke_url
}
Loading
Loading