Skip to content

Commit 15f9b20

Browse files
committed
Create Traffic Generator for Calling Sample App Endpoints
1 parent b3d7e7c commit 15f9b20

File tree

17 files changed

+304
-230
lines changed

17 files changed

+304
-230
lines changed

.github/workflows/java-eks-e2e-test.yml

+21-8
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,28 @@ jobs:
321321
working-directory: terraform/java/eks
322322
run: echo "APP_ENDPOINT=$(terraform output sample_app_endpoint)" >> $GITHUB_ENV
323323

324-
# This steps increases the speed of the validation by creating the telemetry data in advance
325-
- name: Call all test APIs
326-
continue-on-error: true
324+
# - name: Deploy the traffic generator
325+
# working-directory: traffic-generator/deployments
326+
# run: |
327+
# sed -e "s/111122223333.dkr.ecr.us-west-2/${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}/g" -e "s/MAIN_SAMPLE_APP_ENDPOINT/${{ env.APP_ENDPOINT }}/g" -e "s/REMOTE_SAMPLE_APP_ENDPOINT/${{ env.REMOTE_SERVICE_POD_IP }}/g" -e "s/TESTING_ID/${{ env.TESTING_ID }}/g" ./traffic-generator.yaml
328+
#
329+
# kubectl apply --namespace=${{ env.SAMPLE_APP_NAMESPACE }} -f ./traffic-generator.yaml
330+
#
331+
# cat ./traffic-generator.yaml
332+
#
333+
# sleep 10000
334+
335+
- name: Deploy the traffic generator
327336
run: |
328-
curl -S -s "http://${{ env.APP_ENDPOINT }}/outgoing-http-call"
329-
curl -S -s "http://${{ env.APP_ENDPOINT }}/aws-sdk-call?ip=${{ env.REMOTE_SERVICE_POD_IP }}&testingId=${{ env.TESTING_ID }}"
330-
curl -S -s "http://${{ env.APP_ENDPOINT }}/remote-service?ip=${{ env.REMOTE_SERVICE_POD_IP }}&testingId=${{ env.TESTING_ID }}"
331-
curl -S -s "http://${{ env.APP_ENDPOINT }}/client-call"
332-
curl -S -s "http://${{ env.APP_ENDPOINT }}/mysql"
337+
kubectl create deployment traffic-generator \
338+
--image=${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}.amazonaws.com/e2e-test-resource:traffic-generator \
339+
--replicas=1
340+
341+
kubectl set env deployment/traffic-generator MAIN_ENDPOINT=${{ env.APP_ENDPOINT }}
342+
kubectl set env deployment/traffic-generator REMOTE_ENDPOINT=${{ env.REMOTE_SERVICE_POD_IP }}
343+
kubectl set env deployment/traffic-generator ID=${{ env.TESTING_ID }}
344+
345+
kubectl delete pods --all -n ${{ env.SAMPLE_APP_NAMESPACE }}
333346
334347
- name: Initiate Gradlew Daemon
335348
if: steps.initiate-gradlew == 'failure'

