service: &service
  name: usrv-transfer
plugins:
  - serverless-webpack
  - serverless-domain-manager
  - serverless-dynamodb-autoscaling
  - serverless-prune-plugin
  - serverless-api-stage
custom:
  # Plugins Variables
  service: *service
  prefix: /${self:provider.stage}/${self:custom.service.name}
  version: v1
  resources:
    snsCharges: ${self:provider.stage}-${self:custom.service.name}-charges
    snsWebhook: ${self:provider.stage}-${self:custom.service.name}-webhook
    lambdaCallGtw: ${self:custom.service.name}-${self:provider.stage}-callGtw
    lambdaCallAgr: ${self:custom.service.name}-${self:provider.stage}-callAgr
  webpack:
    packager: "npm"
    includeModules:
      forceInclude:
        - soap
      forceExclude:
        - aws-sdk
  customDomain:
    basePath: ${ssm:${self:custom.prefix}/BASE_PATH, self:provider.stage}
    domainName: ${ssm:${self:custom.prefix}/DOMAIN, env:USRV_DOMAIN}
    stage: ${self:provider.stage}
    certificateName: "*.kushkipagos.com"
    createRoute53Record: false
  stageSettings:
    MethodSettings:
      LoggingLevel: INFO
provider:
  name: aws
  runtime: nodejs8.10
  stage: ${env:USRV_STAGE}
  timeout: 29
  environment:
    USRV_STAGE: ${self:provider.stage}
    USRV_REGION: { "Ref": "AWS::Region" }
    USRV_NAME: ${self:custom.service.name}
    USRV_COMMIT: ${env:USRV_COMMIT}
    USRV_BRANCH: ${env:USRV_BRANCH}
    ROLLBAR_TOKEN: ${ssm:${self:custom.prefix}/ROLLBAR_TOKEN}
    ######## RESOURCES ########
    DYNAMO_TRANSACTION: ${self:resources.Resources.transaction.Properties.TableName}
    DYNAMO_MERCHANT: ${self:resources.Resources.merchants.Properties.TableName}
    DYNAMO_PROCESSOR_USRV: ${ssm:${self:custom.prefix}/DYNAMO_PROCESSOR_USRV}
    DYNAMO_MERCHANT_USRV: ${ssm:${self:custom.prefix}/DYNAMO_MERCHANT_USRV}
    FIREHOSE_REDSHIFT: ${self:resources.Resources.firehoseRedshift.Properties.DeliveryStreamName}
    FIREHOSE_ELASTIC: ${self:resources.Resources.firehoseElastic.Properties.DeliveryStreamName}
    LAMBDA_GTW: ${self:custom.resources.lambdaCallGtw}
    LAMBDA_AGR: ${self:custom.resources.lambdaCallAgr}
    SNS_CHARGES:
      {
        "Fn::Join":
          [
            "",
            [
              "arn:aws:sns:",
              { "Ref": "AWS::Region" },
              ":",
              { "Ref": "AWS::AccountId" },
              ":${self:custom.resources.snsCharges}",
            ],
          ],
      }
    SNS_WEBHOOK:
      {
        "Fn::Join":
          [
            "",
            [
              "arn:aws:sns:",
              { "Ref": "AWS::Region" },
              ":",
              { "Ref": "AWS::AccountId" },
              ":${self:custom.resources.snsWebhook}",
            ],
          ],
      }
  iamRoleStatements:
    - Effect: Allow
      Action:
        - firehose:PutRecordBatch
      Resource:
        - "Fn::GetAtt":
            - firehoseElastic
            - Arn
        - "Fn::GetAtt":
            - firehoseRedshift
            - Arn
    - Effect: "Allow"
      Action:
        - dynamodb:PutItem
        - dynamodb:GetItem
      Resource:
        - "Fn::GetAtt":
            - transaction
            - Arn
        - "Fn::GetAtt":
            - merchants
            - Arn
    - Effect: "Allow"
      Action:
        - dynamodb:Query
      Resource:
        "Fn::Join":
          - ""
          - - "Fn::GetAtt":
                - transaction
                - Arn
            - /index/documentNumber
    - Effect: "Allow"
      Action:
        - dynamodb:Query
      Resource:
        "Fn::Join":
          - ""
          - - "Fn::GetAtt":
                - transaction
                - Arn
            - /index/ticketNumber
    - Effect: Allow
      Action:
        - SNS:Publish
      Resource:
        - {
            "Fn::Join":
              [
                "",
                [
                  "arn:aws:sns:",
                  { "Ref": "AWS::Region" },
                  ":",
                  { "Ref": "AWS::AccountId" },
                  ":${self:custom.resources.snsCharges}",
                ],
              ],
          }
        - {
            "Fn::Join":
              [
                "",
                [
                  "arn:aws:sns:",
                  { "Ref": "AWS::Region" },
                  ":",
                  { "Ref": "AWS::AccountId" },
                  ":${self:custom.resources.snsWebhook}",
                ],
              ],
          }
    - Effect: "Allow"
      Action:
        - ssm:GetParameter
        - ssm:GetParameters
        - ssm:GetParametersByPath
      Resource:
        - {
            "Fn::Join":
              [
                "",
                [
                  "arn:aws:ssm:",
                  { "Ref": "AWS::Region" },
                  ":",
                  { "Ref": "AWS::AccountId" },
                  ":parameter${self:custom.prefix}/*",
                ],
              ],
          }
    - Effect: Allow
      Action:
        - lambda:InvokeFunction
      Resource:
        - {
            "Fn::Join":
              [
                "",
                [
                  "arn:aws:lambda:",
                  { "Ref": "AWS::Region" },
                  ":",
                  { "Ref": "AWS::AccountId" },
                  ":function:${self:custom.resources.lambdaCallGtw}",
                ],
              ],
          }
        - {
            "Fn::Join":
              [
                "",
                [
                  "arn:aws:lambda:",
                  { "Ref": "AWS::Region" },
                  ":",
                  { "Ref": "AWS::AccountId" },
                  ":function:${self:custom.resources.lambdaCallAgr}",
                ],
              ],
          }
