Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 3 additions & 15 deletions unicorn_contracts/tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,6 @@ def aws_credentials():
os.environ['AWS_SESSION_TOKEN'] = 'testing'


@pytest.fixture(scope='function')
def env_vars():
os.environ['POWERTOOLS_SERVICE_NAME']='unicorn.contracts'
os.environ['SERVICE_NAMESPACE']='unicorn.contracts'
os.environ['POWERTOOLS_SERVICE_NAME']='unicorn.contracts'
os.environ['POWERTOOLS_TRACE_DISABLED']='true'
os.environ['POWERTOOLS_LOGGER_LOG_EVENT']='Info'
os.environ['POWERTOOLS_LOGGER_SAMPLE_RATE']='0.1'
os.environ['POWERTOOLS_METRICS_NAMESPACE']='unicorn.contracts'
os.environ['LOG_LEVEL']='INFO'


@pytest.fixture(scope='function')
def dynamodb(aws_credentials):
with mock_dynamodb():
Expand All @@ -51,12 +39,12 @@ def sqs(aws_credentials):
@pytest.fixture(scope='function')
def lambda_context():
context: LambdaContext = LambdaContext()
context._function_name="contractsService-CreateContractFunction-IWaQgsTEtLtX"
context._function_name="contractsService-LambdaFunction-IWaQgsTEtLtX"
context._function_version="$LATEST"
context._invoked_function_arn="arn:aws:lambda:ap-southeast-2:424490683636:function:contractsService-CreateContractFunction-IWaQgsTEtLtX"
context._invoked_function_arn="arn:aws:lambda:ap-southeast-2:424490683636:function:contractsService-LambdaFunction-IWaQgsTEtLtX"
context._memory_limit_in_mb=128
context._aws_request_id="6f970d26-71d6-4c87-a196-9375f85c7b07"
context._log_group_name="/aws/lambda/contractsService-CreateContractFunction-IWaQgsTEtLtX"
context._log_group_name="/aws/lambda/contractsService-LambdaFunction-IWaQgsTEtLtX"
context._log_stream_name="2022/07/14/[$LATEST]7c71ca59882b4c569dd007c7e41c81e8"
# context._identity=CognitoIdentity([cognito_identity_id=None,cognito_identity_pool_id=None])])
# context._client_context=None
Expand Down
23 changes: 0 additions & 23 deletions unicorn_contracts/tests/unit/event_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,3 @@ def sqs_event(messages: List[dict],
})

return SQSEvent({ "Records": records })




# {
# "Records": [
# {
# "messageAttributes": {
# "HttpMethod": {
# "stringValue": "PUT",
# "stringListValues": [],
# "binaryListValues": [],
# "dataType": "String"
# }
# },
# "md5OfMessageAttributes": "39c36267fdf9c8d354b1069e44662d24",
# "md5OfBody": "4bc398b7ae8e52d7f7eaed3cb76c12ef",
# "eventSource": "aws:sqs",
# "eventSourceARN": "arn:aws:sqs:ap-southeast-2:718758479978:uni-prop-local-contract-UnicornContractsIngestQueue-p5zisiK0Xbxn",
# "awsRegion": "ap-southeast-2"
# }
# ]
# }
11 changes: 6 additions & 5 deletions unicorn_contracts/tests/unit/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ def return_env_vars_dict(k=None):

env_dict = {
"AWS_DEFAULT_REGION": "ap-southeast-2",
"EVENT_BUS": EVENTBUS_NAME,
"DYNAMODB_TABLE": TABLE_NAME,
"EVENT_BUS": "test-eventbridge",
"LOG_LEVEL":"INFO",
"SERVICE_NAMESPACE": "unicorn.contracts",
"POWERTOOLS_LOGGER_CASE": "PascalCase",
"POWERTOOLS_SERVICE_NAME":"unicorn.contracts",
"POWERTOOLS_TRACE_DISABLED":"true",
"POWERTOOLS_LOGGER_LOG_EVENT":"true",
"POWERTOOLS_LOGGER_SAMPLE_RATE":"0.1",
"POWERTOOLS_METRICS_NAMESPACE":"unicorn.contracts",
"POWERTOOLS_SERVICE_NAME":"unicorn.contracts",
"POWERTOOLS_TRACE_DISABLED":"true",
"SERVICE_NAMESPACE": "unicorn.contracts",
"LOG_LEVEL":"INFO",
}