.github/workflows/test.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
## This workflow aims to run the Application Signals end-to-end tests as a canary to
5+
## test the artifacts for App Signals enablement. It will deploy a sample app and remote
6+
## service on two EC2 instances, call the APIs, and validate the generated telemetry,
7+
## including logs, metrics, and traces.
8+
name: Test
9+
on:
10+
# push:
11+
12+
permissions:
13+
id-token: write
14+
contents: read
15+
16+
jobs:
17+
# default:
18+
# strategy:
19+
# fail-fast: false
20+
# matrix:
21+
# aws-region: ['us-east-1']
22+
# uses: ./.github/workflows/java-ec2-default-e2e-test.yml
23+
# secrets: inherit
24+
# with:
25+
# aws-region: ${{ matrix.aws-region }}
26+
# caller-workflow-name: 'test'
27+
28+
eks:
29+
strategy:
30+
fail-fast: false
31+
matrix:
32+
aws-region: [ 'us-east-1' ]
33+
uses: ./.github/workflows/java-eks-e2e-test.yml
34+
secrets: inherit
35+
with:
36+
aws-region: ${{ matrix.aws-region }}
37+
test-cluster-name: 'e2e-playground'
38+
caller-workflow-name: 'test'
39+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# This workflow will build and the traffic generator image to each region whenever there is an update made to the traffic-generator folder.
2+
# This image will be used by EKS and K8s test to call sample app endpoints
3+
name: Create and Push Traffic Generator Image
4+
5+
on:
6+
workflow_dispatch:
7+
push:
8+
# branches:
9+
# - main
10+
# paths:
11+
# - 'traffic-generator/**'
12+
13+
permissions:
14+
id-token: write
15+
contents: read
16+
17+
jobs:
18+
build-and-push-image:
19+
runs-on: ubuntu-latest
20+
strategy:
21+
matrix:
22+
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',
23+
'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1',
24+
'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',
25+
'us-east-1','us-east-2','us-west-1','us-west-2']
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
30+
- name: Configure AWS Credentials
31+
uses: aws-actions/configure-aws-credentials@v4
32+
with:
33+
role-to-assume: ${{ secrets.E2E_SECRET_TEST_ROLE_ARN }}
34+
aws-region: us-east-1
35+
36+
- name: Retrieve account
37+
uses: aws-actions/aws-secretsmanager-get-secrets@v1
38+
with:
39+
secret-ids: |
40+
ACCOUNT_ID, region-account/${{ matrix.aws-region }}
41+
42+
- name: Configure AWS Credentials
43+
uses: aws-actions/configure-aws-credentials@v4
44+
with:
45+
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }}
46+
aws-region: ${{ matrix.aws-region }}
47+
48+
- name: Login to Amazon ECR
49+
id: login-ecr
50+
uses: aws-actions/amazon-ecr-login@v2
51+
52+
- name: Build, tag, and push image to Amazon ECR
53+
working-directory: traffic-generator
54+
env:
55+
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
56+
REPOSITORY: e2e-test-resource
57+
IMAGE_TAG: traffic-generator
58+
run: |
59+
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
60+
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG

terraform/java/ec2/default/main.tf

+38
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ resource "aws_instance" "main_service_instance" {
9494
}
9595
}
9696