package:
  individually: true
  excludeDevDependencies: true
functions:
  tokens:
    handler: src/handler/TokenHandler.HANDLER
    events:
      - http:
          method: post
          path: ${self:custom.version}/tokens
          cors:
            origin: "*"
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
              - Public-Merchant-Id
            allowCredentials: false
          authorizer:
            authorizerResultTtlInSeconds: "0"
            name: publicCredential
            identitySource: method.request.header.Public-Merchant-Id
            type: request
            arn: ${ssm:${self:custom.prefix}/PUBLIC_AUTHORIZER}
  queueWebhooks:
    handler: src/handler/QueueWebhooksHandler.HANDLER
    timeout: 300
    events:
      - stream:
          type: dynamodb
          arn:
            "Fn::GetAtt":
              - transaction
              - StreamArn
  status:
    handler: src/handler/StatusHandler.HANDLER
    events:
      - http:
          method: get
          path: ${self:custom.version}/status/{token}
          authorizer:
            authorizerResultTtlInSeconds: "0"
            name: privateCredential
            identitySource: method.request.header.Private-Merchant-Id
            type: request
            arn: ${ssm:${self:custom.prefix}/PRIVATE_AUTHORIZER}
  bankList:
    handler: src/handler/BankListHandler.HANDLER
    events:
      - http:
          method: get
          path: ${self:custom.version}/bankList
          cors:
            origin: "*"
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
              - Public-Merchant-Id
            allowCredentials: false
          authorizer:
            authorizerResultTtlInSeconds: "0"
            name: publicCredential
            identitySource: method.request.header.Public-Merchant-Id
            type: request
            arn: ${ssm:${self:custom.prefix}/PUBLIC_AUTHORIZER}
  init:
    handler: src/handler/InitHandler.HANDLER
    events:
      - http:
          method: post
          path: ${self:custom.version}/init
          authorizer:
            authorizerResultTtlInSeconds: "0"
            name: privateCredential
            identitySource: method.request.header.Private-Merchant-Id
            type: request
            arn: ${ssm:${self:custom.prefix}/PRIVATE_AUTHORIZER}
  agent:
    handler: src/handler/AgentHandler.HANDLER
    events:
      - http:
          path: ${self:custom.version}/agent
          method: get
  charges:
    handler: src/handler/ChargeHandler.HANDLER
    timeout: 300
    events:
      - sns: ${self:custom.resources.snsCharges}
  webhookSns:
    handler: src/handler/WebhookSnsHandler.HANDLER
    events:
      - sns: ${self:custom.resources.snsWebhook}
  syncProcessor:
    handler: src/handler/SyncProcessorsHandler.HANDLER
    events:
      - stream: ${ssm:${self:custom.prefix}/MERCHANT_ARN}
  callGtw:
    handler: src/handler/CallHandler.HANDLER
    vpc:
      securityGroupIds:
        - ${ssm:${self:custom.prefix}/VPC_SG}
      subnetIds:
        - ${ssm:${self:custom.prefix}/VPC_SUBNET1}
        - ${ssm:${self:custom.prefix}/VPC_SUBNET2}
  callAgr:
    handler: src/handler/CallHandler.HANDLER
    vpc:
      securityGroupIds:
        - ${ssm:${self:custom.prefix}/VPC_SG}
      subnetIds:
        - ${ssm:${self:custom.prefix}/VPC_SUBNET3}
        - ${ssm:${self:custom.prefix}/VPC_SUBNET4}
