Skip to content

Commit

Permalink
feat: structure refactoring and pulumi initial config (#28)
Browse files Browse the repository at this point in the history
* feat: structure refactoring and pulumi initial config

* feat: update folders naming to align with the approach one api per repo

* feat: pack source api files under src folder

* feat: add initial postman collection
  • Loading branch information
kshychko authored Jul 11, 2022
1 parent 8049e2c commit a31cbee
Show file tree
Hide file tree
Showing 21 changed files with 353 additions and 5 deletions.
Binary file removed APIs/.DS_Store
Binary file not shown.
172 changes: 172 additions & 0 deletions api/Traceability API Test Cases.postman_collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
{
"info": {
"_postman_id": "94d787d7-723d-4b07-a520-fe25cc97e1c2",
"name": "Traceability API Test Cases",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "19445004"
},
"item": [
{
"name": "Create ObjectEvent",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 201\", function () {",
" pm.response.to.have.status(201);",
"});",
"",
"pm.test(\"EventID id is expected\", function () {",
" var jsonData = pm.response.json();",
" pm.collectionVariables.set(\"eventID\", jsonData.eventID);",
"});",
""
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disabledSystemHeaders": {}
},
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"itemList\": [\n {\n \"id\": \"string\",\n \"name\": \"string\"\n }\n ],\n \"quantityList\": [\n {\n \"productClass\": \"string\",\n \"quantity\": \"string\",\n \"uom\": \"string\"\n }\n ],\n \"eventTime\": \"2019-08-24T14:15:22Z\",\n \"actionCode\": \"string\",\n \"dispositionCode\": \"string\",\n \"businessStepCode\": \"string\",\n \"readPointId\": \"string\",\n \"locationId\": \"string\"\n} \n",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{TRACEABILITY_API_ENDPOINT}}/objectEvents",
"host": [
"{{TRACEABILITY_API_ENDPOINT}}"
],
"path": [
"objectEvents"
]
}
},
"response": []
},
{
"name": "Get ObjectEvent",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"EventID id is expected\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.eventID).to.eql(pm.collectionVariables.get(\"eventID\"));",
"",
"});",
""
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disabledSystemHeaders": {}
},
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{TRACEABILITY_API_ENDPOINT}}/objectEvents/{{eventID}}",
"host": [
"{{TRACEABILITY_API_ENDPOINT}}"
],
"path": [
"objectEvents",
"{{eventID}}"
]
}
},
"response": []
},
{
"name": "Get ObjectEvents",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"EventID id is expected\", function () {",
" var jsonData = pm.response.json();",
" const event = jsonData.items.find( ({ eventID }) => eventID === pm.collectionVariables.get(\"eventID\") );",
" pm.expect(event.eventID).to.eql(pm.collectionVariables.get(\"eventID\"));",
"",
"});",
""
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disabledSystemHeaders": {}
},
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{TRACEABILITY_API_ENDPOINT}}/objectEvents/",
"host": [
"{{TRACEABILITY_API_ENDPOINT}}"
],
"path": [
"objectEvents",
""
]
}
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"key": "TRACEABILITY_API_V1",
"value": "https://9idvmp0256.execute-api.ap-southeast-2.amazonaws.com/v1",
"type": "string"
},
{
"key": "eventID",
"value": ""
}
]
}
10 changes: 5 additions & 5 deletions APIs/traceabilityAPI.json → api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1319,19 +1319,19 @@
}
}
},
"Template_ErrorSchema": {
"TemplateErrorSchema": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Template_Error"
"$ref": "#/components/schemas/TemplateError"
},
"description": ""
}
}
},
"Template_Error": {
"TemplateError": {
"type": "object",
"properties": {
"id": {
Expand All @@ -1348,12 +1348,12 @@
"description": ""
},
"source": {
"$ref": "#/components/schemas/Template_ErrorSource",
"$ref": "#/components/schemas/TemplateErrorSource",
"description": ""
}
}
},
"Template_ErrorSource": {
"TemplateErrorSource": {
"type": "object",
"properties": {
"pointer": {
Expand Down
3 changes: 3 additions & 0 deletions config/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pyc
venv/
tmp/
2 changes: 2 additions & 0 deletions config/Pulumi.dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config:
aws:region: ap-southeast-2
2 changes: 2 additions & 0 deletions config/Pulumi.mock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config:
aws:region: ap-southeast-2
6 changes: 6 additions & 0 deletions config/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: sustainability
runtime:
name: python
# options:
# virtualenv: venv
description: An AWS Python Pulumi program for sustainability api mock deployment
100 changes: 100 additions & 0 deletions config/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""An AWS Python Pulumi program"""

import pulumi
import pulumi_aws as aws
import iam
import json
import string
import random
from pulumi import ResourceOptions
from pulumi_command import local

region = aws.config.region

custom_stage_name = 'v1'

build = local.Command(''.join(random.choice(string.ascii_lowercase) for i in range(10)),
create="./scripts/build.sh"
)

##################
## Lambda Function
##################

# Create a Lambda function, using the zip created with the scripts/build.sh script.

lambda_func = aws.lambda_.Function("itc-api-imp",
role=iam.lambda_role.arn,
runtime="python3.9",
handler="src/itc_api.handler",
code=pulumi.FileArchive('./tmp/deployment-package.zip'),
opts=ResourceOptions(depends_on=[build])
)


####################################################################
##
## API Gateway REST API (API Gateway V1 / original)
## /{proxy+} - passes all requests through to the lambda function
##
####################################################################
# Create a single Swagger spec route handler for a Lambda function.
def swagger_route_handler(arn, openapi_):
openapi["paths"]["/{proxy+}"] = {
"x-amazon-apigateway-any-method": {
"x-amazon-apigateway-integration": {
"uri": f'arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/{arn}/invocations',
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"type": "aws_proxy",
},
},
}
return openapi_

# TODO: figure out how to create the api gateway with one step
# at the moment the resource creation fails if the code below isn't being executed first
# openapi = {
# "swagger": "2.0",
# "info": {"title": "api", "version": "1.0"},
# "paths": {},
# }
#
# rest_api = aws.apigateway.RestApi("api",
# body=lambda_func.arn.apply(lambda arn: json.dumps(swagger_route_handler(arn, openapi))))


with open("../api/openapi.json", encoding="utf-8") as f:
read_data = f.read()
f.closed

openapi = json.loads(read_data);
rest_api = aws.apigateway.RestApi("api",
body=lambda_func.arn.apply(
lambda arn: json.dumps(swagger_route_handler(arn, openapi))))

# Create a deployment of the Rest API.
deployment = aws.apigateway.Deployment("api-deployment",
rest_api=rest_api.id,
# Note: Set to empty to avoid creating an implicit stage, we'll create it
# explicitly below instead.
stage_name="",
)

# Create a stage, which is an addressable instance of the Rest API. Set it to point at the latest deployment.
stage = aws.apigateway.Stage("api-stage",
rest_api=rest_api.id,
deployment=deployment.id,
stage_name=custom_stage_name,
)

# Give permissions from API Gateway to invoke the Lambda
invoke_permission = aws.lambda_.Permission("api-lambda-permission",
action="lambda:invokeFunction",
function=lambda_func.name,
principal="apigateway.amazonaws.com",
source_arn=deployment.execution_arn.apply(lambda arn: arn + "*/*"),
)

# Export the https endpoint of the running Rest API
pulumi.export("apigateway-rest-endpoint", deployment.invoke_url.apply(lambda url: url + custom_stage_name))
43 changes: 43 additions & 0 deletions config/iam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2016-2018, Pulumi Corporation. All rights reserved.

from pulumi_aws import iam

lambda_role = iam.Role('lambdaRole',
assume_role_policy="""{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}"""
)

lambda_role_policy = iam.RolePolicy('lambdaRolePolicy',
role=lambda_role.id,
policy="""{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"dynamodb:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": "arn:aws:dynamodb:*:*:*"
}]
}"""
)
3 changes: 3 additions & 0 deletions config/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pulumi>=3.0.0,<4.0.0
pulumi-aws>=5.0.0,<6.0.0
pulumi-command>=0.3.2,<1.0.0
17 changes: 17 additions & 0 deletions config/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

#set -e

pip install -U pip setuptools wheel
pip install pdm
if [ -d "tmp" ]; then
rm -rf "tmp"
fi
mkdir "tmp"
cp -r ../mock/* "tmp"
cd "tmp"
pdm sync --prod --no-editable
cd __pypackages__/3.9/lib
zip -r ../../../deployment-package.zip .
cd ../../../
zip -g deployment-package.zip src/*.py
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit a31cbee

Please sign in to comment.