Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
e02c1d1
chore: Converted SAM Config file from TOML to YAML using samp-cli
igorlg Aug 24, 2023
67cce74
feat: Updated template for new Contracts service implementation model
igorlg Aug 24, 2023
329ebed
chore: add API contract
igorlg Aug 24, 2023
4511b41
chore: Refactored integration tests
igorlg Aug 24, 2023
9178454
chore: Updated unit tests, et al
igorlg Aug 24, 2023
ed05ee8
feat: Add EB Pipes
igorlg Aug 25, 2023
5422ed1
bug: remove file added by mistake
igorlg Aug 25, 2023
04d5933
feat: Refactored unicorn_web
igorlg Aug 25, 2023
94884fa
chore: Implemented final Unit tests for unicorn_contracts
igorlg Aug 29, 2023
7ee33b8
test: Fixed all unit, integration and Curl tests for unicorn_contracts
igorlg Aug 31, 2023
e96e9c9
chore: add missing licensing header
igorlg Aug 31, 2023
843e573
chore: typos and file styling
igorlg Sep 1, 2023
5f69695
fix: remote unused test file, fixed naming convention of subscriber E…
igorlg Sep 1, 2023
1c49f9a
chore: remove unused coverage file
igorlg Sep 4, 2023
ae8f05c
feat: Updated unicorn_web to v2 architecture, implemented integration…
igorlg Sep 4, 2023
bc1abb5
fix: remove curl-test from make test alias
igorlg Sep 4, 2023
cd069f3
chore: remove unused swagger-cli from make build
igorlg Sep 4, 2023
db480c5
chore: Update Python dependencies on unicorn_properties
igorlg Sep 4, 2023
bd48fdf
chore: remove Coverage config, add Integration tests to pyproject in …
igorlg Sep 4, 2023
36cf11e
chore: replace samconfig file from TOML to YAML
igorlg Sep 4, 2023
7398792
feat: Add EventBridge subscribers and subscription rules to unicorn_p…
igorlg Sep 4, 2023
7036ed4
chore: move state machine definition out of src/ to match across runt…
igorlg Sep 4, 2023
1015c1c
chore: update template section name comments
igorlg Sep 4, 2023
08239a6
chore: update cfn-lint ignored rules
igorlg Sep 4, 2023
7b17abb
chore: linted/inlined intrinsic functions for better readability
igorlg Sep 4, 2023
d51c0fa
feat: add local EB bus to unicorn_properties, replace hard-coded serv…
igorlg Sep 4, 2023
855a317
feat: add EB SSM Params to unicorn_properties
igorlg Sep 4, 2023
0dfce33
chore: add missing DDB permissions, remove unused SQS permission from…
igorlg Sep 4, 2023
70320f6
chore: lint unicorn_properties template, change EB trigger rule for C…
igorlg Sep 4, 2023
a870ebe
chore: fix EventBus name, lint JSON files in unicorn_properties event…
igorlg Sep 4, 2023
b11afb8
chore: replace hardcoded stack name from Makefile with YQ command to …
igorlg Sep 4, 2023
014f2c3
chore: lint and document Makefile stage groups
igorlg Sep 4, 2023
fd19ea1
test: add Integration tests scaffold
igorlg Sep 4, 2023
f432c5a
chore: Add SAM validate to Makefile build stage
igorlg Sep 4, 2023
53c8fd4
chore: remove unecessary SAM command line argument from build stage -…
igorlg Sep 4, 2023
fbab0f8
chore: lint JSON files, remove unused JSON event payloads
igorlg Sep 4, 2023
0857d85
bug: fix EB catch-all rule pattern match, add naming to EB catch-all …
igorlg Sep 4, 2023
899b874
feat: Split event schemas and registry to each service
igorlg Sep 5, 2023
ce1087e
chore: Add license header to state_machine definition
igorlg Sep 5, 2023
c25e9dd
fix: moved schema for PublicationEvaluationCompleted event from unico…
igorlg Sep 5, 2023
f83e750
chore: minor changes to templates
sliedig Sep 5, 2023
c2c46e1
Merge pull request #1 from sliedig/v2
igorlg Sep 5, 2023
d80db89
fix: renamed unicorn_web namespace in unicorn_properties schema library
igorlg Sep 5, 2023
66ce914
refactor: extracted property_id parsing into its own method
igorlg Sep 5, 2023
e647a7f
refactor: removed DB update stage from approval function, and removed…
igorlg Sep 5, 2023
03bcc89
feat: Split event schemas and registry to each service
igorlg Sep 5, 2023
be057fe
chore: Add license header to state_machine definition
igorlg Sep 5, 2023
11247c3
fix: moved schema for PublicationEvaluationCompleted event from unico…
igorlg Sep 5, 2023
2c909e8
fix: renamed unicorn_web namespace in unicorn_properties schema library
igorlg Sep 5, 2023
da21f8f
refactor: extracted property_id parsing into its own method
igorlg Sep 5, 2023
e85cd82
refactor: removed DB update stage from approval function, and removed…
igorlg Sep 5, 2023
6e0dace
feat: updating Stage values to lowercase;
sliedig Sep 7, 2023
7ff4fc7
Merge branch 'v2' into v2
igorlg Sep 8, 2023
612525f
chore: Fix naming structures, move ServiceNamespace SSM param to Shar…
igorlg Sep 8, 2023
bf38a75
feat: Add shared stack to Python implementation
igorlg Sep 8, 2023
dd43f68
bug: Fix catch-all rule from each service to match events from every …
igorlg Sep 8, 2023
e7ac110
chore: remove top-level section comments from templates
igorlg Sep 8, 2023
a2f93ed
chore: update Python dependencies
igorlg Sep 8, 2023
5163fd8
chore: remove unused PyTest Coverage tool
igorlg Sep 8, 2023
c730205
chore: fix typos and misnomers in template comments
igorlg Sep 8, 2023
2b0f150
chore: add description comments to template resources
igorlg Sep 8, 2023
bdc896b
chore: add comments to resources and cfn-lint rules in template.yaml
igorlg Sep 8, 2023
788c943
chore: reordered resources in template.yaml to improve readability
igorlg Sep 8, 2023
a7799b2
chore: removed unused outputs
igorlg Sep 8, 2023
8239d5e
chore: lambda function outputs - added ARN output, renamed Name output
igorlg Sep 8, 2023
62f3684
chore: reordered and fixed StateMachine policy templates
igorlg Sep 8, 2023
dd57e7d
chore: Uncommented StateMachine event trigger, as dependency with uni…
igorlg Sep 8, 2023
c3c7452
chore: add missing Outputs for CatchAll CW Logs group
igorlg Sep 8, 2023
7897190
chore: add missing OnFailure SQS destination
igorlg Sep 8, 2023
c87589f
bug: replaces status=NEW for PENDING on test DDB items, as per new ar…
igorlg Sep 8, 2023
ff004ff
chore: remove commented-out Event payload
igorlg Sep 8, 2023
66a6cac
Merge pull request #37 from igorlg/v2
sliedig Sep 9, 2023
46f01b1
chore: minor changes to template formatting (#39)
sliedig Sep 11, 2023
28b7345
update dependencies (#41)
igorlg Sep 11, 2023
a261399
nested stacks (#42)
igorlg Sep 11, 2023
89019c5
Lint code (#43)
igorlg Sep 11, 2023
3b8e4e7
contract -> contracts
Kevinwochan Sep 12, 2023
3259fdc
contract->contracts tests
Kevinwochan Sep 12, 2023
f3fffa6
Merge pull request #44 from Kevinwochan/v2
sliedig Sep 12, 2023
779805f
test: remove partially-implemented Integration tests
igorlg Sep 13, 2023
8b39a4a
chore: Bring files inline with Dotnet, Java and Typescript
igorlg Sep 13, 2023
4da2d6e
test: fixing EventBus name in PublicationEvaluationCompleted event pa…
igorlg Sep 13, 2023
9d8f9b2
bug: wrong Event source filter parameter in unicorn_web subscriptions
igorlg Sep 13, 2023
8375a09
chore: add log statements in unicorn_web's request_approval_function …
igorlg Sep 13, 2023
50e5aab
bug: remove message attribute HttpMethod filter
igorlg Sep 13, 2023
b5fe716
bug: unicorn_web requestApproval should only filter out properties in…
igorlg Sep 13, 2023
cc70ed1
refactor: add schema package to pyproject
igorlg Sep 13, 2023
8425d64
chore: add missing global env var to unicorn_web, to bring it inline …
igorlg Sep 13, 2023
ac2c62e
bug: wrong parameter being used for unicorn_web's PublicationApproved…
igorlg Sep 13, 2023
70871b4
refactor: change CodeUri of all Lambda functions in unicorn_web to be…
igorlg Sep 13, 2023
118e480
docs: add API Gateway CW Logs group tag
igorlg Sep 13, 2023
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
.idea/*
**/.aws-sam/
.vscode/*
.vscode/settings.json
Empty file removed .vscode/settings.json
Empty file.
97 changes: 87 additions & 10 deletions unicorn_contracts/Makefile
Original file line number Diff line number Diff line change
@@ -1,34 +1,70 @@
stackName := uni-prop-local-contract
#### Global Variables
stackName := $(shell yq -oy '.default.global.parameters.stack_name' samconfig.yaml)


#### Test Variables
apiUrl = $(call cf_output,$(stackName),ApiUrl)
ddbPropertyId = $(call get_ddb_key,create_contract_valid_payload_1)


#### Build/Deploy Tasks
ci: clean build deploy

build:
sam validate --lint
cfn-lint template.yaml -a cfn_lint_serverless.rules
poetry export --without-hashes --format=requirements.txt --output=src/requirements.txt
sam build -c $(DOCKER_OPTS)

deps:
poetry install

deploy: build
sam deploy --no-confirm-changeset

sync:
sam sync --stack-name $(stackName) --watch
deploy: deps build
sam deploy

test: unit-test
#### Tests
test: unit-test integration-test

unit-test:
poetry run pytest tests/unit/

integration-test: deps
AWS_SAM_STACK_NAME=$(stackName) poetry run pytest tests/integration/
poetry run pytest tests/integration/

curl-test: clean-tests
$(call runif,CREATE CONTRACT)
$(call mcurl,POST,create_contract_valid_payload_1)

$(call runif,Query DDB)
$(call ddb_get,$(ddbPropertyId))

$(call runif,UPDATE CONTRACT)
$(call mcurl,PUT,update_existing_contract_valid_payload_1)

$(call runif,Query DDB)
$(call ddb_get,$(ddbPropertyId))

$(call runif,Delete DDB Items)
$(MAKE) clean-tests

@echo "[DONE]"


clean-tests:
$(call ddb_delete,$(ddbPropertyId)) || true


#### Utilities
sync:
sam sync --stack-name $(stackName) --watch

logs:
sam logs --stack-name $(stackName) -t
sam logs -t

clean:
find . -type d -name __pycache__ -exec rm -rf {} \; 2>/dev/null || true
find . -type f -name requirements.txt -exec rm -f {} \; 2>/dev/null || true
rm -rf .pytest_cache/ .aws-sam/ htmlcov/ .coverage || true
rm -rf .pytest_cache/ .aws-sam/ || true

delete:
sam delete --stack-name $(stackName) --no-prompts
Expand All @@ -38,3 +74,44 @@ ci_init:
poetry export --without-hashes --format=requirements.txt --output=src/requirements.txt --with dev
poetry run pip install -r src/requirements.txt
poetry install -n


#### Helper Functions
define runif
@echo
@echo "Run $(1) now?"
@read
@echo "Running $(1)"
endef

define ddb_get
@aws dynamodb get-item \
--table-name $(call cf_output,$(stackName),ContractsTableName) \
--key '$(1)' \
| jq -f tests/integration/transformations/ddb_contract.jq
endef

define ddb_delete
aws dynamodb delete-item \
--table-name $(call cf_output,$(stackName),ContractsTableName) \
--key '$(1)'
endef

define mcurl
curl -X $(1) -H "Content-type: application/json" -d @$(call payload,$(2)) $(apiUrl)contract
endef

define get_ddb_key
$(shell jq '. | {property_id:{S:.property_id}}' $(call payload,$(1)) | tr -d ' ')
endef

define payload
tests/integration/events/$(1).json
endef

define cf_output
$(shell aws cloudformation describe-stacks \
--output text \
--stack-name $(1) \
--query 'Stacks[0].Outputs[?OutputKey==`$(2)`].OutputValue')
endef
24 changes: 24 additions & 0 deletions unicorn_contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,27 @@ Here is an example of an event that is published to EventBridge:
}
}
```

### Testing the APIs

```bash
export API=`aws cloudformation describe-stacks --stack-name uni-prop-local-contract --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" --output text`

curl --location --request POST "${API}contract" \
--header 'Content-Type: application/json' \
--data-raw '{
"address": {
"country": "USA",
"city": "Anytown",
"street": "Main Street",
"number": 111
},
"seller_name": "John Doe",
"property_id": "usa/anytown/main-street/111"
}'


curl --location --request PUT "${API}contract" \
--header 'Content-Type: application/json' \
--data-raw '{"property_id": "usa/anytown/main-street/111"}' | jq
```
145 changes: 145 additions & 0 deletions unicorn_contracts/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
openapi: "3.0.1"
info:
title: "Unicorn Contracts API"
version: "1.0.0"
description: Unicorn Properties Contract Service API
paths:
/contracts:
post:
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CreateContractModel"
required: true
responses:
"200":
description: "200 response"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-request-validator: "Validate body"
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt: [UnicornContractsApiIntegrationRole, Arn]
httpMethod: "POST"
uri:
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:sqs:path/${AWS::AccountId}/${UnicornContractsIngestQueue.QueueName}"
responses:
default:
statusCode: "200"
responseTemplates:
application/json: '{"message":"OK"}'
requestParameters:
integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
requestTemplates:
application/json: "Action=SendMessage&MessageBody=$input.body&MessageAttribute.1.Name=HttpMethod&MessageAttribute.1.Value.StringValue=$context.httpMethod&MessageAttribute.1.Value.DataType=String"
passthroughBehavior: "never"
type: "aws"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
requestTemplates:
application/json: '{"statusCode": 200}'
passthroughBehavior: "when_no_match"
type: "mock"
put:
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateContractModel"
required: true
responses:
"200":
description: "200 response"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-request-validator: "Validate body"
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt: [UnicornContractsApiIntegrationRole, Arn]
httpMethod: "POST"
uri:
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:sqs:path/${AWS::AccountId}/${UnicornContractsIngestQueue.QueueName}"
responses:
default:
statusCode: "200"
responseTemplates:
application/json: '{"message":"OK"}'
requestParameters:
integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
requestTemplates:
application/json: "Action=SendMessage&MessageBody=$input.body&MessageAttribute.1.Name=HttpMethod&MessageAttribute.1.Value.StringValue=$context.httpMethod&MessageAttribute.1.Value.DataType=String"
passthroughBehavior: "never"
type: "aws"
components:
schemas:
CreateContractModel:
required:
- "property_id"
- "seller_name"
- "address"
type: "object"
properties:
property_id:
type: "string"
seller_name:
type: "string"
address:
required:
- "city"
- "country"
- "number"
- "street"
type: "object"
properties:
country:
type: "string"
city:
type: "string"
street:
type: "string"
number:
type: "integer"
UpdateContractModel:
required:
- "property_id"
type: "object"
properties:
$ref: "#/components/schemas/CreateContractModel/properties"
# property_id:
# type: "string"
Empty:
title: "Empty Schema"
type: "object"
x-amazon-apigateway-request-validators:
Validate body:
validateRequestParameters: false
validateRequestBody: true
85 changes: 85 additions & 0 deletions unicorn_contracts/integration/ContractStatusChanged.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "ContractStatusChanged"
},
"paths": {},
"components": {
"schemas": {
"AWSEvent": {
"type": "object",
"required": [
"detail-type",
"resources",
"detail",
"id",
"source",
"time",
"region",
"version",
"account"
],
"x-amazon-events-detail-type": "ContractStatusChanged",
"x-amazon-events-source": "unicorn.contracts",
"properties": {
"detail": {
"$ref": "#/components/schemas/ContractStatusChanged"
},
"account": {
"type": "string"
},
"detail-type": {
"type": "string"
},
"id": {
"type": "string"
},
"region": {
"type": "string"
},
"resources": {
"type": "array",
"items": {
"type": "object"
}
},
"source": {
"type": "string"
},
"time": {
"type": "string",
"format": "date-time"
},
"version": {
"type": "string"
}
}
},
"ContractStatusChanged": {
"type": "object",
"required": [
"contract_last_modified_on",
"contract_id",
"contract_status",
"property_id"
],
"properties": {
"contract_id": {
"type": "string"
},
"contract_last_modified_on": {
"type": "string",
"format": "date-time"
},
"contract_status": {
"type": "string"
},
"property_id": {
"type": "string"
}
}
}
}
}
}
Loading