resources:
  Resources:
    GatewayResponseDefault400:
      Type: "AWS::ApiGateway::GatewayResponse"
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: UNAUTHORIZED
        StatusCode: 400
        ResponseTemplates:
          "application/json": "{\n \"message\": \"ID de comercio o credencial no válido\",\n \"code\": \"T004\" \n }"
        RestApiId:
          Ref: "ApiGatewayRestApi"
    transaction:
      Type: "AWS::DynamoDB::Table"
      Properties:
        TableName: ${self:provider.stage}-${self:custom.service.name}-transactions
        AttributeDefinitions:
          - AttributeName: token
            AttributeType: S
          - AttributeName: documentNumber
            AttributeType: S
          - AttributeName: ticketNumber
            AttributeType: S
          - AttributeName: publicMerchantId
            AttributeType: S
          - AttributeName: userIp
            AttributeType: S
          - AttributeName: created
            AttributeType: N
          - AttributeName: trazabilityCode
            AttributeType: S
        KeySchema:
          - AttributeName: token
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        StreamSpecification:
          StreamViewType: NEW_AND_OLD_IMAGES
        GlobalSecondaryIndexes:
          - IndexName: documentNumber
            KeySchema:
              - AttributeName: documentNumber
                KeyType: HASH
              - AttributeName: created
                KeyType: RANGE
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
          - IndexName: ticketNumber
            KeySchema:
              - AttributeName: ticketNumber
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
          - IndexName: publicMerchantId
            KeySchema:
              - AttributeName: publicMerchantId
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
          - IndexName: userIp
            KeySchema:
              - AttributeName: userIp
                KeyType: HASH
              - AttributeName: created
                KeyType: RANGE
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 5
              WriteCapacityUnits: 5
          - IndexName: trazabilityCode
            KeySchema:
              - AttributeName: trazabilityCode
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
    merchants:
      Type: "AWS::DynamoDB::Table"
      Properties:
        TableName: ${self:provider.stage}-${self:custom.service.name}-merchants
        AttributeDefinitions:
          - AttributeName: publicMerchantId
            AttributeType: S
          - AttributeName: privateMerchantId
            AttributeType: S
        KeySchema:
          - AttributeName: publicMerchantId
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        GlobalSecondaryIndexes:
          - IndexName: privateMerchantId
            KeySchema:
              - AttributeName: privateMerchantId
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
        StreamSpecification:
          StreamViewType: NEW_AND_OLD_IMAGES
    firehoseRedshift:
      Type: "AWS::KinesisFirehose::DeliveryStream"
      Properties:
        DeliveryStreamName: ${self:provider.stage}-${self:custom.service.name}-transaction-redshift
        RedshiftDestinationConfiguration:
          ClusterJDBCURL: "jdbc:redshift://${ssm:${self:custom.prefix}/REDSHIFT_HOST}:5439/${ssm:${self:custom.prefix}/REDSHIFT_DATABASE}"
          Username: "${ssm:${self:custom.prefix}/REDSHIFT_USER}"
          Password: "${ssm:${self:custom.prefix}/REDSHIFT_PASS}"
          RoleARN: "arn:aws:iam::073501845287:role/firehose_delivery_role"
          CloudWatchLoggingOptions:
            Enabled: true
            LogGroupName: "${self:custom.prefix}/firehose/redshift"
            LogStreamName: "DeliveryStream"
          CopyCommand:
            CopyOptions: "dateformat 'auto' json 'auto'"
            DataTableName: '"${ssm:${self:custom.prefix}/REDSHIFT_STAGE}".transfer_transactions'
          S3Configuration:
            BucketARN: "arn:aws:s3:::etl-transactional"
            BufferingHints:
              IntervalInSeconds: "60"
              SizeInMBs: "100"
            CompressionFormat: "UNCOMPRESSED"
            Prefix: "${self:provider.stage}/${self:custom.service.name}/redshift/"
            RoleARN: "arn:aws:iam::073501845287:role/firehose_delivery_role"
    firehoseElastic:
      Type: "AWS::KinesisFirehose::DeliveryStream"
      Properties:
        DeliveryStreamName: ${self:provider.stage}-${self:custom.service.name}-transaction-elastic
        ElasticsearchDestinationConfiguration:
          DomainARN: "${ssm:${self:custom.prefix}/ELASTIC_ARN}"
          IndexName: "${ssm:${self:custom.prefix}/ELASTIC_STAGE}_transactions"
          TypeName: "transaction"
          CloudWatchLoggingOptions:
            Enabled: true
            LogGroupName: "${self:custom.prefix}/firehose/elastic"
            LogStreamName: "DeliveryStream"
          RetryOptions:
            DurationInSeconds: 300
          S3BackupMode: FailedDocumentsOnly
          IndexRotationPeriod: "NoRotation"
          BufferingHints:
            IntervalInSeconds: "60"
            SizeInMBs: "100"
          RoleARN: "arn:aws:iam::073501845287:role/firehose_delivery_role"
          S3Configuration:
            BucketARN: "arn:aws:s3:::etl-transactional"
            BufferingHints:
              IntervalInSeconds: "60"
              SizeInMBs: "100"
            CompressionFormat: "UNCOMPRESSED"
            Prefix: "${self:provider.stage}/${self:custom.service.name}/elastic/"
            RoleARN: "arn:aws:iam::073501845287:role/firehose_delivery_role"