env_dict |= k
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_valid_create_event(dynamodb, sqs, lambda_context):
def test_valid_update_event(dynamodb, sqs, lambda_context):
payload = load_event('update_contract_valid_1')
event = sqs_event([{'body': payload, 'attributes': {'HttpMethod': 'PUT'}}])

# Loading function here so that mocking works correctly.
from contracts_service import contract_event_handler # noqa: F401
# Reload is required to prevent function setup reuse from another test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


@metrics.log_metrics(capture_cold_start_metric=True) # type: ignore
@logger.inject_lambda_context(log_event=True) # type: ignore
@logger.inject_lambda_context(log_event=True)
@tracer.capture_method
def lambda_handler(event, context):
"""Functions processes DynamoDB Stream to detect changes in the contract status
Expand Down Expand Up @@ -76,7 +76,7 @@ def lambda_handler(event, context):
return result



@tracer.capture_method
def task_successful(task_token: str, contract_status: dict):
"""Send the token for a specified contract status back to Step Functions to continue workflow execution.

Expand All @@ -89,9 +89,11 @@ def task_successful(task_token: str, contract_status: dict):
Contract Status object to return to statemachine.
"""
output = {'Payload': contract_status}
logger.info(output)
return sfn.send_task_success(taskToken=task_token, output=json.dumps(output))


@tracer.capture_method
def ddb_deserialize(dynamo_image: dict) -> dict:
"""Converts the DynamoDB stream object to json dict

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@


