Skip to content

Commit 954ee59

Browse files
authored
feat: add simple OAuth for testing MCP flows (#390)
* feat: add basic OAuth flow * feat: add OAuth 2 flow to user service * feat: fix integration test issue * chore: clippy fix + build warnings * feat: update auth flow and add OAuth to MCP server * feat: add IaC examples for MCP server * fix: update Postgres datatypes * feat: add OAuth endpoints to Terraform * feat: add OAuth endpoints to TF and SAM * feat: update login form styling * chore: update DDB table name * chore: update packaging script for additional functions * feat: add build step to tf-apply * fix: update Terraform and SAM templates * fix: add build sub command to SAM deploy * chore: add log message for email under test * fix: resolve TF and SAM DDB definition issues * fix: resolve compilation issue * fix: update template DDB definition * chore: updates to load sims and packages * feat: fix integration tests for user service * feat: removed unused referecens * fix: integration test compilation errors * feat: add poetry export command * feat: fix TF example API stages * feat: update SAM template to use cargo lambda build * fix: resolve issue with SAM template permissions * fix: resolve integration test issues * chore: update SAM template to use pre-built
1 parent 80537b3 commit 954ee59

File tree

103 files changed

+12130
-1172
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+12130
-1172
lines changed

cdk-deploy-all.sh

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ cdk deploy --require-approval never
1111
popd
1212

1313
# Service deployments in parallel
14-
pushd src/inventory-service/cdk
14+
pushd src/inventory-service
1515
mvn clean package -DskipTests -q
16+
popd
17+
pushd src/inventory-service/cdk
1618
cdk deploy --require-approval never &>../../../deployment-logs/inventory-service.log &
1719
popd
1820

@@ -41,8 +43,16 @@ cdk deploy --require-approval never &>../../deployment-logs/loyalty-point-servic
4143
popd
4244

4345
pushd src/activity-service
44-
npm i
45-
./package.sh
46+
pip install --upgrade pip pre-commit poetry
47+
pre-commit install
48+
poetry config --local virtualenvs.in-project true
49+
poetry install --no-root
50+
npm ci
51+
poetry export --only=dev --format=requirements.txt > dev_requirements.txt
52+
poetry export --without=dev --format=requirements.txt > lambda_requirements.txt
53+
rm -rf .build
54+
mkdir -p .build/lambdas ; cp -r activity_service .build/lambdas
55+
mkdir -p .build/common_layer ; poetry export --without=dev --format=requirements.txt > .build/common_layer/requirements.txt
4656
cdk deploy --require-approval=never &>../../deployment-logs/activity-service.log &
4757
popd
4858

loadtest/Dockerfile-longrunning

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM node:22-alpine
2+
3+
WORKDIR /usr/app
4+
COPY ./ /usr/app
5+
RUN npm install -g artillery@latest
6+
RUN npm install
7+
RUN chmod +x start.sh
8+
9+
CMD ["./start.sh"]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: "3.8"
2+
3+
services:
4+
loadtest:
5+
restart: always
6+
build:
7+
context: .
8+
dockerfile: Dockerfile-longrunning
9+
environment:
10+
- ENV=${ENV}
11+
- PRODUCT_API_ENDPOINT=${PRODUCT_API_ENDPOINT}
12+
- USER_API_ENDPOINT=${USER_API_ENDPOINT}
13+
- ORDER_API_ENDPOINT=${ORDER_API_ENDPOINT}
14+
- INVENTORY_API_ENDPOINT=${INVENTORY_API_ENDPOINT}
15+
- LOYALTY_API_ENDPOINT=${LOYALTY_API_ENDPOINT}

loadtest/generator.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ module.exports = {
1212
Math.random() * context.vars.products.length
1313
);
1414

15-
console.log(context.vars.products[randomIndex]);
16-
1715
context.vars.OrderProducts = [context.vars.products[randomIndex].productId];
1816

1917
return done();

loadtest/loadsimulator-low.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
config:
2+
target: "https://"
3+
http:
4+
timeout: 60
5+
processor: "generator.js"
6+
phases:
7+
# Arrival count is a fixed number of requests to be sent over the duration
8+
# Over the course of 10 seconds, 2 requests will be sent
9+
- duration: 10
10+
arrivalCount: 2
11+
- duration: 90
12+
arrivalCount: 20
13+
- duration: 120
14+
arrivalCount: 5
15+
- duration: 30
16+
arrivalCount: 10
17+
- duration: 10
18+
arrivalCount: 10
19+
20+
scenarios:
21+
- name: "User create order"
22+
flow:
23+
- function: "generateEmailAddress"
24+
- post:
25+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/user"
26+
headers:
27+
Content-Type: "application/json"
28+
json:
29+
email_address: "{{ Email }}"
30+
first_name: "Test"
31+
last_name: "User"
32+
password: "{{ Password }}"
33+
- post:
34+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
35+
headers:
36+
Content-Type: "application/json"
37+
json:
38+
email_address: "{{ Email }}"
39+
password: "{{ Password }}"
40+
capture:
41+
json: "$.data.token"
42+
as: jwt
43+
- get:
44+
url: "{{ $processEnvironment.PRODUCT_API_ENDPOINT }}/product"
45+
capture:
46+
json: "$.data"
47+
as: products
48+
- function: setOrderProducts
49+
- post:
50+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders"
51+
headers:
52+
Content-Type: "application/json"
53+
Authorization: "Bearer {{jwt}}"
54+
json:
55+
products: "{{ OrderProducts }}"
56+
capture:
57+
json: "$.data.orderId"
58+
as: OrderId
59+
- name: "Admin complete order"
60+
flow:
61+
- post:
62+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
63+
headers:
64+
Content-Type: "application/json"
65+
json:
66+
email_address: "[email protected]"
67+
password: "Admin!23"
68+
capture:
69+
json: "$.data.token"
70+
as: adminJwt
71+
- get:
72+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders/confirmed"
73+
headers:
74+
Authorization: "Bearer {{adminJwt}}"
75+
capture:
76+
json: "$"
77+
as: confirmedOrders
78+
- function: getLatestConfirmedOrder
79+
- post:
80+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders/{{ ConfirmedOrderId }}/complete"
81+
ifTrue: 'ConfirmedOrderId'
82+
headers:
83+
Content-Type: "application/json"
84+
Authorization: "Bearer {{adminJwt}}"
85+
json:
86+
orderId: "{{ ConfirmedOrderId }}"
87+
userId: "{{ ConfirmedOrderUserId }}"
88+
- name: "Admin re-stock products"
89+
flow:
90+
- post:
91+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
92+
headers:
93+
Content-Type: "application/json"
94+
json:
95+
email_address: "[email protected]"
96+
password: "Admin!23"
97+
capture:
98+
json: "$.data.token"
99+
as: adminJwt
100+
- get:
101+
url: "{{ $processEnvironment.PRODUCT_API_ENDPOINT }}/product"
102+
capture:
103+
json: "$.data"
104+
as: products
105+
- function: setOutOfStockProductId
106+
- get:
107+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/inventory/{{ ProductId }}"
108+
ifTrue: 'ProductId'
109+
headers:
110+
Authorization: "Bearer {{adminJwt}}"
111+
capture:
112+
json: "$.data.currentStockLevel"
113+
as: currentStockLevel
114+
- function: generateRestockAmount
115+
- post:
116+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/inventory"
117+
ifTrue: 'ProductId'
118+
headers:
119+
Content-Type: "application/json"
120+
Authorization: "Bearer {{adminJwt}}"
121+
json:
122+
productId: "{{ProductId}}"
123+
stockLevel: "{{NewStockLevel}}"
124+
- name: "Admin create products"
125+
flow:
126+
- post:
127+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
128+
headers:
129+
Content-Type: "application/json"
130+
json:
131+
email_address: "[email protected]"
132+
password: "Admin!23"
133+
capture:
134+
json: "$.data.token"
135+
as: adminJwt
136+
- function: generateProductName
137+
- post:
138+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/product"
139+
ifTrue: 'ProductName'
140+
headers:
141+
Content-Type: "application/json"
142+
Authorization: "Bearer {{adminJwt}}"
143+
json:
144+
name: "{{ProductName}}"
145+
price: "{{Price}}"

loadtest/loadsimulator.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ config:
44
timeout: 60
55
processor: "generator.js"
66
phases:
7+
# Arrival count is a fixed number of requests to be sent over the duration
8+
# Over the course of 10 seconds, 10 requests will be sent
79
- duration: 10
810
arrivalCount: 10
911
- duration: 30

loadtest/loadsimulator_1.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
config:
2+
target: "https://"
3+
http:
4+
timeout: 60
5+
processor: "generator.js"
6+
phases:
7+
# Arrival count is a fixed number of requests to be sent over the duration
8+
# Over the course of 10 seconds, 10 requests will be sent
9+
- duration: 10
10+
arrivalCount: 10
11+
- duration: 30
12+
arrivalCount: 10
13+
14+
scenarios:
15+
- name: "User create order"
16+
flow:
17+
- function: "generateEmailAddress"
18+
- post:
19+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/user"
20+
headers:
21+
Content-Type: "application/json"
22+
json:
23+
email_address: "{{ Email }}"
24+
first_name: "Test"
25+
last_name: "User"
26+
password: "{{ Password }}"
27+
- post:
28+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
29+
headers:
30+
Content-Type: "application/json"
31+
json:
32+
email_address: "{{ Email }}"
33+
password: "{{ Password }}"
34+
capture:
35+
json: "$.data.token"
36+
as: jwt
37+
- get:
38+
url: "{{ $processEnvironment.PRODUCT_API_ENDPOINT }}/product"
39+
capture:
40+
json: "$.data"
41+
as: products
42+
- function: setOrderProducts
43+
- post:
44+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders"
45+
headers:
46+
Content-Type: "application/json"
47+
Authorization: "Bearer {{jwt}}"
48+
json:
49+
products: "{{ OrderProducts }}"
50+
capture:
51+
json: "$.data.orderId"
52+
as: OrderId
53+
- name: "Admin complete order"
54+
flow:
55+
- post:
56+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
57+
headers:
58+
Content-Type: "application/json"
59+
json:
60+
email_address: "[email protected]"
61+
password: "Admin!23"
62+
capture:
63+
json: "$.data.token"
64+
as: adminJwt
65+
- get:
66+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders/confirmed"
67+
headers:
68+
Authorization: "Bearer {{adminJwt}}"
69+
capture:
70+
json: "$"
71+
as: confirmedOrders
72+
- function: getLatestConfirmedOrder
73+
- post:
74+
url: "{{ $processEnvironment.ORDER_API_ENDPOINT }}/orders/{{ ConfirmedOrderId }}/complete"
75+
ifTrue: 'ConfirmedOrderId'
76+
headers:
77+
Content-Type: "application/json"
78+
Authorization: "Bearer {{adminJwt}}"
79+
json:
80+
orderId: "{{ ConfirmedOrderId }}"
81+
userId: "{{ ConfirmedOrderUserId }}"
82+
- name: "Admin re-stock products"
83+
flow:
84+
- post:
85+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
86+
headers:
87+
Content-Type: "application/json"
88+
json:
89+
email_address: "[email protected]"
90+
password: "Admin!23"
91+
capture:
92+
json: "$.data.token"
93+
as: adminJwt
94+
- get:
95+
url: "{{ $processEnvironment.PRODUCT_API_ENDPOINT }}/product"
96+
capture:
97+
json: "$.data"
98+
as: products
99+
- function: setOutOfStockProductId
100+
- get:
101+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/inventory/{{ ProductId }}"
102+
ifTrue: 'ProductId'
103+
headers:
104+
Authorization: "Bearer {{adminJwt}}"
105+
capture:
106+
json: "$.data.currentStockLevel"
107+
as: currentStockLevel
108+
- function: generateRestockAmount
109+
- post:
110+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/inventory"
111+
ifTrue: 'ProductId'
112+
headers:
113+
Content-Type: "application/json"
114+
Authorization: "Bearer {{adminJwt}}"
115+
json:
116+
productId: "{{ProductId}}"
117+
stockLevel: "{{NewStockLevel}}"
118+
- name: "Admin create products"
119+
flow:
120+
- post:
121+
url: "{{ $processEnvironment.USER_API_ENDPOINT }}/login"
122+
headers:
123+
Content-Type: "application/json"
124+
json:
125+
email_address: "[email protected]"
126+
password: "Admin!23"
127+
capture:
128+
json: "$.data.token"
129+
as: adminJwt
130+
- function: generateProductName
131+
- post:
132+
url: "{{ $processEnvironment.INVENTORY_API_ENDPOINT }}/product"
133+
ifTrue: 'ProductName'
134+
headers:
135+
Content-Type: "application/json"
136+
Authorization: "Bearer {{adminJwt}}"
137+
json:
138+
name: "{{ProductName}}"
139+
price: "{{Price}}"

0 commit comments

Comments
 (0)