97+
98+
9799
resource "null_resource" "main_service_setup" {
98100
connection {
99101
type = "ssh"
@@ -212,3 +214,39 @@ resource "null_resource" "remote_service_setup" {
212214

213215
depends_on = [aws_instance.remote_service_instance]
214216
}
217+
218+
resource "null_resource" "traffic_generator_setup" {
219+
connection {
220+
type = "ssh"
221+
user = var.user
222+
private_key = local.private_key_content
223+
host = aws_instance.main_service_instance.public_ip
224+
}
225+
226+
provisioner "remote-exec" {
227+
inline = [
228+
<<-EOF
229+
# Bring in the traffic generator files to EC2 Instance
230+
traffic_generator_index='${file("../../../traffic-generator/index.js")}'
231+
traffic_generator_package='${file("../../../traffic-generator/package.json")}'
232+
233+
echo $traffic_generator_index > index.js
234+
echo $traffic_generator_package > package.json
235+
236+
# Install the traffic generator dependencies
237+
sudo yum install nodejs -y && npm install
238+
239+
# Start the traffic generator in the background
240+
tmux new -s traffic-generator -d
241+
tmux send-keys -t traffic-generator 'cd /traffic-generator/' C-m
242+
tmux send-keys -t traffic-generator "export MAIN_ENDPOINT=\"${aws_instance.main_service_instance.public_dns}\"" C-m
243+
tmux send-keys -t traffic-generator "export REMOTE_ENDPOINT=\"${aws_instance.remote_service_instance.public_ip}\"" C-m
244+
tmux send-keys -t traffic-generator "export ID=\"${var.test_id}\"" C-m
245+
tmux send-keys -t traffic-generator "node index.js" C-m
246+
247+
EOF
248+
]
249+
}
250+
251+
depends_on = [null_resource.main_service_setup, null_resource.remote_service_setup]
252+
}

traffic-generator/Dockerfile

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Use the official lightweight Node.js 16 image.
2+
# https://hub.docker.com/_/node
3+
# FROM node:16-slim
4+
FROM public.ecr.aws/eks-distro-build-tooling/nodejs:16
5+
6+
# Create and change to the app directory
7+
WORKDIR /usr/src/app
8+
9+
# Copy application dependency manifests to the container image.
10+
# A wildcard is used to ensure copying both package.json AND package-lock.json (if available).
11+
# Copying this first prevents re-running npm install on every code change.
12+
COPY package*.json ./
13+
14+
# Install dependencies
15+
RUN npm install
16+
17+
# Copy local code to the container image.
18+
COPY . .
19+
20+
# Run the web service on container startup.
21+
CMD [ "npm", "start" ]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: traffic-generator
5+
labels:
6+
app: traffic-generator
7+
spec:
8+
replicas: 1
9+
selector:
10+
matchLabels:
11+
app: traffic-generator
12+
template:
13+
metadata:
14+
labels:
15+
app: traffic-generator
16+
spec:
17+
containers:
18+
- name: traffic-generator
19+
image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/traffic-generator:latest
20+
env:
21+
- name: MAIN_ENDPOINT
22+
value: "MAIN_SAMPLE_APP_ENDPOINT"
23+
- name: REMOTE_ENDPOINT
24+
value: "REMOTE_SAMPLE_APP_ENDPOINT"
25+
- name: ID
26+
value: "TESTING_ID"

traffic-generator/index.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const axios = require('axios');
2+
3+
const mainEndpoint = process.env.MAIN_ENDPOINT || 'your-main-sample-app-end-point';
4+
const remoteEndpoint = process.env.REMOTE_ENDPOINT || 'your-remote-sample-app-end-point';
5+
const id = process.env.ID || 'your-testing-id';
6+
7+
const urls = [
8+
`http://${mainEndpoint}/outgoing-http-call`,
9+
`http://${mainEndpoint}/aws-sdk-call?ip=${remoteEndpoint}&testingId=${id}`,
10+
`http://${mainEndpoint}/remote-service?ip=${remoteEndpoint}&testingId=${id}`,
11+
`http://${mainEndpoint}/client-call`,
12+
`http://${mainEndpoint}/mysql`
13+
]
14+
15+
// Send API requests to the sample app
16+
async function sendRequests(urls) {
17+
try {
18+
const fetchPromises = urls.map(url => axios.get(url));
19+
const responses = await Promise.all(fetchPromises);
20+
21+
// Handle the responses
22+
responses.forEach((response, index) => {
23+
if (response.status === 200) {
24+
const data = response.data;
25+
console.log(`Response from ${urls[index]}:`, data);
26+
} else {
27+
console.error(`Failed to fetch ${urls[index]}:`, response.statusText);
28+
}
29+
});
30+
} catch (error) {
31+
console.error('Error sending GET requests:', error);
32+
}
33+
}
34+
35+
// Traffic generator that sends traffic every specified interval. Send request immediately then every 2 minutes afterwards
36+
function trafficGenerator(urls, interval) {
37+
sendGetRequests(urls);
38+
setInterval(() => sendRequests(urls), interval);
39+
}
40+
41+
// Start sending GET requests every 2 minutes (120,000 milliseconds)
42+
startInterval(urls, 120000);

traffic-generator/package.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "traffic-generator",
3+
"version": "1.0.0",
4+
"description": "A simple traffic generator that sends GET requests to a list of URLs every 2 minutes",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "node index.js"
8+
},
9+
"dependencies": {
10+
"node-fetch": "^3.2.0"
11+
}
12+
}

validator/src/main/java/com/amazon/aoc/callers/HttpCaller.java

-102
This file was deleted.

0 commit comments

Comments
 (0)