@metrics.log_metrics(capture_cold_start_metric=True) # type: ignore
@logger.inject_lambda_context(log_event=True) # type: ignore
@logger.inject_lambda_context(log_event=True)
@tracer.capture_method
def lambda_handler(event, context):
"""Function checks to see whether the contract status exists and waits for APPROVAL
Expand Down
98 changes: 49 additions & 49 deletions unicorn_properties/state_machine/property_approval.asl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ StartAt: VerifyContractExists

States:
VerifyContractExists:
Type: Task
Resource: arn:aws:states:::lambda:invoke
InputPath: $.detail
ResultPath: $.contract_exists_check
Parameters:
Payload:
Input.$: $
FunctionName: ${ContractExistsChecker}
Next: CheckImageIntegrity
Catch:
- ErrorEquals:
- ContractStatusNotFoundException
Next: NotFound
Comment: >-
ContractExistsChecker checks to see if a contract for a specified
property exists.
Type: Task
Resource: arn:aws:states:::lambda:invoke
InputPath: $.detail
ResultPath: $.contract_exists_check
Parameters:
Payload:
Input.$: $
FunctionName: ${ContractExistsChecker}
Next: CheckImageIntegrity
Catch:
- ErrorEquals:
- ContractStatusNotFoundException
Next: NotFound
Comment: >-
ContractExistsChecker checks to see if a contract for a specified
property exists.

NotFound:
Type: Fail

Expand All @@ -50,7 +50,7 @@ States:
unsafe content.
ItemsPath: "$.detail.images"
ResultPath: "$.imageModerations"

CheckDescriptionSentiment:
Type: Task
Parameters:
Expand All @@ -64,44 +64,44 @@ States:
Type: Task
Resource: arn:aws:states:::lambda:invoke
ResultPath: "$.validation_check"
ResultSelector :
ResultSelector:
validation_result.$: "$.Payload.validation_result"
Parameters:
Payload.$: $
FunctionName: ${ContentIntegrityValidator}
Retry:
- ErrorEquals:
- Lambda.ServiceException
- Lambda.AWSLambdaException
- Lambda.SdkClientException
IntervalSeconds: 2
MaxAttempts: 6
BackoffRate: 2
- ErrorEquals:
- Lambda.ServiceException
- Lambda.AWSLambdaException
- Lambda.SdkClientException
IntervalSeconds: 2
MaxAttempts: 6
BackoffRate: 2
Next: IsContentSafe

IsContentSafe:
Type: Choice
Choices:
- Variable: $.validation_check.validation_result
StringEquals: PASS
Next: WaitForContractApproval
- Variable: $.validation_check.validation_result
StringEquals: PASS
Next: WaitForContractApproval
Default: PublicationEvaluationCompletedDeclined

PublicationEvaluationCompletedDeclined:
Type: Task
Resource: arn:aws:states:::events:putEvents
Parameters:
Entries:
- Detail:
property_id.$: "$.detail.property_id"
evaluation_result: "DECLINED"
DetailType: PublicationEvaluationCompleted
EventBusName: ${EventBusName}
Source: ${ServiceName}
- Detail:
property_id.$: "$.detail.property_id"
evaluation_result: "DECLINED"
DetailType: PublicationEvaluationCompleted
EventBusName: ${EventBusName}
Source: ${ServiceName}
Next: Declined
Declined:
Type: Succeed

WaitForContractApproval:
Type: Task
Resource: arn:aws:states:::lambda:invoke.waitForTaskToken
Expand All @@ -113,13 +113,13 @@ States:
TaskToken.$: $$.Task.Token
FunctionName: ${WaitForContractApproval}
Retry:
- ErrorEquals:
- Lambda.ServiceException
- Lambda.AWSLambdaException
- Lambda.SdkClientException
IntervalSeconds: 2
MaxAttempts: 6
BackoffRate: 2
- ErrorEquals:
- Lambda.ServiceException
- Lambda.AWSLambdaException
- Lambda.SdkClientException
IntervalSeconds: 2
MaxAttempts: 6
BackoffRate: 2
Next: PublicationEvaluationCompletedApproved
Comment: ContractStatusChecker

Expand All @@ -128,12 +128,12 @@ States:
Resource: arn:aws:states:::events:putEvents
Parameters:
Entries:
- Detail:
property_id.$: "$.detail.property_id"
evaluation_result: "APPROVED"
DetailType: PublicationEvaluationCompleted
EventBusName: ${EventBusName}
Source: ${ServiceName}
- Detail:
property_id.$: "$.detail.property_id"
evaluation_result: "APPROVED"
DetailType: PublicationEvaluationCompleted
EventBusName: ${EventBusName}
Source: ${ServiceName}
Next: Approved
Approved:
Type: Succeed
4 changes: 1 addition & 3 deletions unicorn_shared/samconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ default:
resolve_s3: true
deploy:
parameters:
template_file: uni-prop-shared.yaml
confirm_changeset: false
fail_on_empty_changeset: false
on_failure: ROLLBACK
capabilities: CAPABILITY_IAM
parameter_overrides:
- "Stage=Local"

- "Stage=local"
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
AWSTemplateFormatVersion: "2010-09-09"
Transform:
- AWS::LanguageExtensions
- AWS::Serverless-2016-10-31
Description: >
Base infrastructure that will set up the central event bus and S3 image upload bucket.


#### PARAMETERS
Parameters:
Stage:
Type: String
Default: Local
Default: local
AllowedValues:
- Local
- Dev
- Prod
- local
- dev
- prod


#### MAPPINGS - Should be removed when values change to lower case
Mappings:
Stage:
Dev:
Value: dev
Prod:
Value: prod
Local:
Value: local


#### GLOBALS
Globals:
Function:
Timeout: 15
Expand All @@ -43,29 +31,49 @@ Globals:
service: Unicorn Base Infrastructure


#### RESOURCES
Resources:
# S3 PROPERTY IMAGES BUCKET
UnicornPropertiesImagesBucket:
Type: AWS::S3::Bucket
#### SSM PARAMETERS
# Service Namespaces
UnicornContractsNamespaceParam:
Type: AWS::SSM::Parameter
Properties:
BucketName: !Sub
- uni-prop-${st}-images-${AWS::AccountId}
- st: !FindInMap [Stage, !Ref Stage, Value]
Type: String
Name: !Sub /uni-prop/${Stage}/UnicornContractsNamespace
Value: "unicorn.contracts"
UnicornPropertiesNamespaceParam:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: !Sub /uni-prop/${Stage}/UnicornPropertiesNamespace
Value: "unicorn.properties"
UnicornWebNamespaceParam:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: !Sub /uni-prop/${Stage}/UnicornWebNamespace
Value: "unicorn.web"

# Images S3 Bucket
UnicornPropertiesImagesBucketParam:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: !Sub /UniProp/${Stage}/ImagesBucket
Name: !Sub /uni-prop/${Stage}/ImagesBucket
Value: !Ref UnicornPropertiesImagesBucket

# IMAGE UPLOAD CUSTOM RESOURCE FUNCTION

#### S3 PROPERTY IMAGES BUCKET
UnicornPropertiesImagesBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub uni-prop-${Stage}-images-${AWS::AccountId}


#### IMAGE UPLOAD CUSTOM RESOURCE FUNCTION
ImageUploadFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.lambda_handler
Runtime: python3.9
Policies:
- S3CrudPolicy:
BucketName: !Ref UnicornPropertiesImagesBucket
Expand Down