-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# This workflow will build and the traffic generator image to each region whenever there is an update made to the traffic-generator folder. | ||
# This image will be used by EKS and K8s test to call sample app endpoints | ||
name: Create and Push Traffic Generator Image | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
# branches: | ||
# - main | ||
# paths: | ||
# - 'traffic-generator/**' | ||
|
||
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: | ||
build-and-push-image: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
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'] | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- 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/${{ matrix.aws-region }} | ||
- name: Configure AWS Credentials | ||
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: ${{ matrix.aws-region }} | ||
|
||
- name: Login to Amazon ECR | ||
id: login-ecr | ||
uses: aws-actions/amazon-ecr-login@v2 | ||
|
||
- name: Build, tag, and push image to Amazon ECR | ||
working-directory: traffic-generator | ||
env: | ||
REGISTRY: ${{ steps.login-ecr.outputs.registry }} | ||
REPOSITORY: e2e-test-resource | ||
IMAGE_TAG: traffic-generator | ||
run: | | ||
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG . | ||
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG | ||
upload-files: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
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'] | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- 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/${{ matrix.aws-region }} | ||
- name: Configure AWS Credentials | ||
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: ${{ matrix.aws-region }} | ||
|
||
- name: Upload traffic generator files | ||
working-directory: traffic-generator | ||
run: | | ||
zip traffic-generator.zip ./index.js ./package.json | ||
aws s3 cp traffic-generator.zip s3://aws-appsignals-sample-app-prod-${{ matrix.aws-region }}/traffic-generator.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Use the official lightweight Node.js 16 image. | ||
# https://hub.docker.com/_/node | ||
# FROM node:16-slim | ||
FROM public.ecr.aws/eks-distro-build-tooling/nodejs:16 | ||
|
||
# Create and change to the app directory | ||
WORKDIR /usr/src/app | ||
|
||
# Copy application dependency manifests to the container image. | ||
# A wildcard is used to ensure copying both package.json AND package-lock.json (if available). | ||
# Copying this first prevents re-running npm install on every code change. | ||
COPY package*.json ./ | ||
|
||
# Install dependencies | ||
RUN npm install | ||
|
||
# Copy local code to the container image. | ||
COPY . . | ||
|
||
# Run the web service on container startup. | ||
CMD [ "npm", "start" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
const axios = require('axios'); | ||
|
||
// Send API requests to the sample app | ||
const sendRequests = async (urls) => { | ||
try { | ||
const fetchPromises = urls.map(url => axios.get(url)); | ||
const responses = await Promise.all(fetchPromises); | ||
|
||
// Handle the responses | ||
responses.forEach((response, index) => { | ||
if (response.status === 200) { | ||
const data = response.data; | ||
console.log(`Response from ${urls[index]}:`, data); | ||
} else { | ||
console.error(`Failed to fetch ${urls[index]}:`, response.statusText); | ||
} | ||
}); | ||
} catch (error) { | ||
console.error('Error sending GET requests:', error); | ||
} | ||
} | ||
|
||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); | ||
|
||
// This loop will run until the environment variables are available | ||
const waitForEnvVariables = async () => { | ||
while (!process.env.MAIN_ENDPOINT || !process.env.REMOTE_ENDPOINT || !process.env.ID || !process.env.CANARY_TYPE) { | ||
console.log('Environment variables not set. Waiting for 10 seconds...'); | ||
await sleep(10000); // Wait for 10 seconds | ||
} | ||
}; | ||
|
||
// Traffic generator that sends traffic every specified interval. Send request immediately then every 2 minutes afterwords | ||
const trafficGenerator = async (interval) => { | ||
await waitForEnvVariables(); | ||
|
||
const mainEndpoint = process.env.MAIN_ENDPOINT; | ||
const remoteEndpoint = process.env.REMOTE_ENDPOINT; | ||
const id = process.env.ID; | ||
const canaryType = process.env.CANARY_TYPE | ||
|
||
let urls = [ | ||
`http://${mainEndpoint}/outgoing-http-call`, | ||
`http://${mainEndpoint}/aws-sdk-call?ip=${remoteEndpoint}&testingId=${id}`, | ||
`http://${mainEndpoint}/remote-service?ip=${remoteEndpoint}&testingId=${id}`, | ||
`http://${mainEndpoint}/client-call` | ||
]; | ||
|
||
if (canaryType === 'java-eks' || canaryType === 'python-eks') { | ||
urls.push(`http://${mainEndpoint}/mysql`) | ||
} | ||
|
||
// Need to call some APIs so that it exceeds the metric limiter threshold and make the test | ||
// APIs generate AllOtherOperations metric. Sleep for a minute to let cloudwatch service process the API call | ||
// Calling it here before calling the remote sample app endpoint because the API generated by it is validated | ||
// for AllOtherRemoteOperations in the metric validation step | ||
if (canaryType === 'java-metric-limiter'){ | ||
const fakeUrls = [ | ||
`http://${mainEndpoint}`, | ||
`http://${mainEndpoint}/fake-endpoint` | ||
] | ||
// Send the fake requests and wait a minute | ||
await sendRequests(fakeUrls); | ||
await sleep(60000); | ||
} | ||
|
||
await sendRequests(urls); | ||
setInterval(() => sendRequests(urls), interval); | ||
} | ||
|
||
const interval = 60 * 1000; | ||
// Start sending GET requests every minute (60,000 milliseconds) | ||
trafficGenerator(interval); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "traffic-generator", | ||
"version": "1.0.0", | ||
"description": "A simple traffic generator that sends GET requests to a list of URLs every 2 minutes", | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "node index.js" | ||
}, | ||
"dependencies": { | ||
"axios": "^1.4.0" | ||
} | ||
} |