From cb5b385f822904fbdbef0a70c16f8bf94f47cf60 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sun, 12 Oct 2025 22:32:09 -0700 Subject: [PATCH 01/18] Added activemq and tabbitmq private lambda java sam project --- .../ActiveMQAndClientEC2.yaml | 853 ++++++++++++++++ .../DocumentDBAndMongoClientEC2.yaml | 946 ++++++++++++++++++ activemq-private-lambda-java-sam/README.md | 26 + .../activemq_consumer_dynamo_sam/.gitignore | 53 + .../activemq_consumer_dynamo_sam/README.md | 104 ++ .../.gitignore | 1 + .../.settings/org.eclipse.jdt.apt.core.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 9 + .../.settings/org.eclipse.m2e.core.prefs | 4 + .../activemq_event_consumer_function/pom.xml | 90 ++ .../events/activemq/DynamoDBUpdater.java | 83 ++ .../events/activemq/HandlerActiveMQ.java | 88 ++ .../samples/events/activemq/Person.java | 135 +++ .../events/activemq/DynamoDBUpdaterTest.java | 260 +++++ .../events/activemq/HandlerActiveMQTest.java | 233 +++++ .../samples/events/activemq/TestContext.java | 45 + .../samples/events/activemq/TestLogger.java | 14 + .../events/event.json | 186 ++++ .../template_original.yaml | 119 +++ .../activemq_message_sender_json/.gitignore | 1 + .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.apt.core.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 16 + .../.settings/org.eclipse.m2e.core.prefs | 4 + .../activemq_message_sender_json/Commands.txt | 5 + .../activemq_message_sender_json/README.md | 27 + .../activemq_message_sender_json/pom.xml | 136 +++ .../producer/JsonActiveMQProducer.java | 195 ++++ .../main/java/activemq/producer/Person.java | 107 ++ .../producer/SecretsManagerDecoder.java | 47 + .../src/main/java/activemq/producer/User.java | 67 ++ .../src/main/resources/us-500.csv | 500 +++++++++ .../DocumentDBAndMongoClientEC2.yaml | 946 ++++++++++++++++++ rabbitmq-private-lambda-java-sam/README.md | 2 + .../rabbitmq_consumer_dynamo_sam/.gitignore | 53 + .../rabbitmq_consumer_dynamo_sam/README.md | 104 ++ .../events/event.json | 608 +++++++++++ .../.gitignore | 1 + .../.settings/org.eclipse.jdt.apt.core.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 9 + .../.settings/org.eclipse.m2e.core.prefs | 4 + .../rabbitmq_event_consumer_function/pom.xml | 85 ++ .../events/rabbitmq/DynamoDBUpdater.java | 112 +++ .../events/rabbitmq/HandlerRabbitMQ.java | 102 ++ .../samples/events/rabbitmq/Person.java | 137 +++ .../events/rabbitmq/DynamoDBUpdaterTest.java | 689 +++++++++++++ .../events/rabbitmq/HandlerRabbitMQTest.java | 655 ++++++++++++ .../samples/events/rabbitmq/TestContext.java | 45 + .../samples/events/rabbitmq/TestLogger.java | 14 + .../template.yaml | 128 +++ .../rabbitmq_message_sender_json/.gitignore | 53 + .../rabbitmq_message_sender_json/Commands.txt | 10 + .../rabbitmq_message_sender_json/pom.xml | 131 +++ .../producer/JsonRabbitMQProducer.java | 182 ++++ .../main/java/rabbitmq/producer/Person.java | 107 ++ .../producer/SecretsManagerDecoder.java | 47 + .../src/main/java/rabbitmq/producer/User.java | 67 ++ .../src/main/resources/us-500.csv | 500 +++++++++ 58 files changed, 9157 insertions(+) create mode 100644 activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml create mode 100644 activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml create mode 100755 activemq-private-lambda-java-sam/README.md create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/.gitignore create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.gitignore create mode 100644 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs create mode 100644 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/pom.xml create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdater.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQ.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/Person.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdaterTest.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQTest.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestContext.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestLogger.java create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/events/event.json create mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/.gitignore create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.core.resources.prefs create mode 100644 activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.apt.core.prefs create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.core.prefs create mode 100644 activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.m2e.core.prefs create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/README.md create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/pom.xml create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/JsonActiveMQProducer.java create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/Person.java create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/User.java create mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/resources/us-500.csv create mode 100644 rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml create mode 100755 rabbitmq-private-lambda-java-sam/README.md create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/.gitignore create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/README.md create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/events/event.json create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.gitignore create mode 100644 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs create mode 100644 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/pom.xml create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdater.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQ.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/Person.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdaterTest.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQTest.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestContext.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestLogger.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/.gitignore create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/Commands.txt create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/pom.xml create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/JsonRabbitMQProducer.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/Person.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/SecretsManagerDecoder.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/User.java create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/resources/us-500.csv diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml new file mode 100644 index 000000000..2a41b7654 --- /dev/null +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -0,0 +1,853 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + ActiveMQEngineVersion: + Type: String + Default: 5.18.3 + Description: ActiveMQ engine version + JavaVersion: + Type: String + Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 + AllowedValues: + - java11 + - java17 + - java21 + Default: java21 + ActiveMQBrokerName: + Type: String + Default: ActiveMQJavaLambdaBroker + Description: ActiveMQ broker name for Lambda function + ActiveMQQueueName: + Type: String + Default: ActiveMQJavaLambdaQueue + Description: ActiveMQ queue name for Lambda function + ActiveMQBrokerAdminUser: + Type: String + Description: Username for the ActiveMQ Broker + Default: activemqadmin + ActiveMQBrokerPassword: + Type: String + Description: Password for the ActiveMQ Broker + Default: activemqPassword123 + NoEcho: true + ServerlessLandGithubLocation: + Type: String + Default: https://github.com/aws-samples/serverless-patterns.git + Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PublicThree: + CIDR: '10.0.2.0/24' + PrivateSubnetActiveMQOne: + CIDR: '10.0.3.0/24' + PrivateSubnetActiveMQTwo: + CIDR: '10.0.4.0/24' + PrivateSubnetActiveMQThree: + CIDR: '10.0.5.0/24' + +Resources: + # Secrets Manager Secret for ActiveMQ credentials + ActiveMQSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonActiveMQCredentials' + Description: ActiveMQ broker master user credentials + SecretString: !Sub | + { + "username": "${ActiveMQBrokerAdminUser}", + "password": "${ActiveMQBrokerPassword}" + } + + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'ActiveMQVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetTwo' + PublicSubnetThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetThree' + PrivateSubnetActiveMQOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQOne' + PrivateSubnetActiveMQTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQTwo' + PrivateSubnetActiveMQThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQThree', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQThree' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + NATEIP1: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP1.AllocationId + SubnetId: !Ref 'PublicSubnetOne' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway1' + + NATEIP2: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP2.AllocationId + SubnetId: !Ref 'PublicSubnetTwo' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway2' + + NATEIP3: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway3: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP3.AllocationId + SubnetId: !Ref 'PublicSubnetThree' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway3' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + PublicSubnetThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetThree + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute1: + Type: AWS::EC2::Route + DependsOn: NATGateway1 + Properties: + RouteTableId: !Ref 'PrivateRouteTable1' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway1' + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute2: + Type: AWS::EC2::Route + DependsOn: NATGateway2 + Properties: + RouteTableId: !Ref 'PrivateRouteTable2' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway2' + + PrivateRouteTable3: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute3: + Type: AWS::EC2::Route + DependsOn: NATGateway3 + Properties: + RouteTableId: !Ref 'PrivateRouteTable3' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway3' + + PrivateSubnetActiveMQOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnetActiveMQOne + + PrivateSubnetActiveMQTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnetActiveMQTwo + + PrivateSubnetActiveMQThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable3 + SubnetId: !Ref PrivateSubnetActiveMQThree + + ActiveMQClientInstanceSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup + GroupName: !Sub "${AWS::StackName} Security group attached to the ActiveMQ client" + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 10.0.0.0/16 + + ActiveMQSecurityGroup: + Type: AWS::EC2::SecurityGroup + DependsOn: [VPC,ActiveMQClientInstanceSecurityGroup] + Properties: + GroupDescription: ActiveMQ Security Group + GroupName: !Sub "${AWS::StackName} Security group for the ActiveMQ broker" + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 61617 + ToPort: 61617 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 8162 + ToPort: 8162 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 0 + ToPort: 65535 + CidrIp: 10.0.0.0/16 + + ActiveMQClientSelfIngressAllowRule: + Type: AWS::EC2::SecurityGroupIngress + DependsOn: ActiveMQClientInstanceSecurityGroup + Properties: + GroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + + # ActiveMQ Subnet Group + ActiveMQSubnetGroup: + Type: AWS::MQ::Configuration + Properties: + Name: !Sub "${AWS::StackName}-activemq-config" + Description: ActiveMQ configuration for the cluster + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + Data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ActiveMQ Broker + ActiveMQBroker: + Type: AWS::MQ::Broker + Properties: + BrokerName: !Ref ActiveMQBrokerName + DeploymentMode: ACTIVE_STANDBY_MULTI_AZ + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + HostInstanceType: mq.t3.micro + PubliclyAccessible: false + AutoMinorVersionUpgrade: false + Configuration: + Id: !Ref ActiveMQSubnetGroup + Revision: 1 + Users: + - Username: !Ref ActiveMQBrokerAdminUser + Password: !Ref ActiveMQBrokerPassword + ConsoleAccess: true + Groups: + - admin + SubnetIds: + - !Ref PrivateSubnetActiveMQOne + - !Ref PrivateSubnetActiveMQTwo + SecurityGroups: + - !Ref ActiveMQSecurityGroup + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-activemq-broker" + + ActiveMQClientEC2Instance: + DependsOn: ActiveMQBroker + Type: AWS::EC2::Instance + Properties: + InstanceType: m5.large + IamInstanceProfile: !Ref EC2InstanceProfile + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + SubnetId: !Ref PublicSubnetOne + SecurityGroupIds: [!GetAtt ActiveMQClientInstanceSecurityGroup.GroupId] + ImageId: !Ref LatestAmiId + Tags: + - Key: 'Name' + Value: 'ActiveMQClientInstance' + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: 50 + VolumeType: gp2 + DeleteOnTermination: true + UserData: + Fn::Base64: + !Sub + - | + #!/bin/bash + yum update -y + + # install Java + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum update -y + + # install Java + JAVA_VERSION=${java_version} + echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + if [ "$JAVA_VERSION" == "java11" ]; then + sudo yum install java-11-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java17" ]; then + sudo yum install java-17-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java21" ]; then + sudo yum install java-21-amazon-corretto-devel -y + else + sudo yum install java-21-amazon-corretto-devel -y + fi + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of Java succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install nmap-ncat -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of nmap succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install git -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of git succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum erase awscli -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum erase of awscli succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install jq -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of jq succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y docker + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of docker succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + service docker start + usermod -a -G docker ec2-user + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y maven + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of maven succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + cd /home/ec2-user + su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user + su -c "pip3 install boto3 --user" -s /bin/sh ec2-user + su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user + + # install AWS CLI 2 - access with aws2 + cd /home/ec2-user + mkdir -p awscli + cd awscli + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + # Install AWS SAM CLI + cd /home/ec2-user + mkdir -p awssam + cd awssam + wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + unzip aws-sam-cli-linux-x86_64.zip -d sam-installation + sudo ./sam-installation/install + + # Set environment variables + ACTIVEMQ_BROKER_ID=${activemq_broker_id} + ACTIVEMQ_BROKER_ENDPOINT=${activemq_broker_endpoint} + ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} + ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} + AWS_REGION=${aws_region} + ACTIVEMQ_SUBNET_ONE=${activemq_subnet_one} + ACTIVEMQ_SUBNET_TWO=${activemq_subnet_two} + ACTIVEMQ_SUBNET_THREE=${activemq_subnet_three} + ACTIVEMQ_SECURITY_GROUP=${activemq_security_group} + ACTIVEMQ_BROKER_ADMIN_USER=${activemq_broker_admin_user} + ACTIVEMQ_BROKER_PASSWORD=${activemq_broker_password} + SECURITY_GROUP=${security_group_id} + + echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_ONE=$ACTIVEMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_TWO=$ACTIVEMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_THREE=$ACTIVEMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECURITY_GROUP=$ACTIVEMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ADMIN_USER=$ACTIVEMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_PASSWORD=$ACTIVEMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + + # Clone serverless patterns + cd /home/ec2-user + SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} + git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION + cd ./serverless-patterns + git sparse-checkout set --no-cone /activemq-private-lambda-java-sam + git checkout + cd activemq-private-lambda-java-sam + sudo chown -R ec2-user . + + # Get IP CIDR range for EC2 Instance Connect + cd /home/ec2-user + mkdir -p ip_prefix + cd ip_prefix + git clone https://github.com/joetek/aws-ip-ranges-json.git + cd aws-ip-ranges-json + AWS_REGION=${aws_region} + EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') + echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile + SECURITY_GROUP=${security_group_id} + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP + + - activemq_broker_id: !Ref ActiveMQBroker + activemq_broker_endpoint: !Sub + - "ssl://${endpoint}:61617" + - endpoint: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + activemq_queue_name: !Ref ActiveMQQueueName + activemq_secret_arn: !Ref ActiveMQSecret + serverless_land_github_location: !Ref ServerlessLandGithubLocation + aws_region: !Ref 'AWS::Region' + java_version: !Ref JavaVersion + security_group_id : !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + activemq_subnet_one: !Ref PrivateSubnetActiveMQOne + activemq_subnet_two: !Ref PrivateSubnetActiveMQTwo + activemq_subnet_three: !Ref PrivateSubnetActiveMQThree + activemq_security_group: !GetAtt ActiveMQSecurityGroup.GroupId + activemq_broker_admin_user: !Ref ActiveMQBrokerAdminUser + activemq_broker_password: !Ref ActiveMQBrokerPassword + + EC2InstanceEndpoint: + Type: AWS::EC2::InstanceConnectEndpoint + Properties: + PreserveClientIp: true + SecurityGroupIds: + - !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + SubnetId: !Ref PublicSubnetOne + + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Action: 'sts:AssumeRole' + Path: "/" + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonMQFullAccess + - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore + - arn:aws:iam::aws:policy/AmazonS3FullAccess + - arn:aws:iam::aws:policy/IAMFullAccess + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 + Policies: + - PolicyName: ActiveMQAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ActiveMQFullAccess", + "Effect": "Allow", + "Action": [ + "mq:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecretsManagerAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${ActiveMQSecret}" + } + ] + }' + - PolicyName: CloudformationDeploy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecurityGroupsPolicy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupEgress", + "ec2:ModifySecurityGroupRules", + "ec2:UpdateSecurityGroupRuleDescriptionsIngress", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:ModifySecurityGroupRules" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" + ] + } + ] + }' + + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Join + - '-' + - - 'EC2ActiveMQProfile' + - !Ref 'AWS::StackName' + Roles: + - !Ref EC2Role + +Outputs: + VPCId: + Description: The ID of the VPC created + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PublicSubnetOne: + Description: The name of the public subnet created + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Sub "${AWS::StackName}-PublicSubnetOne" + PrivateSubnetActiveMQOne: + Description: The ID of private subnet one created + Value: !Ref 'PrivateSubnetActiveMQOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQOne" + PrivateSubnetActiveMQTwo: + Description: The ID of private subnet two created + Value: !Ref 'PrivateSubnetActiveMQTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQTwo" + PrivateSubnetActiveMQThree: + Description: The ID of private subnet three created + Value: !Ref 'PrivateSubnetActiveMQThree' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQThree" + VPCStackName: + Description: The name of the VPC Stack + Value: !Ref 'AWS::StackName' + Export: + Name: !Sub "${AWS::StackName}-VPCStackName" + ActiveMQBrokerEndpoint: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Sub + - "ssl://${endpoint}:61617" + - endpoint: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint" + ActiveMQBrokerConsoleURL: + Description: ActiveMQ Broker Web Console URL + Value: !Sub + - "https://${endpoint}" + - endpoint: !Select [0, !GetAtt ActiveMQBroker.IpAddresses] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerConsoleURL" + ActiveMQSecretArn: + Description: ARN of the ActiveMQ credentials secret + Value: !Ref ActiveMQSecret + Export: + Name: !Sub "${AWS::StackName}-ActiveMQSecretArn" + SecurityGroupId: + Description: ID of security group for ActiveMQ clients + Value: !GetAtt ActiveMQSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" + EC2InstanceEndpointID: + Description: The ID of the EC2 Instance Endpoint + Value: !Ref EC2InstanceEndpoint + ActiveMQBrokerName: + Description: The Broker name to use for the Java Lambda Function + Value: !Ref ActiveMQBrokerName + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerName" + ActiveMQQueueName: + Description: The Queue name to use for the Java Lambda Function + Value: !Ref ActiveMQQueueName + Export: + Name: !Sub "${AWS::StackName}-ActiveMQQueueName" diff --git a/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml b/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml new file mode 100644 index 000000000..eba751ca8 --- /dev/null +++ b/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml @@ -0,0 +1,946 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + DocumentDBEngineVersion: + Type: String + Default: 5.0.0 + Description: DocumentDB engine version + JavaVersion: + Type: String + Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 + AllowedValues: + - java11 + - java17 + - java21 + Default: java21 + DocumentDBDatabaseName: + Type: String + Default: DocumentDBJavaLambdaDB + Description: DocumentDB database name for Lambda function + DocumentDBCollectionName: + Type: String + Default: DocumentDBJavaLambdaCollection + Description: DocumentDB collection name for Lambda function + DocumentDBClusterAdminUser: + Type: String + Description: Password for the DocumentDB Cluster + Default: docdbadmin + DocumentDBClusterPassword: + Type: String + Description: Password for the DocumentDB Cluster + Default: docdbPassword123 + NoEcho: true + DocumentDBTrustStorePassword: + Type: String + Description: Password for the DocumentDB Client TLS Truststore Password + Default: docdbTrustPass123 + NoEcho: true + ServerlessLandGithubLocation: + Type: String + Default: https://github.com/aws-samples/serverless-patterns.git + Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PublicThree: + CIDR: '10.0.2.0/24' + PrivateSubnetDocDBOne: + CIDR: '10.0.3.0/24' + PrivateSubnetDocDBTwo: + CIDR: '10.0.4.0/24' + PrivateSubnetDocDBThree: + CIDR: '10.0.5.0/24' + +Resources: + # Secrets Manager Secret for DocumentDB credentials + DocumentDBSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonDocumentDBCredentials' + Description: DocumentDB cluster master user credentials + SecretString: !Sub | + { + "username": "${DocumentDBClusterAdminUser}", + "password": "${DocumentDBClusterPassword}" + } + + DocumentDBTrustStoreSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonDocumentDBTruststore' + Description: DocumentDB secret for truststore for SSL client to connect + SecretString: !Sub | + { + "truststore": "/home/ec2-user/mongotruststore/rds-truststore.jks", + "truststorepassword": "${DocumentDBTrustStorePassword}" + } + + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'DocumentDBVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetTwo' + PublicSubnetThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetThree' + PrivateSubnetDocDBOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBOne' + PrivateSubnetDocDBTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBTwo' + PrivateSubnetDocDBThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBThree', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBThree' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + NATEIP1: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP1.AllocationId + SubnetId: !Ref 'PublicSubnetOne' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway1' + + NATEIP2: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP2.AllocationId + SubnetId: !Ref 'PublicSubnetTwo' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway2' + + NATEIP3: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway3: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP3.AllocationId + SubnetId: !Ref 'PublicSubnetThree' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway3' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + PublicSubnetThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetThree + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute1: + Type: AWS::EC2::Route + DependsOn: NATGateway1 + Properties: + RouteTableId: !Ref 'PrivateRouteTable1' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway1' + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute2: + Type: AWS::EC2::Route + DependsOn: NATGateway2 + Properties: + RouteTableId: !Ref 'PrivateRouteTable2' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway2' + + PrivateRouteTable3: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute3: + Type: AWS::EC2::Route + DependsOn: NATGateway3 + Properties: + RouteTableId: !Ref 'PrivateRouteTable3' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway3' + + PrivateSubnetDocDBOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnetDocDBOne + + PrivateSubnetDocDBTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnetDocDBTwo + + PrivateSubnetDocDBThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable3 + SubnetId: !Ref PrivateSubnetDocDBThree + + DocumentDBClientInstanceSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup + GroupName: !Sub "${AWS::StackName} Security group attached to the DocumentDB client" + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 10.0.0.0/16 + + DocumentDBSecurityGroup: + Type: AWS::EC2::SecurityGroup + DependsOn: [VPC,DocumentDBClientInstanceSecurityGroup] + Properties: + GroupDescription: DocumentDB Security Group + GroupName: !Sub "${AWS::StackName} Security group for the DocumentDB cluster" + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 27017 + ToPort: 27017 + SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 0 + ToPort: 65535 + CidrIp: 10.0.0.0/16 + + DocumentDBClientSelfIngressAllowRule: + Type: AWS::EC2::SecurityGroupIngress + DependsOn: DocumentDBClientInstanceSecurityGroup + Properties: + GroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + + DocumentDBClientEC2Instance: + DependsOn: DocumentDBCluster + Type: AWS::EC2::Instance + Properties: + InstanceType: m5.large + IamInstanceProfile: !Ref EC2InstanceProfile + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + SubnetId: !Ref PublicSubnetOne + SecurityGroupIds: [!GetAtt DocumentDBClientInstanceSecurityGroup.GroupId] + ImageId: !Ref LatestAmiId + Tags: + - Key: 'Name' + Value: 'DocumentDBClientInstance' + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: 50 + VolumeType: gp2 + DeleteOnTermination: true + UserData: + Fn::Base64: + !Sub + - | + #!/bin/bash + yum update -y + + # install Java + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum update -y + # yum install java-openjdk11-devel -y + + # install Java + JAVA_VERSION=${java_version} + echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + if [ "$JAVA_VERSION" == "java11" ]; then + sudo yum install java-11-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java17" ]; then + sudo yum install java-17-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java21" ]; then + sudo yum install java-21-amazon-corretto-devel -y + else + sudo yum install java-21-amazon-corretto-devel -y + fi + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of Java succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install nmap-ncat -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of nmap succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install git -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of git succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum erase awscli -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum erase of awscli succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install jq -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of jq succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y docker + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of docker succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + service docker start + usermod -a -G docker ec2-user + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y maven + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of maven succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + cd /home/ec2-user + su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user + su -c "pip3 install boto3 --user" -s /bin/sh ec2-user + su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user + + # install AWS CLI 2 - access with aws2 + cd /home/ec2-user + mkdir -p awscli + cd awscli + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + + # Install MongoDB shell + cd /home/ec2-user + wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-amazon2-x86_64-100.9.4.tgz + tar -zxvf mongodb-database-tools-amazon2-x86_64-100.9.4.tgz + sudo cp mongodb-database-tools-amazon2-x86_64-100.9.4/bin/* /usr/local/bin/ + + + # Install AWS SAM CLI + cd /home/ec2-user + mkdir -p awssam + cd awssam + wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + unzip aws-sam-cli-linux-x86_64.zip -d sam-installation + sudo ./sam-installation/install + + # Set environment variables + DOCDB_CLUSTER_ENDPOINT=${docdb_cluster_endpoint} + DOCDB_CLUSTER_RESOURCE=${docdb_cluster_resource} + DOCDB_CLUSTER_IDENTIFIER=${docdb_cluster_identifier} + DOCDB_DATABASE=${docdb_database} + DOCDB_COLLECTION=${docdb_collection} + DOCDB_SECRET_ARN=${docdb_secret_arn} + AWS_REGION=${aws_region} + DOCDB_SUBNET_ONE=${docdb_subnet_one} + DOCDB_SUBNET_TWO=${docdb_subnet_two} + DOCDB_SUBNET_THREE=${docdb_subnet_three} + DOCDB_SECURITY_GROUP=${docdb_security_group} + DOCDB_CLUSTER_ADMIN_USER=${docdb_cluster_admin_user} + DOCDB_CLUSTER_PASSWORD=${docdb_cluster_password} + DOCDB_TRUST_STORE_PASSWORD=${docdb_trust_store_password} + SECURITY_GROUP=${security_group_id} + + + echo "export DOCDB_CLUSTER_ENDPOINT=$DOCDB_CLUSTER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_RESOURCE=$DOCDB_CLUSTER_RESOURCE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_IDENTIFIER=$DOCDB_CLUSTER_IDENTIFIER" >> /home/ec2-user/.bash_profile + echo "export DOCDB_DATABASE=$DOCDB_DATABASE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_COLLECTION=$DOCDB_COLLECTION" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SECRET_ARN=$DOCDB_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_ONE=$DOCDB_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_TWO=$DOCDB_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_THREE=$DOCDB_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SECURITY_GROUP=$DOCDB_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_ADMIN_USER=$DOCDB_CLUSTER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_PASSWORD=$DOCDB_CLUSTER_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export DOCDB_TRUST_STORE_PASSWORD=$DOCDB_TRUST_STORE_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + + + # Clone serverless patterns + cd /home/ec2-user + SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} + git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION + cd ./serverless-patterns + git sparse-checkout set --no-cone /documentdb-lambda-java-sam + git checkout + cd documentdb-lambda-java-sam + sudo chown -R ec2-user . + + #Install MongoShell + sudo cp ./mongodb-org-8.0.repo /etc/yum.repos.d + cd /home/ec2-user + mkdir mongoshell + cd mongoshell + sudo yum install -y mongodb-mongosh + + #Create Java Keystore to connect to DocumentDB + cd /home/ec2-user + mkdir mongotruststore + cd /home/ec2-user/mongotruststore + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/java_keystore_script.sh . + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/TRUSTSTORE_PASSWORD/$DOCDB_TRUST_STORE_PASSWORD/g" java_keystore_script.sh + chmod +x java_keystore_script.sh + sh ./java_keystore_script.sh + + #Create DocumentDB database and collection + cd /home/ec2-user/mongoshell + wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/docdb_db_collection.sh . + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/mongodbcolcreate.js . + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/connect_to_mongo_shell.sh . + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" docdb_db_collection.sh + sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" docdb_db_collection.sh + sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" docdb_db_collection.sh + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" docdb_db_collection.sh + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" docdb_db_collection.sh + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" mongodbcolcreate.js + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" mongodbcolcreate.js + sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" connect_to_mongo_shell.sh + sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" connect_to_mongo_shell.sh + sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" connect_to_mongo_shell.sh + chmod +x docdb_db_collection.sh + chmod +x connect_to_mongo_shell.sh + sh ./docdb_db_collection.sh + + #Substitute SAM template variables + cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam + cd documentdb_streams_consumer_dynamo_sam + cp template_original.yaml template.yaml + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/DOCDB_CLUSTER_IDENTIFIER/$DOCDB_CLUSTER_IDENTIFIER/g" template.yaml + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" template.yaml + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" template.yaml + sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml + sed -i "s/DOCDB_SECRET_ARN/$DOCDB_SECRET_ARN/g" template.yaml + sed -i "s/DOCDB_SUBNET_ONE/$DOCDB_SUBNET_ONE/g" template.yaml + sed -i "s/DOCDB_SUBNET_TWO/$DOCDB_SUBNET_TWO/g" template.yaml + sed -i "s/DOCDB_SUBNET_THREE/$DOCDB_SUBNET_THREE/g" template.yaml + sed -i "s/DOCDB_SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + + #Adding DocumentDB variables to DocumentDB secret as CloudFormation cannot create a secret of type DocumentDB like you manually can + aws secretsmanager put-secret-value --secret-id AmazonDocumentDBCredentials --secret-string "{\"host\":\"$DOCDB_CLUSTER_ENDPOINT\",\"port\":\"27017\",\"username\":\"$DOCDB_CLUSTER_ADMIN_USER\",\"password\":\"$DOCDB_CLUSTER_PASSWORD\",\"engine\":\"mongo\",\"ssl\":\"true\",\"dbClusterIdentifier\":\"$DOCDB_CLUSTER_IDENTIFIER\"}" + + #Compiling Sender Program and Updating Command File with DocumentDB Database and Collection names + cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/documentdb_streams_message_sender_json + sudo chown -R ec2-user . + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" commands.sh + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" commands.sh + mvn clean install + + # Get IP CIDR range for EC2 Instance Connect + cd /home/ec2-user + mkdir -p ip_prefix + cd ip_prefix + git clone https://github.com/joetek/aws-ip-ranges-json.git + cd aws-ip-ranges-json + AWS_REGION=${aws_region} + EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') + echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile + SECURITY_GROUP=${security_group_id} + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP + + - docdb_cluster_endpoint: !GetAtt DocumentDBCluster.Endpoint + docdb_cluster_resource: !GetAtt DocumentDBCluster.ClusterResourceId + docdb_cluster_identifier: !Ref DocumentDBCluster + docdb_database: !Ref DocumentDBDatabaseName + docdb_collection: !Ref DocumentDBCollectionName + docdb_secret_arn: !Ref DocumentDBSecret + serverless_land_github_location: !Ref ServerlessLandGithubLocation + aws_region: !Ref 'AWS::Region' + java_version: !Ref JavaVersion + security_group_id : !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + docdb_subnet_one: !Ref PrivateSubnetDocDBOne + docdb_subnet_two: !Ref PrivateSubnetDocDBTwo + docdb_subnet_three: !Ref PrivateSubnetDocDBThree + docdb_security_group: !GetAtt DocumentDBSecurityGroup.GroupId + docdb_cluster_admin_user: !Ref DocumentDBClusterAdminUser + docdb_cluster_password: !Ref DocumentDBClusterPassword + docdb_trust_store_password: !Ref DocumentDBTrustStorePassword + + + EC2InstanceEndpoint: + Type: AWS::EC2::InstanceConnectEndpoint + Properties: + PreserveClientIp: true + SecurityGroupIds: + - !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + SubnetId: !Ref PublicSubnetOne + + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Action: 'sts:AssumeRole' + Path: "/" + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonDocDBFullAccess + - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore + - arn:aws:iam::aws:policy/AmazonS3FullAccess + - arn:aws:iam::aws:policy/IAMFullAccess + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 + Policies: + - PolicyName: DocumentDBAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "DocumentDBFullAccess", + "Effect": "Allow", + "Action": [ + "docdb:*", + "docdb-elastic:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecretsManagerAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${DocumentDBSecret}" + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${DocumentDBTrustStoreSecret}" + } + ] + }' + - PolicyName: CloudformationDeploy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecurityGroupsPolicy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupEgress", + "ec2:ModifySecurityGroupRules", + "ec2:UpdateSecurityGroupRuleDescriptionsIngress", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:ModifySecurityGroupRules" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" + ] + } + ] + }' + + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Join + - '-' + - - 'EC2DocumentDBProfile' + - !Ref 'AWS::StackName' + Roles: + - !Ref EC2Role + + + # DocumentDB Subnet Group + DocumentDBSubnetGroup: + Type: AWS::DocDB::DBSubnetGroup + Properties: + DBSubnetGroupDescription: Subnet group for DocumentDB cluster + SubnetIds: + - !Ref PrivateSubnetDocDBOne + - !Ref PrivateSubnetDocDBTwo + - !Ref PrivateSubnetDocDBThree + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-subnet-group" + + # DocumentDB Instance-Based Cluster + DocumentDBCluster: + Type: AWS::DocDB::DBCluster + Properties: + DBClusterIdentifier: !Sub "${AWS::StackName}-docdb-cluster" + MasterUsername: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:username}}" + MasterUserPassword: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:password}}" + EngineVersion: !Ref DocumentDBEngineVersion + DBSubnetGroupName: !Ref DocumentDBSubnetGroup + VpcSecurityGroupIds: + - !Ref DocumentDBSecurityGroup + BackupRetentionPeriod: 7 + PreferredBackupWindow: "07:00-09:00" + PreferredMaintenanceWindow: "sun:09:00-sun:11:00" + StorageEncrypted: true + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-cluster" + + DocumentDBInstance1: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-1" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-1" + + DocumentDBInstance2: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-2" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-2" + + DocumentDBInstance3: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-3" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-31" + +Outputs: + VPCId: + Description: The ID of the VPC created + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PublicSubnetOne: + Description: The name of the public subnet created + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Sub "${AWS::StackName}-PublicSubnetOne" + PrivateSubnetDocDBOne: + Description: The ID of private subnet one created + Value: !Ref 'PrivateSubnetDocDBOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBOne" + PrivateSubnetDocDBTwo: + Description: The ID of private subnet two created + Value: !Ref 'PrivateSubnetDocDBTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBTwo" + PrivateSubnetDocDBThree: + Description: The ID of private subnet three created + Value: !Ref 'PrivateSubnetDocDBThree' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBThree" + VPCStackName: + Description: The name of the VPC Stack + Value: !Ref 'AWS::StackName' + Export: + Name: !Sub "${AWS::StackName}-VPCStackName" + DocumentDBClusterEndpoint: + Description: DocumentDB Instance-Based Cluster Endpoint + Value: !GetAtt DocumentDBCluster.Endpoint + Export: + Name: !Sub "${AWS::StackName}-DocumentDBClusterEndpoint" + DocumentDBSecretArn: + Description: ARN of the DocumentDB credentials secret + Value: !Ref DocumentDBSecret + Export: + Name: !Sub "${AWS::StackName}-DocumentDBSecretArn" + SecurityGroupId: + Description: ID of security group for DocumentDB clients + Value: !GetAtt DocumentDBSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" + EC2InstanceEndpointID: + Description: The ID of the EC2 Instance Endpoint + Value: !Ref EC2InstanceEndpoint + DocumentDBDatabaseName: + Description: The Database name to use for the Java Lambda Function + Value: !Ref DocumentDBDatabaseName + Export: + Name: !Sub "${AWS::StackName}-DocumentDBDatabaseName" + DocumentDBCollectionName: + Description: The Collection name to use for the Java Lambda Function + Value: !Ref DocumentDBCollectionName + Export: + Name: !Sub "${AWS::StackName}-DocumentDBCollectionName" diff --git a/activemq-private-lambda-java-sam/README.md b/activemq-private-lambda-java-sam/README.md new file mode 100755 index 000000000..30114baba --- /dev/null +++ b/activemq-private-lambda-java-sam/README.md @@ -0,0 +1,26 @@ +# javaActiveMQLambdaDynamoDB +Java samples for ActiveMQ --> Lambda --> DynamoDB + +This repository has code samples for implementing a Lambda function in Java that listens on an Amazon ActiveMQ queue as its event source and upon receipt of messages from the Amazon ActiveMQ queue, the code in the lambda function parses the contents of the message (both metadata as well as payload data) and outputs the contents into an Amazon DynamoDB table + +Each example has two Java Maven projects - a Sender Project and a Lambda Receiver Project + +The sender project has instructions on how to generate messages on the Amazon ActiveMQ queue such that those messages can then be received by the corresponding lambda receiver + +Currently, the following samples exist in this repository + +1) JSONMessage - In this example, the sender program generates Amazon ActiveMQ messages with a JSON payload + +More examples will be added in the future + +In order to run these examples, create the following in an AWS account + +1) A VPC with 3 public and 3 private subnets and an internet gateway and 3 NAT gateways for each of the three private subnets - For an example of a Cloudformation template to create a VPC, refer to this document - https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html + +2) Create an AWS Cloud9 environment and use one of the public subnets created in the VPC above for creating the Cloud9 environment - For an example of a Cloudformation template to create a Cloud9 environment, refer to the document - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloud9-environmentec2.html + +3) Create a Security Group and assign it to the EC2 instance of the Cloud9 environment + +4) Create an IAM role and attach it to the EC2 instance of the Cloud9 environment + +5) Under each sample, refer to the README files inside the sender and the receiver folders - For example under the JSONMessage folder, refer to the README files inside the sub-folders activemq_message_sender_json (sender) and activemq_consumer_dynamo_sam (receiver) for instructions \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/.gitignore b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/.gitignore new file mode 100755 index 000000000..73a5e7b94 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/.gitignore @@ -0,0 +1,53 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +node_modules +npm-debug.log +package-lock.json +package +*out.yml +out.json +bucket-name.txt +target +build +.gradle +*.zip +bin +obj +Gemfile.lock +lib +__pycache__ +*.pyc +.classpath +.factorypath +.project +.settings/* +.aws +.sam +.aws-sam +samconfig.toml +__init__.py +.DS_Store +.project \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md new file mode 100755 index 000000000..4d4d15497 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md @@ -0,0 +1,104 @@ +# activemq-consumer-dynamo-sam + +This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. + +- activemq_event_consumer_function/src/main/java - Code for the application's Lambda function. +- events - Invocation events that you can use to invoke the function. +- activemq_event_consumer_function/src/test/java - Unit tests for the application code. +- template.yaml - A template that defines the application's AWS resources. + +The application uses several AWS resources, including a Lambda function, an ActiveMQ event source and a DynamoDB table to which the lambda function will write. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. + + +## Use the SAM CLI to build and test locally + +Build your application with the `sam build` command. + +```bash +sam build +``` + +The SAM CLI installs dependencies defined in `activemq_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. + +Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. + +Run functions locally and invoke them with the `sam local invoke` command. + +```bash +sam local invoke --event events/event.json +``` + +## Deploy the sample application + +The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. + +To use the SAM CLI, you need the following tools. + +* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) +* Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) + +To build and deploy your application for the first time, run the following in your shell: + +```bash +sam build +sam deploy --guided +``` + +The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Parameter ActiveMQBrokerName**: The name of the ActiveMQ Broker +* **Parameter ActiveMQBrokerUniqueString**: The unique string of the ActiveMQ Broker +* **Parameter ActiveMQQueue**: The name of the ActiveMQ Queue +* **Parameter SecretsManagerSecretForMQName**: The name of the Secrets Manager secret that has the ActiveMQ broker Username and Password +* **Parameter SecretsManagerSecretForMQUniqueString**: The unique string of the Secrets Manager secret that has the ActiveMQ broker Username and Password +* **Parameter Subnet1**: The name of the first subnet where the ActiveMQ broker has been configured +* **Parameter Subnet2**: The name of the second subnet where the ActiveMQ broker has been configured +* **Parameter SecurityGroup**: The name of the security group where the ActiveMQ broker has been configured +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails +* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. +* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally +* **SAM configuration environment [default]**: Environment for storing deployment information locally + +You should get a message "Successfully created/updated stack - in " if all goes well + + +## Test the sample application + +Once the lambda function is deployed, send some ActiveMQ messages on the queue that the lambda function is listening on. + +Use the project ../activemq_message_sender_json. + +Look at the Readme of that project to determine how to build that project and run the command that will send ActiveMQ messages with a Json payload to the lambda function built using this project. The lambda function will receive the ActiveMQ messages with a JSON payload and input fields from the ActiveMQ message into a DynamoDB table. + +The value field of each SQS message that will be sent out will be a Json element of the format + +"person": { + "firstname": "Myra", + "lastname": "Munns", + "company": "Anker Law Office", + "street": "461 Prospect Pl #316", + "city": "Euless", + "county": "Tarrant", + "state": "TX", + "zip": "76040", + "homePhone": "817-914-7518", + "cellPhone": "817-451-3518", + "email": "mmunns@cox.net", + "website": "http://www.ankerlawoffice.com" +} + +Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) + +Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. + +The lambda code parses the ActiveMQ messages and outputs the fields in the ActiveMQ messages to Cloudwatch logs + +A single lambda function receives a batch of messages. + +The code in this example prints out the fields in the ActiveMQ message and logs them in Cloudwatch logs. + +Apart from outputting to Cloudwatch logs, the lambda function also inputs fields from the ActiveMQ message (both message metadata fields as well as payload fields from the JSON payload) into a DynamoDB table created by the SAM template. You can log into the AWS console and look at the DynamoDB table and run a scan to see data getting input from the ActiveMQ message into the DynamoDB table diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.gitignore b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.gitignore new file mode 100755 index 000000000..b83d22266 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 000000000..d4313d4b2 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 000000000..46235dc07 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/pom.xml b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/pom.xml new file mode 100755 index 000000000..841867816 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/pom.xml @@ -0,0 +1,90 @@ + + 4.0.0 + com.amazonaws.services.lambda.samples.events.activemq + ActiveMQConsumer + 1.0 + jar + A sample Lambda ActiveMQ consumer + + 11 + 11 + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.11.0 + + + + com.amazonaws + aws-java-sdk-dynamodb + 1.12.445 + + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + org.mockito + mockito-core + 3.7.7 + test + + + org.mockito + mockito-junit-jupiter + 3.8.0 + test + + + + + com.fasterxml.jackson.core + jackson-core + 2.15.1 + + + org.apache.activemq + activemq-client + 5.15.8 + + + org.apache.activemq + activemq-pool + 5.15.8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + package + + shade + + + + + + + diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdater.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdater.java new file mode 100755 index 000000000..9ed434f4c --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdater.java @@ -0,0 +1,83 @@ +package com.amazonaws.services.lambda.samples.events.activemq; + +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; +import com.amazonaws.services.dynamodbv2.document.DynamoDB; +import com.amazonaws.services.dynamodbv2.document.Item; +import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.dynamodbv2.document.Table; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent; + +public class DynamoDBUpdater { + + String dynamoDBTableName; + AmazonDynamoDB client; + DynamoDB dynamoDB; + Table dynamoTable; + + + public DynamoDBUpdater(String dynamoDBTableName) { + super(); + if (null == dynamoDBTableName) { + this.dynamoDBTableName = "ACTIVEMQ_LAMBDA_DYNAMO_TABLE"; + } else { + this.dynamoDBTableName = dynamoDBTableName; + } + String AWS_SAM_LOCAL = System.getenv("AWS_SAM_LOCAL"); + if (null == AWS_SAM_LOCAL) { + this.client = AmazonDynamoDBClientBuilder.standard().build(); + } else { + this.client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(new EndpointConfiguration("http://127.0.0.1:8000", "")).build(); + this.dynamoDBTableName = "ACTIVEMQ_LAMBDA_DYNAMO_TABLE"; + } + //this.client = AmazonDynamoDBClientBuilder.standard().build(); + this.dynamoDB = new DynamoDB(client); + this.dynamoTable = dynamoDB.getTable(this.dynamoDBTableName); + } + + public PutItemOutcome insertIntoDynamoDB(ActiveMQEvent.ActiveMQMessage msg, Person thisPerson, LambdaLogger logger, long receiveTime, String eventSource, String eventSourceARN) { + logger.log("Now inserting a row in DynamoDB for messageID = " + msg.getMessageID()); + Item item = new Item(); + item.withPrimaryKey("MessageID", msg.getMessageID()); + item.withString("EventSource", eventSource); + item.withString("EventSourceARN", eventSourceARN); + item.withString("Firstname", thisPerson.getFirstname()); + item.withString("Lastname", thisPerson.getLastname()); + item.withString("Company", thisPerson.getCompany()); + item.withString("Street", thisPerson.getStreet()); + item.withString("City", thisPerson.getCity()); + item.withString("County", thisPerson.getCounty()); + item.withString("State", thisPerson.getState()); + item.withString("Zip", thisPerson.getZip()); + item.withString("Cellphone", thisPerson.getCellPhone()); + item.withString("Homephone", thisPerson.getHomePhone()); + item.withString("Email", thisPerson.getEmail()); + item.withString("Website", thisPerson.getWebsite()); + item.withString("CorrelationID", msg.getCorrelationID()); + item.withString("MessageType", msg.getMessageType()); + if (null == msg.getReplyTo()) { + item.withNull("ReplyTo"); + } else { + item.withString("ReplyTo", msg.getReplyTo()); + } + if (null == msg.getType()) { + item.withNull("Type"); + } else { + item.withString("Type", msg.getType()); + } + item.withLong("BrokerInTime", msg.getBrokerInTime()); + item.withLong("BrokerOutTime", msg.getBrokerOutTime()); + item.withInt("DeliveryMode", msg.getDeliveryMode()); + item.withLong("Expiration", msg.getExpiration()); + item.withInt("Priority", msg.getPriority()); + item.withLong("TimeStamp", msg.getTimestamp()); + item.withString("Queue", msg.getDestination().getPhysicalName()); + item.withBoolean("WhetherRedelivered", msg.getRedelivered()); + item.withLong("ReceiveTime", receiveTime); + logger.log("Now done inserting a row in DynamoDB for messageID = " + msg.getMessageID()); + return dynamoTable.putItem(item); + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQ.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQ.java new file mode 100755 index 000000000..fdedd6a33 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQ.java @@ -0,0 +1,88 @@ +//Lambda Runtime delivers a batch of messages to the lambda function +//Each batch of messages has two fields EventSource and EventSourceARN +//Each batch of messages also has a field called Records +//The Records is a map with multiple keys and values +//Each key is a combination of the Topic Name and the Partition Number +//One batch of messages can contain messages from multiple partitions + +/* +To simplify representing a batch of Kafka messages as a list of messages +We have created a Java class called KafkaMessage under the models package +Here we are mapping the structure of an incoming Kafka event to a list of +objects of the KafkaMessage class + */ + +package com.amazonaws.services.lambda.samples.events.activemq; + +import java.util.Base64; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +// Handler value: example.HandlerSQS +public class HandlerActiveMQ implements RequestHandler{ + String dynamoDBTableName = System.getenv("DYNAMO_DB_TABLE"); + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater(dynamoDBTableName); + boolean addToDynamoDB; + ObjectMapper objectMapper = new ObjectMapper(); + @Override + public String handleRequest(ActiveMQEvent event, Context context) + { + LambdaLogger logger = context.getLogger(); + logger.log("Begin Event *************"); + try { + logger.log(objectMapper.writeValueAsString(event)); + } catch (JsonProcessingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + logger.log("End Event ***************"); + for(ActiveMQEvent.ActiveMQMessage msg : event.getMessages()){ + try { + addToDynamoDB = true; + long currentTime = System.currentTimeMillis(); + logger.log("Begin Message *************"); + logger.log(objectMapper.writeValueAsString(msg)); + logger.log("End Message ***************"); + logger.log("Begin Message Body *************"); + String base64EncodedData = msg.getData(); + String decodedData = ""; + if (null != base64EncodedData) { + byte[] decodedDataBytes = Base64.getDecoder().decode(base64EncodedData); + decodedData = new String(decodedDataBytes); + } + logger.log(decodedData); + logger.log("End Message Body ***************"); + logger.log("EventSource = " + event.getEventSource()); + logger.log("EventSourceARN = " + event.getEventSourceArn()); + logger.log("CorrelationID = " + msg.getCorrelationID()); + logger.log("MessageID = " + msg.getMessageID()); + logger.log("MessageType = " + msg.getMessageType()); + logger.log("ReplyTo = " + msg.getReplyTo()); + logger.log("Type = " + msg.getType()); + logger.log("BrokerInTime = " + msg.getBrokerInTime()); + logger.log("BrokerOutTime = " + msg.getBrokerOutTime()); + logger.log("DeliveryMode = " + msg.getDeliveryMode()); + logger.log("Expiration = " + msg.getExpiration()); + logger.log("Priority = " + msg.getPriority()); + logger.log("TimeStamp = " + msg.getTimestamp()); + logger.log("Queue = " + msg.getDestination().getPhysicalName()); + logger.log("WhetherRedelivered = " + msg.getRedelivered()); + Person thisPerson = objectMapper.readValue(decodedData, Person.class); + //Person thisPerson = gson.fromJson(decodedData, Person.class); + logger.log("This person = " + thisPerson.toJson()); + String AWS_SAM_LOCAL = System.getenv("AWS_SAM_LOCAL"); + if ((null == AWS_SAM_LOCAL) && (addToDynamoDB)) { + ddbUpdater.insertIntoDynamoDB(msg, thisPerson, logger, currentTime, event.getEventSource(), event.getEventSourceArn()); + } + } catch (Exception e) { + logger.log("An exception happened - " + e.getMessage()); + return "500"; + } + } + return "200"; + } +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/Person.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/Person.java new file mode 100755 index 000000000..3b1601195 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/activemq/Person.java @@ -0,0 +1,135 @@ +package com.amazonaws.services.lambda.samples.events.activemq; + +import java.util.Objects; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Person { + + String firstname; + String lastname; + String company; + String street; + String city; + String county; + String state; + String zip; + String homePhone; + String cellPhone; + String email; + String website; + public Person() { + super(); + } + public String getFirstname() { + return firstname; + } + public void setFirstname(String firstname) { + this.firstname = firstname; + } + public String getLastname() { + return lastname; + } + public void setLastname(String lastname) { + this.lastname = lastname; + } + public String getCompany() { + return company; + } + public void setCompany(String company) { + this.company = company; + } + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getCounty() { + return county; + } + public void setCounty(String county) { + this.county = county; + } + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + public String getZip() { + return zip; + } + public void setZip(String zip) { + this.zip = zip; + } + public String getHomePhone() { + return homePhone; + } + public void setHomePhone(String homePhone) { + this.homePhone = homePhone; + } + public String getCellPhone() { + return cellPhone; + } + public void setCellPhone(String cellPhone) { + this.cellPhone = cellPhone; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getWebsite() { + return website; + } + public void setWebsite(String website) { + this.website = website; + } + @Override + public String toString() { + return "Person [firstname=" + firstname + ", lastname=" + lastname + ", company=" + company + ", street=" + + street + ", city=" + city + ", county=" + county + ", state=" + state + ", zip=" + zip + + ", homePhone=" + homePhone + ", cellPhone=" + cellPhone + ", email=" + email + ", website=" + website + + "]"; + } + + public String toJson() { + ObjectMapper om = new ObjectMapper(); + try { + return om.writeValueAsString(this); + } catch (JsonProcessingException e) { + return this.toString(); + } + } + @Override + public int hashCode() { + return Objects.hash(cellPhone, city, company, county, email, firstname, homePhone, lastname, state, street, + website, zip); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Person other = (Person) obj; + return Objects.equals(cellPhone, other.cellPhone) && Objects.equals(city, other.city) + && Objects.equals(company, other.company) && Objects.equals(county, other.county) + && Objects.equals(email, other.email) && Objects.equals(firstname, other.firstname) + && Objects.equals(homePhone, other.homePhone) && Objects.equals(lastname, other.lastname) + && Objects.equals(state, other.state) && Objects.equals(street, other.street) + && Objects.equals(website, other.website) && Objects.equals(zip, other.zip); + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdaterTest.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdaterTest.java new file mode 100755 index 000000000..3b4a0013d --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/DynamoDBUpdaterTest.java @@ -0,0 +1,260 @@ +package com.amazonaws.services.lambda.samples.events.activemq; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Base64; + +import org.junit.jupiter.api.Test; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.document.DynamoDB; +import com.amazonaws.services.dynamodbv2.document.Item; +import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.dynamodbv2.document.Table; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.mockito.ArgumentMatchers; + +class DynamoDBUpdaterTest { + + private static final String mqEventJson = "{\n" + + " \"eventSource\": \"aws:mq\",\n" + + " \"eventSourceArn\": \"arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0\",\n" + + " \"messages\": [\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:51\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148495,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-51\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMb3JyaWUiLCJsYXN0bmFtZSI6Ik5lc3RsZSIsImNvbXBhbnkiOiJCYWxsYXJkIFNwYWhyIEFuZHJld3MiLCJzdHJlZXQiOiIzOSBTIDd0aCBTdCIsImNpdHkiOiJUdWxsYWhvbWEiLCJjb3VudHkiOiJDb2ZmZWUiLCJzdGF0ZSI6IlROIiwiemlwIjoiMzczODgiLCJob21lUGhvbmUiOiI5MzEtODc1LTY2NDQiLCJjZWxsUGhvbmUiOiI5MzEtMzAzLTYwNDEiLCJlbWFpbCI6ImxuZXN0bGVAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5iYWxsYXJkc3BhaHJhbmRyZXdzLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148496,\n" + + " \"brokerOutTime\": 1687328529311\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:85\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148547,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-85\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNeXJhIiwibGFzdG5hbWUiOiJNdW5ucyIsImNvbXBhbnkiOiJBbmtlciBMYXcgT2ZmaWNlIiwic3RyZWV0IjoiNDYxIFByb3NwZWN0IFBsICMzMTYiLCJjaXR5IjoiRXVsZXNzIiwiY291bnR5IjoiVGFycmFudCIsInN0YXRlIjoiVFgiLCJ6aXAiOiI3NjA0MCIsImhvbWVQaG9uZSI6IjgxNy05MTQtNzUxOCIsImNlbGxQaG9uZSI6IjgxNy00NTEtMzUxOCIsImVtYWlsIjoibW11bm5zQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5hbmtlcmxhd29mZmljZS5jb20ifQ==\",\n" + + " \"brokerInTime\": 1687328148547,\n" + + " \"brokerOutTime\": 1687328529546\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:87\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148552,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-87\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMYWkiLCJsYXN0bmFtZSI6IkdhdG8iLCJjb21wYW55IjoiXCJGbGlnZywgS2VubmV0aCBJIEpyXCIiLCJzdHJlZXQiOiIzNyBBbGFiYW1hIEF2ZSIsImNpdHkiOiJFdmFuc3RvbiIsImNvdW50eSI6IkNvb2siLCJzdGF0ZSI6IklMIiwiemlwIjoiNjAyMDEiLCJob21lUGhvbmUiOiI4NDctNzI4LTcyODYiLCJjZWxsUGhvbmUiOiI4NDctOTU3LTQ2MTQiLCJlbWFpbCI6ImxhaS5nYXRvQGdhdG8ub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmxpZ2drZW5uZXRoaWpyLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148552,\n" + + " \"brokerOutTime\": 1687328529548\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:3\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148391,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-3\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148392,\n" + + " \"brokerOutTime\": 1687328529551\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:19\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148434,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-19\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJGbGV0Y2hlciIsImxhc3RuYW1lIjoiRmxvc2kiLCJjb21wYW55IjoiUG9zdCBCb3ggU2VydmljZXMgUGx1cyIsInN0cmVldCI6IjM5NCBNYW5jaGVzdGVyIEJsdmQiLCJjaXR5IjoiUm9ja2ZvcmQiLCJjb3VudHkiOiJXaW5uZWJhZ28iLCJzdGF0ZSI6IklMIiwiemlwIjoiNjExMDkiLCJob21lUGhvbmUiOiI4MTUtODI4LTIxNDciLCJjZWxsUGhvbmUiOiI4MTUtNDI2LTU2NTciLCJlbWFpbCI6ImZsZXRjaGVyLmZsb3NpQHlhaG9vLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnBvc3Rib3hzZXJ2aWNlc3BsdXMuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148435,\n" + + " \"brokerOutTime\": 1687328529565\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:54\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148504,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-54\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJLYXJsIiwibGFzdG5hbWUiOiJLbG9ub3dza2kiLCJjb21wYW55IjoiXCJSb3NzaSwgTWljaGFlbCBNXCIiLCJzdHJlZXQiOiI3NiBCcm9va3MgU3QgIzkiLCJjaXR5IjoiRmxlbWluZ3RvbiIsImNvdW50eSI6Ikh1bnRlcmRvbiIsInN0YXRlIjoiTkoiLCJ6aXAiOiI4ODIyIiwiaG9tZVBob25lIjoiOTA4LTg3Ny02MTM1IiwiY2VsbFBob25lIjoiOTA4LTQ3MC00NjYxIiwiZW1haWwiOiJrYXJsX2tsb25vd3NraUB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5yb3NzaW1pY2hhZWxtLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148505,\n" + + " \"brokerOutTime\": 1687328529568\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:49\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148492,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-49\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJCbGFpciIsImxhc3RuYW1lIjoiTWFsZXQiLCJjb21wYW55IjoiQm9sbGluZ2VyIE1hY2ggU2hwIFx1MDAyNiBTaGlweWFyZCIsInN0cmVldCI6IjIwOSBEZWNrZXIgRHIiLCJjaXR5IjoiUGhpbGFkZWxwaGlhIiwiY291bnR5IjoiUGhpbGFkZWxwaGlhIiwic3RhdGUiOiJQQSIsInppcCI6IjE5MTMyIiwiaG9tZVBob25lIjoiMjE1LTkwNy05MTExIiwiY2VsbFBob25lIjoiMjE1LTc5NC00NTE5IiwiZW1haWwiOiJibWFsZXRAeWFob28uY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuYm9sbGluZ2VybWFjaHNocHNoaXB5YXJkLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148493,\n" + + " \"brokerOutTime\": 1687328529586\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:99\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148582,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-99\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJBcmxlbmUiLCJsYXN0bmFtZSI6IktsdXNtYW4iLCJjb21wYW55IjoiQmVjayBIb3Jpem9uIEJ1aWxkZXJzIiwic3RyZWV0IjoiMyBTZWNvciBSZCIsImNpdHkiOiJOZXcgT3JsZWFucyIsImNvdW50eSI6Ik9ybGVhbnMiLCJzdGF0ZSI6IkxBIiwiemlwIjoiNzAxMTIiLCJob21lUGhvbmUiOiI1MDQtNzEwLTU4NDAiLCJjZWxsUGhvbmUiOiI1MDQtOTQ2LTE4MDciLCJlbWFpbCI6ImFybGVuZV9rbHVzbWFuQGdtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmJlY2tob3Jpem9uYnVpbGRlcnMuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148583,\n" + + " \"brokerOutTime\": 1687328529593\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:67\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148524,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-67\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJFbGx5IiwibGFzdG5hbWUiOiJNb3JvY2NvIiwiY29tcGFueSI6IktpbGxpb24gSW5kdXN0cmllcyIsInN0cmVldCI6IjcgVyAzMm5kIFN0IiwiY2l0eSI6IkVyaWUiLCJjb3VudHkiOiJFcmllIiwic3RhdGUiOiJQQSIsInppcCI6IjE2NTAyIiwiaG9tZVBob25lIjoiODE0LTM5My01NTcxIiwiY2VsbFBob25lIjoiODE0LTQyMC0zNTUzIiwiZW1haWwiOiJlbGx5X21vcm9jY29AZ21haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cua2lsbGlvbmluZHVzdHJpZXMuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148525,\n" + + " \"brokerOutTime\": 1687328529607\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:41\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148476,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-41\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": true,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJEeWFuIiwibGFzdG5hbWUiOiJPbGRyb3lkIiwiY29tcGFueSI6IkludGVybmF0aW9uYWwgRXllbGV0cyBJbmMiLCJzdHJlZXQiOiI3MjE5IFdvb2RmaWVsZCBSZCIsImNpdHkiOiJPdmVybGFuZCBQYXJrIiwiY291bnR5IjoiSm9obnNvbiIsInN0YXRlIjoiS1MiLCJ6aXAiOiI2NjIwNCIsImhvbWVQaG9uZSI6IjkxMy00MTMtNDYwNCIsImNlbGxQaG9uZSI6IjkxMy02NDUtODkxOCIsImVtYWlsIjoiZG9sZHJveWRAYW9sLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmludGVybmF0aW9uYWxleWVsZXRzaW5jLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148477,\n" + + " \"brokerOutTime\": 1687328529613\n" + + " }\n" + + " ]\n" + + "}"; + + @Test + void testDynamoDBUpdater() { + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater("DBTable"); + assertNotNull(ddbUpdater); + assertEquals(ddbUpdater.dynamoDBTableName, "DBTable"); + assertNotNull(ddbUpdater.client); + assertNotNull(ddbUpdater.dynamoDB); + assertNotNull(ddbUpdater.dynamoTable); + } + + @Test + void testInsertIntoDynamoDB() { + + ObjectMapper om = new ObjectMapper(); + ActiveMQEvent event = null; + try { + event = om.readValue(mqEventJson, ActiveMQEvent.class); + for(ActiveMQEvent.ActiveMQMessage msg : event.getMessages()){ + String base64EncodedData = msg.getData(); + String decodedData = ""; + if (null != base64EncodedData) { + byte[] decodedDataBytes = Base64.getDecoder().decode(base64EncodedData); + decodedData = new String(decodedDataBytes); + } + Person thisPerson = om.readValue(decodedData, Person.class); + Table dynamoDbTable = mock(Table.class); + AmazonDynamoDB client = mock(AmazonDynamoDB.class); + DynamoDB dynamoDB = mock(DynamoDB.class); + PutItemOutcome putoutcome = mock(PutItemOutcome.class); + LambdaLogger logger = mock(LambdaLogger.class); + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater("DBTable"); + ddbUpdater.client = client; + ddbUpdater.dynamoDB = dynamoDB; + ddbUpdater.dynamoTable = dynamoDbTable; + when(ddbUpdater.dynamoTable.putItem(ArgumentMatchers.any(Item.class))).thenReturn(putoutcome); + PutItemOutcome putOutcome = ddbUpdater.insertIntoDynamoDB(msg, thisPerson, logger, System.currentTimeMillis(), event.getEventSource(), event.getEventSourceArn()); + assertNotNull(putOutcome); + } + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQTest.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQTest.java new file mode 100755 index 000000000..a7336a04e --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/HandlerActiveMQTest.java @@ -0,0 +1,233 @@ +package com.amazonaws.services.lambda.samples.events.activemq; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +//import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +class HandlerSQSTest { + private static final String mqEventJson = "{\n" + + " \"eventSource\": \"aws:mq\",\n" + + " \"eventSourceArn\": \"arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0\",\n" + + " \"messages\": [\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:1\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148384,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-1\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148385,\n" + + " \"brokerOutTime\": 1687328148385\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:38\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148471,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-38\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJWYWxlbnRpbmUiLCJsYXN0bmFtZSI6IkdpbGxpYW4iLCJjb21wYW55IjoiRmJzIEJ1c2luZXNzIEZpbmFuY2UiLCJzdHJlZXQiOiI3NzUgVyAxN3RoIFN0IiwiY2l0eSI6IlNhbiBBbnRvbmlvIiwiY291bnR5IjoiQmV4YXIiLCJzdGF0ZSI6IlRYIiwiemlwIjoiNzgyMDQiLCJob21lUGhvbmUiOiIyMTAtODEyLTk1OTciLCJjZWxsUGhvbmUiOiIyMTAtMzAwLTYyNDQiLCJlbWFpbCI6InZhbGVudGluZV9naWxsaWFuQGdtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmZic2J1c2luZXNzZmluYW5jZS5jb20ifQ==\",\n" + + " \"brokerInTime\": 1687328148472,\n" + + " \"brokerOutTime\": 1687328148495\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:48\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148491,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-48\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJFbWVyc29uIiwibGFzdG5hbWUiOiJCb3dsZXkiLCJjb21wYW55IjoiS25pZ2h0cyBJbm4iLCJzdHJlZXQiOiI3NjIgUyBNYWluIFN0IiwiY2l0eSI6Ik1hZGlzb24iLCJjb3VudHkiOiJEYW5lIiwic3RhdGUiOiJXSSIsInppcCI6IjUzNzExIiwiaG9tZVBob25lIjoiNjA4LTMzNi03NDQ0IiwiY2VsbFBob25lIjoiNjA4LTY1OC03OTQwIiwiZW1haWwiOiJlbWVyc29uLmJvd2xleUBib3dsZXkub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cua25pZ2h0c2lubi5jb20ifQ==\",\n" + + " \"brokerInTime\": 1687328148492,\n" + + " \"brokerOutTime\": 1687328148534\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:53\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148498,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-53\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNYXJqb3J5IiwibGFzdG5hbWUiOiJNYXN0ZWxsYSIsImNvbXBhbnkiOiJWaWNvbiBDb3Jwb3JhdGlvbiIsInN0cmVldCI6IjcxIFNhbiBNYXRlbyBBdmUiLCJjaXR5IjoiV2F5bmUiLCJjb3VudHkiOiJEZWxhd2FyZSIsInN0YXRlIjoiUEEiLCJ6aXAiOiIxOTA4NyIsImhvbWVQaG9uZSI6IjYxMC04MTQtNTUzMyIsImNlbGxQaG9uZSI6IjYxMC0zNzktNzEyNSIsImVtYWlsIjoibW1hc3RlbGxhQG1hc3RlbGxhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnZpY29uY29ycG9yYXRpb24uY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148503,\n" + + " \"brokerOutTime\": 1687328148538\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:58\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148514,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-58\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJEZWxteSIsImxhc3RuYW1lIjoiQWhsZSIsImNvbXBhbnkiOiJXeWUgVGVjaG5vbG9naWVzIEluYyIsInN0cmVldCI6IjY1ODk1IFMgMTZ0aCBTdCIsImNpdHkiOiJQcm92aWRlbmNlIiwiY291bnR5IjoiUHJvdmlkZW5jZSIsInN0YXRlIjoiUkkiLCJ6aXAiOiIyOTA5IiwiaG9tZVBob25lIjoiNDAxLTQ1OC0yNTQ3IiwiY2VsbFBob25lIjoiNDAxLTU1OS04OTYxIiwiZW1haWwiOiJkZWxteS5haGxlQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cud3lldGVjaG5vbG9naWVzaW5jLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148514,\n" + + " \"brokerOutTime\": 1687328148552\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:63\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148520,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-63\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJDYXJtZWxpbmEiLCJsYXN0bmFtZSI6IkxpbmRhbGwiLCJjb21wYW55IjoiR2VvcmdlIEplc3NvcCBDYXJ0ZXIgSmV3ZWxlcnMiLCJzdHJlZXQiOiIyNjY0IExld2lzIFJkIiwiY2l0eSI6IkxpdHRsZXRvbiIsImNvdW50eSI6IkRvdWdsYXMiLCJzdGF0ZSI6IkNPIiwiemlwIjoiODAxMjYiLCJob21lUGhvbmUiOiIzMDMtNzI0LTczNzEiLCJjZWxsUGhvbmUiOiIzMDMtODc0LTUxNjAiLCJlbWFpbCI6ImNhcm1lbGluYV9saW5kYWxsQGxpbmRhbGwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZ2VvcmdlamVzc29wY2FydGVyamV3ZWxlcnMuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148520,\n" + + " \"brokerOutTime\": 1687328148556\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:68\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148526,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-68\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJJbGVuZSIsImxhc3RuYW1lIjoiRXJvbWFuIiwiY29tcGFueSI6IlwiUm9iaW5zb24sIFdpbGxpYW0gSiBFc3FcIiIsInN0cmVldCI6IjI4NTMgUyBDZW50cmFsIEV4cHkiLCJjaXR5IjoiR2xlbiBCdXJuaWUiLCJjb3VudHkiOiJBbm5lIEFydW5kZWwiLCJzdGF0ZSI6Ik1EIiwiemlwIjoiMjEwNjEiLCJob21lUGhvbmUiOiI0MTAtOTE0LTkwMTgiLCJjZWxsUGhvbmUiOiI0MTAtOTM3LTQ1NDMiLCJlbWFpbCI6ImlsZW5lLmVyb21hbkBob3RtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnJvYmluc29ud2lsbGlhbWplc3EuY29tIn0=\",\n" + + " \"brokerInTime\": 1687328148527,\n" + + " \"brokerOutTime\": 1687328148559\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:75\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148534,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-75\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNb29uIiwibGFzdG5hbWUiOiJQYXJsYXRvIiwiY29tcGFueSI6IlwiQW1iZWxhbmcsIEplc3NpY2EgTSBNZFwiIiwic3RyZWV0IjoiNzQ5ODkgQnJhbmRvbiBTdCIsImNpdHkiOiJXZWxsc3ZpbGxlIiwiY291bnR5IjoiQWxsZWdhbnkiLCJzdGF0ZSI6Ik5ZIiwiemlwIjoiMTQ4OTUiLCJob21lUGhvbmUiOiI1ODUtODY2LTgzMTMiLCJjZWxsUGhvbmUiOiI1ODUtNDk4LTQyNzgiLCJlbWFpbCI6Im1vb25AeWFob28uY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuYW1iZWxhbmdqZXNzaWNhbW1kLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148534,\n" + + " \"brokerOutTime\": 1687328148574\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:78\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148537,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-78\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJWaXZhIiwibGFzdG5hbWUiOiJUb2Vsa2VzIiwiY29tcGFueSI6Ik1hcmsgSXYgUHJlc3MgTHRkIiwic3RyZWV0IjoiNDI4NCBEb3JpZ28gTG4iLCJjaXR5IjoiQ2hpY2FnbyIsImNvdW50eSI6IkNvb2siLCJzdGF0ZSI6IklMIiwiemlwIjoiNjA2NDciLCJob21lUGhvbmUiOiI3NzMtNDQ2LTU1NjkiLCJjZWxsUGhvbmUiOiI3NzMtMzUyLTM0MzciLCJlbWFpbCI6InZpdmEudG9lbGtlc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tYXJraXZwcmVzc2x0ZC5jb20ifQ==\",\n" + + " \"brokerInTime\": 1687328148538,\n" + + " \"brokerOutTime\": 1687328148576\n" + + " },\n" + + " {\n" + + " \"messageID\": \"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:81\",\n" + + " \"messageType\": \"jms/text-message\",\n" + + " \"timestamp\": 1687328148540,\n" + + " \"deliveryMode\": 1,\n" + + " \"correlationID\": \"TestMessage07-06-21-2023-06-06-02-81\",\n" + + " \"replyTo\": \"null\",\n" + + " \"destination\": {\n" + + " \"physicalName\": \"LambdaActiveMQQueue\"\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"type\": \"TextMessage\",\n" + + " \"expiration\": 0,\n" + + " \"priority\": 4,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJUaW1vdGh5IiwibGFzdG5hbWUiOiJNdWxxdWVlbiIsImNvbXBhbnkiOiJTYXJvbml4IE55bXBoIFByb2R1Y3RzIiwic3RyZWV0IjoiNDQgVyA0dGggU3QiLCJjaXR5IjoiU3RhdGVuIElzbGFuZCIsImNvdW50eSI6IlJpY2htb25kIiwic3RhdGUiOiJOWSIsInppcCI6IjEwMzA5IiwiaG9tZVBob25lIjoiNzE4LTMzMi02NTI3IiwiY2VsbFBob25lIjoiNzE4LTY1NC03MDYzIiwiZW1haWwiOiJ0aW1vdGh5X211bHF1ZWVuQG11bHF1ZWVuLm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnNhcm9uaXhueW1waHByb2R1Y3RzLmNvbSJ9\",\n" + + " \"brokerInTime\": 1687328148541,\n" + + " \"brokerOutTime\": 1687328148578\n" + + " }\n" + + " ]\n" + + "}"; + + @Mock + DynamoDBUpdater ddbUpdater; + + @Test + @ExtendWith(MockitoExtension.class) + void invokeTest() { + + ObjectMapper om = new ObjectMapper(); + //SQSEvent event = gson.fromJson(sqsEventJson, SQSEvent.class); + ActiveMQEvent event = null; + try { + event = om.readValue(mqEventJson, ActiveMQEvent.class); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Context context = new TestContext(); + //PutItemOutcome putItemOutcome = mock(PutItemOutcome.class); + DynamoDBUpdater dbUpdater = mock(DynamoDBUpdater.class); + HandlerActiveMQ handler = new HandlerActiveMQ(); + handler.ddbUpdater = dbUpdater; + //when(handler.ddbUpdater.insertIntoDynamoDB(ArgumentMatchers.any(ActiveMQEvent.ActiveMQMessage.class), ArgumentMatchers.any(Gson.class), ArgumentMatchers.any(LambdaLogger.class), ArgumentMatchers.anyLong(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString())).thenReturn(putItemOutcome); + String result = handler.handleRequest(event, context); + assertEquals(result, "200"); + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestContext.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestContext.java new file mode 100755 index 000000000..8e5f4976d --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestContext.java @@ -0,0 +1,45 @@ +package com.amazonaws.services.lambda.samples.events.activemq; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.CognitoIdentity; +import com.amazonaws.services.lambda.runtime.ClientContext; +import com.amazonaws.services.lambda.runtime.LambdaLogger; + +public class TestContext implements Context{ + + public TestContext() {} + public String getAwsRequestId(){ + return new String("495b12a8-xmpl-4eca-8168-160484189f99"); + } + public String getLogGroupName(){ + return new String("/aws/lambda/my-function"); + } + public String getLogStreamName(){ + return new String("2020/02/26/[$LATEST]704f8dxmpla04097b9134246b8438f1a"); + } + public String getFunctionName(){ + return new String("my-function"); + } + public String getFunctionVersion(){ + return new String("$LATEST"); + } + public String getInvokedFunctionArn(){ + return new String("arn:aws:lambda:us-east-2:123456789012:function:my-function"); + } + public CognitoIdentity getIdentity(){ + return null; + } + public ClientContext getClientContext(){ + return null; + } + public int getRemainingTimeInMillis(){ + return 300000; + } + public int getMemoryLimitInMB(){ + return 512; + } + public LambdaLogger getLogger(){ + return new TestLogger(); + } + +} \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestLogger.java b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestLogger.java new file mode 100755 index 000000000..6ad6a1b9f --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/activemq/TestLogger.java @@ -0,0 +1,14 @@ +package com.amazonaws.services.lambda.samples.events.activemq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.amazonaws.services.lambda.runtime.LambdaLogger; + +public class TestLogger implements LambdaLogger { + private static final Logger logger = LoggerFactory.getLogger(TestLogger.class); + public void log(String message){ + logger.info(message); + } + public void log(byte[] message){ + logger.info(new String(message)); + } +} diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/events/event.json b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/events/event.json new file mode 100755 index 000000000..9d10fcf94 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/events/event.json @@ -0,0 +1,186 @@ +{ + "eventSource": "aws:mq", + "eventSourceArn": "arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0", + "messages": [ + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:1", + "messageType": "jms/text-message", + "timestamp": 1687328148384, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-1", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9", + "brokerInTime": 1687328148385, + "brokerOutTime": 1687328148385 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:38", + "messageType": "jms/text-message", + "timestamp": 1687328148471, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-38", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJWYWxlbnRpbmUiLCJsYXN0bmFtZSI6IkdpbGxpYW4iLCJjb21wYW55IjoiRmJzIEJ1c2luZXNzIEZpbmFuY2UiLCJzdHJlZXQiOiI3NzUgVyAxN3RoIFN0IiwiY2l0eSI6IlNhbiBBbnRvbmlvIiwiY291bnR5IjoiQmV4YXIiLCJzdGF0ZSI6IlRYIiwiemlwIjoiNzgyMDQiLCJob21lUGhvbmUiOiIyMTAtODEyLTk1OTciLCJjZWxsUGhvbmUiOiIyMTAtMzAwLTYyNDQiLCJlbWFpbCI6InZhbGVudGluZV9naWxsaWFuQGdtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmZic2J1c2luZXNzZmluYW5jZS5jb20ifQ==", + "brokerInTime": 1687328148472, + "brokerOutTime": 1687328148495 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:48", + "messageType": "jms/text-message", + "timestamp": 1687328148491, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-48", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJFbWVyc29uIiwibGFzdG5hbWUiOiJCb3dsZXkiLCJjb21wYW55IjoiS25pZ2h0cyBJbm4iLCJzdHJlZXQiOiI3NjIgUyBNYWluIFN0IiwiY2l0eSI6Ik1hZGlzb24iLCJjb3VudHkiOiJEYW5lIiwic3RhdGUiOiJXSSIsInppcCI6IjUzNzExIiwiaG9tZVBob25lIjoiNjA4LTMzNi03NDQ0IiwiY2VsbFBob25lIjoiNjA4LTY1OC03OTQwIiwiZW1haWwiOiJlbWVyc29uLmJvd2xleUBib3dsZXkub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cua25pZ2h0c2lubi5jb20ifQ==", + "brokerInTime": 1687328148492, + "brokerOutTime": 1687328148534 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:53", + "messageType": "jms/text-message", + "timestamp": 1687328148498, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-53", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJNYXJqb3J5IiwibGFzdG5hbWUiOiJNYXN0ZWxsYSIsImNvbXBhbnkiOiJWaWNvbiBDb3Jwb3JhdGlvbiIsInN0cmVldCI6IjcxIFNhbiBNYXRlbyBBdmUiLCJjaXR5IjoiV2F5bmUiLCJjb3VudHkiOiJEZWxhd2FyZSIsInN0YXRlIjoiUEEiLCJ6aXAiOiIxOTA4NyIsImhvbWVQaG9uZSI6IjYxMC04MTQtNTUzMyIsImNlbGxQaG9uZSI6IjYxMC0zNzktNzEyNSIsImVtYWlsIjoibW1hc3RlbGxhQG1hc3RlbGxhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnZpY29uY29ycG9yYXRpb24uY29tIn0=", + "brokerInTime": 1687328148503, + "brokerOutTime": 1687328148538 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:58", + "messageType": "jms/text-message", + "timestamp": 1687328148514, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-58", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJEZWxteSIsImxhc3RuYW1lIjoiQWhsZSIsImNvbXBhbnkiOiJXeWUgVGVjaG5vbG9naWVzIEluYyIsInN0cmVldCI6IjY1ODk1IFMgMTZ0aCBTdCIsImNpdHkiOiJQcm92aWRlbmNlIiwiY291bnR5IjoiUHJvdmlkZW5jZSIsInN0YXRlIjoiUkkiLCJ6aXAiOiIyOTA5IiwiaG9tZVBob25lIjoiNDAxLTQ1OC0yNTQ3IiwiY2VsbFBob25lIjoiNDAxLTU1OS04OTYxIiwiZW1haWwiOiJkZWxteS5haGxlQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cud3lldGVjaG5vbG9naWVzaW5jLmNvbSJ9", + "brokerInTime": 1687328148514, + "brokerOutTime": 1687328148552 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:63", + "messageType": "jms/text-message", + "timestamp": 1687328148520, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-63", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJDYXJtZWxpbmEiLCJsYXN0bmFtZSI6IkxpbmRhbGwiLCJjb21wYW55IjoiR2VvcmdlIEplc3NvcCBDYXJ0ZXIgSmV3ZWxlcnMiLCJzdHJlZXQiOiIyNjY0IExld2lzIFJkIiwiY2l0eSI6IkxpdHRsZXRvbiIsImNvdW50eSI6IkRvdWdsYXMiLCJzdGF0ZSI6IkNPIiwiemlwIjoiODAxMjYiLCJob21lUGhvbmUiOiIzMDMtNzI0LTczNzEiLCJjZWxsUGhvbmUiOiIzMDMtODc0LTUxNjAiLCJlbWFpbCI6ImNhcm1lbGluYV9saW5kYWxsQGxpbmRhbGwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZ2VvcmdlamVzc29wY2FydGVyamV3ZWxlcnMuY29tIn0=", + "brokerInTime": 1687328148520, + "brokerOutTime": 1687328148556 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:68", + "messageType": "jms/text-message", + "timestamp": 1687328148526, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-68", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJJbGVuZSIsImxhc3RuYW1lIjoiRXJvbWFuIiwiY29tcGFueSI6IlwiUm9iaW5zb24sIFdpbGxpYW0gSiBFc3FcIiIsInN0cmVldCI6IjI4NTMgUyBDZW50cmFsIEV4cHkiLCJjaXR5IjoiR2xlbiBCdXJuaWUiLCJjb3VudHkiOiJBbm5lIEFydW5kZWwiLCJzdGF0ZSI6Ik1EIiwiemlwIjoiMjEwNjEiLCJob21lUGhvbmUiOiI0MTAtOTE0LTkwMTgiLCJjZWxsUGhvbmUiOiI0MTAtOTM3LTQ1NDMiLCJlbWFpbCI6ImlsZW5lLmVyb21hbkBob3RtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnJvYmluc29ud2lsbGlhbWplc3EuY29tIn0=", + "brokerInTime": 1687328148527, + "brokerOutTime": 1687328148559 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:75", + "messageType": "jms/text-message", + "timestamp": 1687328148534, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-75", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJNb29uIiwibGFzdG5hbWUiOiJQYXJsYXRvIiwiY29tcGFueSI6IlwiQW1iZWxhbmcsIEplc3NpY2EgTSBNZFwiIiwic3RyZWV0IjoiNzQ5ODkgQnJhbmRvbiBTdCIsImNpdHkiOiJXZWxsc3ZpbGxlIiwiY291bnR5IjoiQWxsZWdhbnkiLCJzdGF0ZSI6Ik5ZIiwiemlwIjoiMTQ4OTUiLCJob21lUGhvbmUiOiI1ODUtODY2LTgzMTMiLCJjZWxsUGhvbmUiOiI1ODUtNDk4LTQyNzgiLCJlbWFpbCI6Im1vb25AeWFob28uY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuYW1iZWxhbmdqZXNzaWNhbW1kLmNvbSJ9", + "brokerInTime": 1687328148534, + "brokerOutTime": 1687328148574 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:78", + "messageType": "jms/text-message", + "timestamp": 1687328148537, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-78", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJWaXZhIiwibGFzdG5hbWUiOiJUb2Vsa2VzIiwiY29tcGFueSI6Ik1hcmsgSXYgUHJlc3MgTHRkIiwic3RyZWV0IjoiNDI4NCBEb3JpZ28gTG4iLCJjaXR5IjoiQ2hpY2FnbyIsImNvdW50eSI6IkNvb2siLCJzdGF0ZSI6IklMIiwiemlwIjoiNjA2NDciLCJob21lUGhvbmUiOiI3NzMtNDQ2LTU1NjkiLCJjZWxsUGhvbmUiOiI3NzMtMzUyLTM0MzciLCJlbWFpbCI6InZpdmEudG9lbGtlc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tYXJraXZwcmVzc2x0ZC5jb20ifQ==", + "brokerInTime": 1687328148538, + "brokerOutTime": 1687328148576 + }, + { + "messageID": "ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:81", + "messageType": "jms/text-message", + "timestamp": 1687328148540, + "deliveryMode": 1, + "correlationID": "TestMessage07-06-21-2023-06-06-02-81", + "replyTo": "null", + "destination": { + "physicalName": "LambdaActiveMQQueue" + }, + "redelivered": false, + "type": "TextMessage", + "expiration": 0, + "priority": 4, + "data": "eyJmaXJzdG5hbWUiOiJUaW1vdGh5IiwibGFzdG5hbWUiOiJNdWxxdWVlbiIsImNvbXBhbnkiOiJTYXJvbml4IE55bXBoIFByb2R1Y3RzIiwic3RyZWV0IjoiNDQgVyA0dGggU3QiLCJjaXR5IjoiU3RhdGVuIElzbGFuZCIsImNvdW50eSI6IlJpY2htb25kIiwic3RhdGUiOiJOWSIsInppcCI6IjEwMzA5IiwiaG9tZVBob25lIjoiNzE4LTMzMi02NTI3IiwiY2VsbFBob25lIjoiNzE4LTY1NC03MDYzIiwiZW1haWwiOiJ0aW1vdGh5X211bHF1ZWVuQG11bHF1ZWVuLm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnNhcm9uaXhueW1waHByb2R1Y3RzLmNvbSJ9", + "brokerInTime": 1687328148541, + "brokerOutTime": 1687328148578 + } + ] +} \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml new file mode 100755 index 000000000..53269fa6e --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml @@ -0,0 +1,119 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + activemq_event_consumer_function + + Sample SAM Template for activemq-consumer-with-sam + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 60 + +Resources: + LambdaActiveMQConsumerJavaFunction: + Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Properties: + FunctionName: java-activemq-consumer-dynamodb-sam + CodeUri: activemq_event_consumer_function + Handler: com.amazonaws.services.lambda.samples.events.activemq.HandlerActiveMQ::handleRequest + Runtime: java21 + Architectures: + - x86_64 + MemorySize: 512 + Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object + Variables: + DYNAMO_DB_TABLE: !Ref ActiveMQDynamoDBTable + JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/ + VpcConfig: + SecurityGroupIds: + - !Ref SecurityGroup + SubnetIds: + - !Ref Subnet1 + - !Ref Subnet2 + Events: + MQEvent: + Type: MQ + Properties: + BatchSize: 100 + MaximumBatchingWindowInSeconds: 5 + Broker: + !Join ['', ["arn:", "aws:", "mq:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "broker:", !Ref ActiveMQBrokerName, ":", !Ref ActiveMQBrokerUniqueString]] + Queues: + - !Ref ActiveMQQueue + SourceAccessConfigurations: + - Type: BASIC_AUTH + URI: + !Join ['', ["arn:", "aws:", "secretsmanager:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "secret:", !Ref SecretsManagerSecretForMQName, "-", !Ref SecretsManagerSecretForMQUniqueString]] + + Policies: + - Statement: + - Sid: ActiveMQPermissionsPolicy + Effect: Allow + Action: + - mq:DescribeBroker + - secretsmanager:GetSecretValue + - ec2:CreateNetworkInterface + - ec2:DeleteNetworkInterface + - ec2:DescribeNetworkInterfaces + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: '*' + - Statement: + - Sid: DynamoDBPermissionsPolicy + Effect: Allow + Action: + - dynamodb:GetItem + - dynamodb:DeleteItem + - dynamodb:PutItem + - dynamodb:Scan + - dynamodb:Query + - dynamodb:UpdateItem + - dynamodb:BatchWriteItem + - dynamodb:BatchGetItem + - dynamodb:DescribeTable + - dynamodb:ConditionCheckItem + Resource: + - !Join ['', ["arn:", "aws:", "dynamodb:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "table/", !Ref ActiveMQDynamoDBTable]] + - !Join ['', ["arn:", "aws:", "dynamodb:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "table/", !Ref ActiveMQDynamoDBTable, "/index/*"]] + + ActiveMQDynamoDBTable: + Type: AWS::Serverless::SimpleTable + Properties: + TableName: ActiveMQDynamoDBTableJava + PrimaryKey: + Name: MessageID + Type: String +Parameters: + ActiveMQBrokerName: + Type: String + Description: Enter the name of the ActiveMQBroker that is part of the ARN + ActiveMQBrokerUniqueString: + Type: String + Description: Enter the unique string of the ActiveMQBroker after the broker name in the ARN + ActiveMQQueue: + Type: String + Description: Enter the name of the ActiveMQ queue from which the lambda function will consume messages + SecretsManagerSecretForMQName: + Type: String + Description: Enter the name of the secret that has username/password for Active MQ + SecretsManagerSecretForMQUniqueString: + Type: String + Description: Enter the unique string of the secret that has username/password for Active MQ + Subnet1: + Type: String + Description: The first of the three private subnets in the ActiveMQ broker's VPC + Subnet2: + Type: String + Description: The second of the three private subnets in the ActiveMQ broker's VPC + SecurityGroup: + Type: String + Description: The security group associated with this function (use same ActiveMQ) +Outputs: + LambdaActiveMQConsumerJavaFunction: + Description: "Queue Consumer Lambda Function ARN" + Value: !GetAtt LambdaActiveMQConsumerJavaFunction.Arn diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/.gitignore b/activemq-private-lambda-java-sam/activemq_message_sender_json/.gitignore new file mode 100755 index 000000000..b83d22266 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.core.resources.prefs b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.core.resources.prefs new file mode 100755 index 000000000..29abf9995 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.apt.core.prefs b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 000000000..d4313d4b2 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.core.prefs b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 000000000..ea7a397f8 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,16 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.m2e.core.prefs b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt b/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt new file mode 100755 index 000000000..c56ac3bf8 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt @@ -0,0 +1,5 @@ +java -classpath /activemq_message_sender_json/target/json-activemq-producer-0.0.1-SNAPSHOT.jar activemq.producer.JsonActiveMQProducer + +Example: + +java -classpath ~/environment/JavaExamples/activemq_message_sender_json/target/json-activemq-producer-0.0.1-SNAPSHOT.jar activemq.producer.JsonActiveMQProducer "failover:(ssl://b-aeb08c0d-6e46-412a-ad45-1507816242b0-1.mq.us-west-2.amazonaws.com:61617,ssl://b-aeb08c0d-6e46-412a-ad45-1507816242b0-2.mq.us-west-2.amazonaws.com:61617)" LambdaActiveMQQueue TestMessage12 10 \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md b/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md new file mode 100755 index 000000000..c72cc7d00 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md @@ -0,0 +1,27 @@ +# activemq-message-sender-json + +This project contains source code and supporting files for a Java application that you can use to generate messages to an ActiveMQ broker queue, that can in turn be consumed by a Lambda function + +- activemq_message_sender_json/src/main/java - Code for the application. +- activemq_message_sender_json/Commands - A file that contains the command to run this application so messages can be generated on an ActiveMQ queue, to invoke the corresponding Lambda function + +## Set-up and run this application + +The steps required before this application can be run are + +1) Install and configure an ActiveMQ cluster (use AWS console or a Cloudformation template) - for detailed instructions look at the AWS documentation - https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-creating-configuring-broker.html. For information on how to use Cloudformation to create an ActiveMQ cluster, take a look at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amazonmq-broker.html + +2) Create a secret in AWS Secrets Manager called AmazonMQCredentials - Choose a secret of type "Other Type of Secret" when creating the secret. Provide the username and password to connect to the ActiveMQ broker, as had been specified at the time of cluster creation. Name this secret AmazonMQCredentials + +3) After cloning the code for this project from Github, go to the folder where the project was cloned and run the command 'mvn clean install' (without the quotes). Make sure maven is installed on the computer from where you are running this command, prior to running the command + +4) If you are running the command to send ActiveMQ messages from a Cloud9 or EC2 instance, make sure that the security group of the ActiveMQ cluster allows inbound traffic from the security group of the Cloud9 or EC2 instance on port 61617. Also make sure that the role associated with the Cloud9 or EC2 instance has policies attached to it that allow the permissions that are needed. For example, you can use the AmazonMQFullAccess policy on the role. + +5) Use the command specified in the activemq_message_sender_json/Commands file to generate ActiveMQ queue messages that can be consumed by the Lambda function. The command specified in the Commands file takes four parameters + + a) The ActiveMQ broker URL of the ActiveMQ cluster created in Step 1 + b) The name of the ActiveMQ queue on which messages will be published. This must match the name of the ActiveMQ queue that is configured in the event source of the lambda function + c) A Unique String that can be used to identify the batch of ActiveMQ queue messages that will be generated + d) The number of ActiveMQ queue messages to generate as part of this batch + +6) If a Lambda function consumer of the ActiveMQ queue messages has already been deployed, then you should be able to see the content of the messages in the Lambda function logs in Cloudwatch \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/pom.xml b/activemq-private-lambda-java-sam/activemq_message_sender_json/pom.xml new file mode 100755 index 000000000..02bc96c19 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/pom.xml @@ -0,0 +1,136 @@ + + 4.0.0 + com.amazonaws.services.lambda.samples.events.activemq + json-activemq-producer + 0.0.1-SNAPSHOT + + UTF-8 + 21 + 21 + 2.20.68 + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.11.0 + + + com.google.code.gson + gson + 2.8.9 + + + org.apache.logging.log4j + log4j-api + 2.21.0 + + + org.apache.logging.log4j + log4j-core + 2.21.0 + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + + software.amazon.awssdk + bom + ${aws.java.sdk.version} + pom + import + + + + software.amazon.awssdk + regions + 2.20.68 + + + software.amazon.awssdk + secretsmanager + 2.20.68 + + + + + software.amazon.awssdk + utils + 2.20.68 + + + com.fasterxml.jackson.core + jackson-core + 2.15.1 + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + 2.15.1 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.15.2 + + + org.apache.activemq + activemq-client + 5.18.4 + + + org.apache.activemq + activemq-pool + 5.18.4 + + + + + + maven-surefire-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.2 + + false + + + + package + + shade + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/JsonActiveMQProducer.java b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/JsonActiveMQProducer.java new file mode 100755 index 000000000..811ca7a85 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/JsonActiveMQProducer.java @@ -0,0 +1,195 @@ +package activemq.producer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.jms.pool.PooledConnectionFactory; +import javax.jms.TextMessage; +import javax.jms.Connection; +import javax.jms.Session; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.DeliveryMode; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class JsonActiveMQProducer { + + Properties prop; + + public static void main(String[] args) { + + String activeMQEndpoint = args[0]; + String activeMQUsername = SecretsManagerDecoder.getUsernameAndPassword().getUsername(); + String activeMQPassword = SecretsManagerDecoder.getUsernameAndPassword().getPassword(); + String activeMQQueue = args[1]; + String seederKeyString = args[2]; + int numberOfMessages = Integer.parseInt(args[3]); + String activeMQMessageKey = seederKeyString + "-" + JsonActiveMQProducer.getTodayDate(); + try { + JsonActiveMQProducer.activeMQQueueReceiver(activeMQEndpoint, activeMQUsername, activeMQPassword, activeMQQueue, activeMQMessageKey, numberOfMessages); + System.exit(0); + } catch (Exception e) { + System.out.println("Exception occurred"); + e.printStackTrace(); + System.exit(-1); + } + } + + public static void activeMQQueueReceiver(String activeMQEndpoint, String activeMQUsername, String activeMQPassword, String activeMQQueue, String seederKeyString, int numberOfMessages) throws Exception { + List people = JsonActiveMQProducer.readDataFile(); + int numberOfMessagesToSend=0; + if (people.size() > numberOfMessages) { + numberOfMessagesToSend = numberOfMessages; + } else { + numberOfMessagesToSend = people.size(); + } + + final ActiveMQConnectionFactory connectionFactory = + createActiveMQConnectionFactory(activeMQEndpoint, activeMQUsername, activeMQPassword); + final PooledConnectionFactory pooledConnectionFactory = + createPooledConnectionFactory(connectionFactory); + + final Connection producerConnection = pooledConnectionFactory + .createConnection(); + producerConnection.start(); + + // Create a session. + final Session producerSession = producerConnection + .createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create a queue + + Destination producerDestination; + try { + producerDestination = producerSession + .createQueue(activeMQQueue); + // Create a producer from the session to the queue. + final MessageProducer producer = producerSession + .createProducer(producerDestination); + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + + for (int i = 1; i <= numberOfMessagesToSend; i++) { + Person thisPerson = JsonActiveMQProducer.getPersonFromLine(people.get(i)); + String thisPersonJson = thisPerson.toJson(); + // Create a message. + TextMessage producerMessage = producerSession + .createTextMessage(thisPersonJson); + producerMessage.setJMSCorrelationID(seederKeyString + "-" + i); + producerMessage.setJMSType("TextMessage"); + producerMessage.setStringProperty("MessageBatchIdentifier", seederKeyString); + producerMessage.setIntProperty("MessageNumberInBatch", i); + producerMessage.setJMSExpiration(1800000); + producerMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT); + // Send the message. + long currentTime = System.currentTimeMillis(); + producer.send(producerMessage); + System.out.println("Sent out one message - Number " + i + " at time = " + currentTime); + } + producer.close(); + + } catch (Exception e1) { + System.out.println("Queue creation failed. Queue may already exist"); + System.out.println(e1.getMessage()); + e1.printStackTrace(); + } finally { + producerSession.close(); + producerConnection.close(); + } + } + + public static Properties readPropertiesFile(String fileName) throws FileNotFoundException, IOException { + FileInputStream fis = null; + Properties prop = null; + try { + fis = new FileInputStream(fileName); + prop = new Properties(); + prop.load(fis); + } catch (FileNotFoundException fnfe) { + fnfe.printStackTrace(); + throw new FileNotFoundException("Not a valid property file path"); + } catch (IOException ioe) { + ioe.printStackTrace(); + throw new IOException("Problem reading property file. Check permissions"); + } finally { + fis.close(); + } + return prop; + } + + public static List readDataFile() { + List personList = new ArrayList(); + InputStream is = JsonActiveMQProducer.class.getClassLoader().getResourceAsStream("us-500.csv"); + BufferedReader bf = new BufferedReader(new InputStreamReader(is)); + String thisLine = null; + try { + thisLine = bf.readLine(); + while (null != thisLine) { + personList.add(thisLine); + thisLine = bf.readLine(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return personList; + } + + public static Person getPersonFromLine(String line) { + + //String[] fields = line.split(","); + String[] fields = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1); + Person thisPerson = new Person(); + thisPerson.setFirstname(fields[0]); + thisPerson.setLastname(fields[1]); + thisPerson.setCompany(fields[2]); + thisPerson.setStreet(fields[3]); + thisPerson.setCity(fields[4]); + thisPerson.setCounty(fields[5]); + thisPerson.setState(fields[6]); + thisPerson.setZip(fields[7]); + thisPerson.setHomePhone(fields[8]); + thisPerson.setCellPhone(fields[9]); + thisPerson.setEmail(fields[10]); + thisPerson.setWebsite(fields[11]); + return thisPerson; + } + + public static String getTodayDate() { + + LocalDateTime ldt = LocalDateTime.now(); + String formattedDateStr = DateTimeFormatter.ofPattern("MM-dd-YYYY-HH-MM-SS").format(ldt); + return formattedDateStr; + } + + private static PooledConnectionFactory + createPooledConnectionFactory(ActiveMQConnectionFactory connectionFactory) { + // Create a pooled connection factory. + final PooledConnectionFactory pooledConnectionFactory = + new PooledConnectionFactory(); + pooledConnectionFactory.setConnectionFactory(connectionFactory); + pooledConnectionFactory.setMaxConnections(10); + return pooledConnectionFactory; + } + + private static ActiveMQConnectionFactory createActiveMQConnectionFactory(String activeMQEndpoint, String activeMQUsername, String activeMQPassword) { + // Create a connection factory. + final ActiveMQConnectionFactory connectionFactory = + new ActiveMQConnectionFactory(activeMQEndpoint); + + // Pass the sign-in credentials. + connectionFactory.setUserName(activeMQUsername); + connectionFactory.setPassword(activeMQPassword); + return connectionFactory; + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/Person.java b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/Person.java new file mode 100755 index 000000000..49b835da0 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/Person.java @@ -0,0 +1,107 @@ +package activemq.producer; + +import com.google.gson.Gson; + +public class Person { + + String firstname; + String lastname; + String company; + String street; + String city; + String county; + String state; + String zip; + String homePhone; + String cellPhone; + String email; + String website; + public Person() { + super(); + } + public String getFirstname() { + return firstname; + } + public void setFirstname(String firstname) { + this.firstname = firstname; + } + public String getLastname() { + return lastname; + } + public void setLastname(String lastname) { + this.lastname = lastname; + } + public String getCompany() { + return company; + } + public void setCompany(String company) { + this.company = company; + } + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getCounty() { + return county; + } + public void setCounty(String county) { + this.county = county; + } + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + public String getZip() { + return zip; + } + public void setZip(String zip) { + this.zip = zip; + } + public String getHomePhone() { + return homePhone; + } + public void setHomePhone(String homePhone) { + this.homePhone = homePhone; + } + public String getCellPhone() { + return cellPhone; + } + public void setCellPhone(String cellPhone) { + this.cellPhone = cellPhone; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getWebsite() { + return website; + } + public void setWebsite(String website) { + this.website = website; + } + @Override + public String toString() { + return "Person [firstname=" + firstname + ", lastname=" + lastname + ", company=" + company + ", street=" + + street + ", city=" + city + ", county=" + county + ", state=" + state + ", zip=" + zip + + ", homePhone=" + homePhone + ", cellPhone=" + cellPhone + ", email=" + email + ", website=" + website + + "]"; + } + + public String toJson() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java new file mode 100755 index 000000000..a5c340af2 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java @@ -0,0 +1,47 @@ +package activemq.producer; + +import com.google.gson.Gson; + +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; +import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; +import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse; + +public class SecretsManagerDecoder { + + public static String getSecret() { + + String secretName = "AmazonMQCredentials"; + + DefaultAwsRegionProviderChain defaultAwsRegionProviderChain = new DefaultAwsRegionProviderChain(); + Region region = defaultAwsRegionProviderChain.getRegion(); + System.out.println("region = " + region.toString()); + + SecretsManagerClient client = SecretsManagerClient.builder() + .region(region) + .build(); + + GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder() + .secretId(secretName) + .build(); + + GetSecretValueResponse getSecretValueResponse = null; + + try { + getSecretValueResponse = client.getSecretValue(getSecretValueRequest); + } catch (Exception e) { + e.printStackTrace(); + } + if (null != getSecretValueResponse) { + return getSecretValueResponse.secretString(); + } else { + return "Sorry mate! No secret found"; + } + } + + public static User getUsernameAndPassword() { + Gson gson = new Gson(); + return gson.fromJson(SecretsManagerDecoder.getSecret(), User.class); + } +} diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/User.java b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/User.java new file mode 100755 index 000000000..672ee8836 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/User.java @@ -0,0 +1,67 @@ +package activemq.producer; + +import java.util.Objects; + +public class User { + String username; + String password; + /** + * + */ + public User() { + super(); + } + /** + * @param username + * @param password + */ + public User(String username, String password) { + super(); + this.username = username; + this.password = password; + } + /** + * @return the username + */ + public String getUsername() { + return username; + } + /** + * @param username the username to set + */ + public void setUsername(String username) { + this.username = username; + } + /** + * @return the password + */ + public String getPassword() { + return password; + } + /** + * @param password the password to set + */ + public void setPassword(String password) { + this.password = password; + } + @Override + public int hashCode() { + return Objects.hash(password, username); + } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof User)) { + return false; + } + User other = (User) obj; + return Objects.equals(password, other.password) && Objects.equals(username, other.username); + } + @Override + public String toString() { + return "User [username=" + username + ", password=" + password + "]"; + } + +} diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/resources/us-500.csv b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/resources/us-500.csv new file mode 100755 index 000000000..20c58066e --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/resources/us-500.csv @@ -0,0 +1,500 @@ +James,Butt,"Benton, John B Jr",6649 N Blue Gum St,New Orleans,Orleans,LA,70116,504-621-8927,504-845-1427,jbutt@gmail.com,http://www.bentonjohnbjr.com +Josephine,Darakjy,"Chanay, Jeffrey A Esq",4 B Blue Ridge Blvd,Brighton,Livingston,MI,48116,810-292-9388,810-374-9840,josephine_darakjy@darakjy.org,http://www.chanayjeffreyaesq.com +Art,Venere,"Chemel, James L Cpa",8 W Cerritos Ave #54,Bridgeport,Gloucester,NJ,8014,856-636-8749,856-264-4130,art@venere.org,http://www.chemeljameslcpa.com +Lenna,Paprocki,Feltz Printing Service,639 Main St,Anchorage,Anchorage,AK,99501,907-385-4412,907-921-2010,lpaprocki@hotmail.com,http://www.feltzprintingservice.com +Donette,Foller,Printing Dimensions,34 Center St,Hamilton,Butler,OH,45011,513-570-1893,513-549-4561,donette.foller@cox.net,http://www.printingdimensions.com +Simona,Morasca,"Chapman, Ross E Esq",3 Mcauley Dr,Ashland,Ashland,OH,44805,419-503-2484,419-800-6759,simona@morasca.com,http://www.chapmanrosseesq.com +Mitsue,Tollner,Morlong Associates,7 Eads St,Chicago,Cook,IL,60632,773-573-6914,773-924-8565,mitsue_tollner@yahoo.com,http://www.morlongassociates.com +Leota,Dilliard,Commercial Press,7 W Jackson Blvd,San Jose,Santa Clara,CA,95111,408-752-3500,408-813-1105,leota@hotmail.com,http://www.commercialpress.com +Sage,Wieser,Truhlar And Truhlar Attys,5 Boston Ave #88,Sioux Falls,Minnehaha,SD,57105,605-414-2147,605-794-4895,sage_wieser@cox.net,http://www.truhlarandtruhlarattys.com +Kris,Marrier,"King, Christopher A Esq",228 Runamuck Pl #2808,Baltimore,Baltimore City,MD,21224,410-655-8723,410-804-4694,kris@gmail.com,http://www.kingchristopheraesq.com +Minna,Amigon,"Dorl, James J Esq",2371 Jerrold Ave,Kulpsville,Montgomery,PA,19443,215-874-1229,215-422-8694,minna_amigon@yahoo.com,http://www.dorljamesjesq.com +Abel,Maclead,Rangoni Of Florence,37275 St Rt 17m M,Middle Island,Suffolk,NY,11953,631-335-3414,631-677-3675,amaclead@gmail.com,http://www.rangoniofflorence.com +Kiley,Caldarera,Feiner Bros,25 E 75th St #69,Los Angeles,Los Angeles,CA,90034,310-498-5651,310-254-3084,kiley.caldarera@aol.com,http://www.feinerbros.com +Graciela,Ruta,Buckley Miller & Wright,98 Connecticut Ave Nw,Chagrin Falls,Geauga,OH,44023,440-780-8425,440-579-7763,gruta@cox.net,http://www.buckleymillerwright.com +Cammy,Albares,"Rousseaux, Michael Esq",56 E Morehead St,Laredo,Webb,TX,78045,956-537-6195,956-841-7216,calbares@gmail.com,http://www.rousseauxmichaelesq.com +Mattie,Poquette,Century Communications,73 State Road 434 E,Phoenix,Maricopa,AZ,85013,602-277-4385,602-953-6360,mattie@aol.com,http://www.centurycommunications.com +Meaghan,Garufi,"Bolton, Wilbur Esq",69734 E Carrillo St,Mc Minnville,Warren,TN,37110,931-313-9635,931-235-7959,meaghan@hotmail.com,http://www.boltonwilburesq.com +Gladys,Rim,T M Byxbee Company Pc,322 New Horizon Blvd,Milwaukee,Milwaukee,WI,53207,414-661-9598,414-377-2880,gladys.rim@rim.org,http://www.tmbyxbeecompanypc.com +Yuki,Whobrey,Farmers Insurance Group,1 State Route 27,Taylor,Wayne,MI,48180,313-288-7937,313-341-4470,yuki_whobrey@aol.com,http://www.farmersinsurancegroup.com +Fletcher,Flosi,Post Box Services Plus,394 Manchester Blvd,Rockford,Winnebago,IL,61109,815-828-2147,815-426-5657,fletcher.flosi@yahoo.com,http://www.postboxservicesplus.com +Bette,Nicka,Sport En Art,6 S 33rd St,Aston,Delaware,PA,19014,610-545-3615,610-492-4643,bette_nicka@cox.net,http://www.sportenart.com +Veronika,Inouye,C 4 Network Inc,6 Greenleaf Ave,San Jose,Santa Clara,CA,95111,408-540-1785,408-813-4592,vinouye@aol.com,http://www.cnetworkinc.com +Willard,Kolmetz,"Ingalls, Donald R Esq",618 W Yakima Ave,Irving,Dallas,TX,75062,972-303-9197,972-896-4882,willard@hotmail.com,http://www.ingallsdonaldresq.com +Maryann,Royster,"Franklin, Peter L Esq",74 S Westgate St,Albany,Albany,NY,12204,518-966-7987,518-448-8982,mroyster@royster.com,http://www.franklinpeterlesq.com +Alisha,Slusarski,Wtlz Power 107 Fm,3273 State St,Middlesex,Middlesex,NJ,8846,732-658-3154,732-635-3453,alisha@slusarski.com,http://www.wtlzpowerfm.com +Allene,Iturbide,"Ledecky, David Esq",1 Central Ave,Stevens Point,Portage,WI,54481,715-662-6764,715-530-9863,allene_iturbide@cox.net,http://www.ledeckydavidesq.com +Chanel,Caudy,Professional Image Inc,86 Nw 66th St #8673,Shawnee,Johnson,KS,66218,913-388-2079,913-899-1103,chanel.caudy@caudy.org,http://www.professionalimageinc.com +Ezekiel,Chui,"Sider, Donald C Esq",2 Cedar Ave #84,Easton,Talbot,MD,21601,410-669-1642,410-235-8738,ezekiel@chui.com,http://www.siderdonaldcesq.com +Willow,Kusko,U Pull It,90991 Thorburn Ave,New York,New York,NY,10011,212-582-4976,212-934-5167,wkusko@yahoo.com,http://www.upullit.com +Bernardo,Figeroa,"Clark, Richard Cpa",386 9th Ave N,Conroe,Montgomery,TX,77301,936-336-3951,936-597-3614,bfigeroa@aol.com,http://www.clarkrichardcpa.com +Ammie,Corrio,"Moskowitz, Barry S",74874 Atlantic Ave,Columbus,Franklin,OH,43215,614-801-9788,614-648-3265,ammie@corrio.com,http://www.moskowitzbarrys.com +Francine,Vocelka,Cascade Realty Advisors Inc,366 South Dr,Las Cruces,Dona Ana,NM,88011,505-977-3911,505-335-5293,francine_vocelka@vocelka.com,http://www.cascaderealtyadvisorsinc.com +Ernie,Stenseth,Knwz Newsradio,45 E Liberty St,Ridgefield Park,Bergen,NJ,7660,201-709-6245,201-387-9093,ernie_stenseth@aol.com,http://www.knwznewsradio.com +Albina,Glick,"Giampetro, Anthony D",4 Ralph Ct,Dunellen,Middlesex,NJ,8812,732-924-7882,732-782-6701,albina@glick.com,http://www.giampetroanthonyd.com +Alishia,Sergi,Milford Enterprises Inc,2742 Distribution Way,New York,New York,NY,10025,212-860-1579,212-753-2740,asergi@gmail.com,http://www.milfordenterprisesinc.com +Solange,Shinko,"Mosocco, Ronald A",426 Wolf St,Metairie,Jefferson,LA,70002,504-979-9175,504-265-8174,solange@shinko.com,http://www.mosoccoronalda.com +Jose,Stockham,Tri State Refueler Co,128 Bransten Rd,New York,New York,NY,10011,212-675-8570,212-569-4233,jose@yahoo.com,http://www.tristaterefuelerco.com +Rozella,Ostrosky,Parkway Company,17 Morena Blvd,Camarillo,Ventura,CA,93012,805-832-6163,805-609-1531,rozella.ostrosky@ostrosky.com,http://www.parkwaycompany.com +Valentine,Gillian,Fbs Business Finance,775 W 17th St,San Antonio,Bexar,TX,78204,210-812-9597,210-300-6244,valentine_gillian@gmail.com,http://www.fbsbusinessfinance.com +Kati,Rulapaugh,Eder Assocs Consltng Engrs Pc,6980 Dorsett Rd,Abilene,Dickinson,KS,67410,785-463-7829,785-219-7724,kati.rulapaugh@hotmail.com,http://www.ederassocsconsltngengrspc.com +Youlanda,Schemmer,Tri M Tool Inc,2881 Lewis Rd,Prineville,Crook,OR,97754,541-548-8197,541-993-2611,youlanda@aol.com,http://www.trimtoolinc.com +Dyan,Oldroyd,International Eyelets Inc,7219 Woodfield Rd,Overland Park,Johnson,KS,66204,913-413-4604,913-645-8918,doldroyd@aol.com,http://www.internationaleyeletsinc.com +Roxane,Campain,Rapid Trading Intl,1048 Main St,Fairbanks,Fairbanks North Star,AK,99708,907-231-4722,907-335-6568,roxane@hotmail.com,http://www.rapidtradingintl.com +Lavera,Perin,Abc Enterprises Inc,678 3rd Ave,Miami,Miami-Dade,FL,33196,305-606-7291,305-995-2078,lperin@perin.org,http://www.abcenterprisesinc.com +Erick,Ferencz,Cindy Turner Associates,20 S Babcock St,Fairbanks,Fairbanks North Star,AK,99712,907-741-1044,907-227-6777,erick.ferencz@aol.com,http://www.cindyturnerassociates.com +Fatima,Saylors,"Stanton, James D Esq",2 Lighthouse Ave,Hopkins,Hennepin,MN,55343,952-768-2416,952-479-2375,fsaylors@saylors.org,http://www.stantonjamesdesq.com +Jina,Briddick,Grace Pastries Inc,38938 Park Blvd,Boston,Suffolk,MA,2128,617-399-5124,617-997-5771,jina_briddick@briddick.com,http://www.gracepastriesinc.com +Kanisha,Waycott,"Schroer, Gene E Esq",5 Tomahawk Dr,Los Angeles,Los Angeles,CA,90006,323-453-2780,323-315-7314,kanisha_waycott@yahoo.com,http://www.schroergeneeesq.com +Emerson,Bowley,Knights Inn,762 S Main St,Madison,Dane,WI,53711,608-336-7444,608-658-7940,emerson.bowley@bowley.org,http://www.knightsinn.com +Blair,Malet,Bollinger Mach Shp & Shipyard,209 Decker Dr,Philadelphia,Philadelphia,PA,19132,215-907-9111,215-794-4519,bmalet@yahoo.com,http://www.bollingermachshpshipyard.com +Brock,Bolognia,Orinda News,4486 W O St #1,New York,New York,NY,10003,212-402-9216,212-617-5063,bbolognia@yahoo.com,http://www.orindanews.com +Lorrie,Nestle,Ballard Spahr Andrews,39 S 7th St,Tullahoma,Coffee,TN,37388,931-875-6644,931-303-6041,lnestle@hotmail.com,http://www.ballardspahrandrews.com +Sabra,Uyetake,Lowy Limousine Service,98839 Hawthorne Blvd #6101,Columbia,Richland,SC,29201,803-925-5213,803-681-3678,sabra@uyetake.org,http://www.lowylimousineservice.com +Marjory,Mastella,Vicon Corporation,71 San Mateo Ave,Wayne,Delaware,PA,19087,610-814-5533,610-379-7125,mmastella@mastella.com,http://www.viconcorporation.com +Karl,Klonowski,"Rossi, Michael M",76 Brooks St #9,Flemington,Hunterdon,NJ,8822,908-877-6135,908-470-4661,karl_klonowski@yahoo.com,http://www.rossimichaelm.com +Tonette,Wenner,Northwest Publishing,4545 Courthouse Rd,Westbury,Nassau,NY,11590,516-968-6051,516-333-4861,twenner@aol.com,http://www.northwestpublishing.com +Amber,Monarrez,Branford Wire & Mfg Co,14288 Foster Ave #4121,Jenkintown,Montgomery,PA,19046,215-934-8655,215-329-6386,amber_monarrez@monarrez.org,http://www.branfordwiremfgco.com +Shenika,Seewald,East Coast Marketing,4 Otis St,Van Nuys,Los Angeles,CA,91405,818-423-4007,818-749-8650,shenika@gmail.com,http://www.eastcoastmarketing.com +Delmy,Ahle,Wye Technologies Inc,65895 S 16th St,Providence,Providence,RI,2909,401-458-2547,401-559-8961,delmy.ahle@hotmail.com,http://www.wyetechnologiesinc.com +Deeanna,Juhas,"Healy, George W Iv",14302 Pennsylvania Ave,Huntingdon Valley,Montgomery,PA,19006,215-211-9589,215-417-9563,deeanna_juhas@gmail.com,http://www.healygeorgewiv.com +Blondell,Pugh,Alpenlite Inc,201 Hawk Ct,Providence,Providence,RI,2904,401-960-8259,401-300-8122,bpugh@aol.com,http://www.alpenliteinc.com +Jamal,Vanausdal,"Hubbard, Bruce Esq",53075 Sw 152nd Ter #615,Monroe Township,Middlesex,NJ,8831,732-234-1546,732-904-2931,jamal@vanausdal.org,http://www.hubbardbruceesq.com +Cecily,Hollack,Arthur A Oliver & Son Inc,59 N Groesbeck Hwy,Austin,Travis,TX,78731,512-486-3817,512-861-3814,cecily@hollack.org,http://www.arthuraoliversoninc.com +Carmelina,Lindall,George Jessop Carter Jewelers,2664 Lewis Rd,Littleton,Douglas,CO,80126,303-724-7371,303-874-5160,carmelina_lindall@lindall.com,http://www.georgejessopcarterjewelers.com +Maurine,Yglesias,"Schultz, Thomas C Md",59 Shady Ln #53,Milwaukee,Milwaukee,WI,53214,414-748-1374,414-573-7719,maurine_yglesias@yglesias.com,http://www.schultzthomascmd.com +Tawna,Buvens,H H H Enterprises Inc,3305 Nabell Ave #679,New York,New York,NY,10009,212-674-9610,212-462-9157,tawna@gmail.com,http://www.hhhenterprisesinc.com +Penney,Weight,Hawaiian King Hotel,18 Fountain St,Anchorage,Anchorage,AK,99515,907-797-9628,907-873-2882,penney_weight@aol.com,http://www.hawaiiankinghotel.com +Elly,Morocco,Killion Industries,7 W 32nd St,Erie,Erie,PA,16502,814-393-5571,814-420-3553,elly_morocco@gmail.com,http://www.killionindustries.com +Ilene,Eroman,"Robinson, William J Esq",2853 S Central Expy,Glen Burnie,Anne Arundel,MD,21061,410-914-9018,410-937-4543,ilene.eroman@hotmail.com,http://www.robinsonwilliamjesq.com +Vallie,Mondella,Private Properties,74 W College St,Boise,Ada,ID,83707,208-862-5339,208-737-8439,vmondella@mondella.com,http://www.privateproperties.com +Kallie,Blackwood,Rowley Schlimgen Inc,701 S Harrison Rd,San Francisco,San Francisco,CA,94104,415-315-2761,415-604-7609,kallie.blackwood@gmail.com,http://www.rowleyschlimgeninc.com +Johnetta,Abdallah,Forging Specialties,1088 Pinehurst St,Chapel Hill,Orange,NC,27514,919-225-9345,919-715-3791,johnetta_abdallah@aol.com,http://www.forgingspecialties.com +Bobbye,Rhym,"Smits, Patricia Garity",30 W 80th St #1995,San Carlos,San Mateo,CA,94070,650-528-5783,650-811-9032,brhym@rhym.com,http://www.smitspatriciagarity.com +Micaela,Rhymes,H Lee Leonard Attorney At Law,20932 Hedley St,Concord,Contra Costa,CA,94520,925-647-3298,925-522-7798,micaela_rhymes@gmail.com,http://www.hleeleonardattorneyatlaw.com +Tamar,Hoogland,A K Construction Co,2737 Pistorio Rd #9230,London,Madison,OH,43140,740-343-8575,740-526-5410,tamar@hotmail.com,http://www.akconstructionco.com +Moon,Parlato,"Ambelang, Jessica M Md",74989 Brandon St,Wellsville,Allegany,NY,14895,585-866-8313,585-498-4278,moon@yahoo.com,http://www.ambelangjessicammd.com +Laurel,Reitler,Q A Service,6 Kains Ave,Baltimore,Baltimore City,MD,21215,410-520-4832,410-957-6903,laurel_reitler@reitler.com,http://www.qaservice.com +Delisa,Crupi,Wood & Whitacre Contractors,47565 W Grand Ave,Newark,Essex,NJ,7105,973-354-2040,973-847-9611,delisa.crupi@crupi.com,http://www.woodwhitacrecontractors.com +Viva,Toelkes,Mark Iv Press Ltd,4284 Dorigo Ln,Chicago,Cook,IL,60647,773-446-5569,773-352-3437,viva.toelkes@gmail.com,http://www.markivpressltd.com +Elza,Lipke,Museum Of Science & Industry,6794 Lake Dr E,Newark,Essex,NJ,7104,973-927-3447,973-796-3667,elza@yahoo.com,http://www.museumofscienceindustry.com +Devorah,Chickering,Garrison Ind,31 Douglas Blvd #950,Clovis,Curry,NM,88101,505-975-8559,505-950-1763,devorah@hotmail.com,http://www.garrisonind.com +Timothy,Mulqueen,Saronix Nymph Products,44 W 4th St,Staten Island,Richmond,NY,10309,718-332-6527,718-654-7063,timothy_mulqueen@mulqueen.org,http://www.saronixnymphproducts.com +Arlette,Honeywell,Smc Inc,11279 Loytan St,Jacksonville,Duval,FL,32254,904-775-4480,904-514-9918,ahoneywell@honeywell.com,http://www.smcinc.com +Dominque,Dickerson,E A I Electronic Assocs Inc,69 Marquette Ave,Hayward,Alameda,CA,94545,510-993-3758,510-901-7640,dominque.dickerson@dickerson.org,http://www.eaielectronicassocsinc.com +Lettie,Isenhower,"Conte, Christopher A Esq",70 W Main St,Beachwood,Cuyahoga,OH,44122,216-657-7668,216-733-8494,lettie_isenhower@yahoo.com,http://www.contechristopheraesq.com +Myra,Munns,Anker Law Office,461 Prospect Pl #316,Euless,Tarrant,TX,76040,817-914-7518,817-451-3518,mmunns@cox.net,http://www.ankerlawoffice.com +Stephaine,Barfield,Beutelschies & Company,47154 Whipple Ave Nw,Gardena,Los Angeles,CA,90247,310-774-7643,310-968-1219,stephaine@barfield.com,http://www.beutelschiescompany.com +Lai,Gato,"Fligg, Kenneth I Jr",37 Alabama Ave,Evanston,Cook,IL,60201,847-728-7286,847-957-4614,lai.gato@gato.org,http://www.fliggkennethijr.com +Stephen,Emigh,"Sharp, J Daniel Esq",3777 E Richmond St #900,Akron,Summit,OH,44302,330-537-5358,330-700-2312,stephen_emigh@hotmail.com,http://www.sharpjdanielesq.com +Tyra,Shields,"Assink, Anne H Esq",3 Fort Worth Ave,Philadelphia,Philadelphia,PA,19106,215-255-1641,215-228-8264,tshields@gmail.com,http://www.assinkannehesq.com +Tammara,Wardrip,Jewel My Shop Inc,4800 Black Horse Pike,Burlingame,San Mateo,CA,94010,650-803-1936,650-216-5075,twardrip@cox.net,http://www.jewelmyshopinc.com +Cory,Gibes,Chinese Translation Resources,83649 W Belmont Ave,San Gabriel,Los Angeles,CA,91776,626-572-1096,626-696-2777,cory.gibes@gmail.com,http://www.chinesetranslationresources.com +Danica,Bruschke,"Stevens, Charles T",840 15th Ave,Waco,McLennan,TX,76708,254-782-8569,254-205-1422,danica_bruschke@gmail.com,http://www.stevenscharlest.com +Wilda,Giguere,"Mclaughlin, Luther W Cpa",1747 Calle Amanecer #2,Anchorage,Anchorage,AK,99501,907-870-5536,907-914-9482,wilda@cox.net,http://www.mclaughlinlutherwcpa.com +Elvera,Benimadho,Tree Musketeers,99385 Charity St #840,San Jose,Santa Clara,CA,95110,408-703-8505,408-440-8447,elvera.benimadho@cox.net,http://www.treemusketeers.com +Carma,Vanheusen,Springfield Div Oh Edison Co,68556 Central Hwy,San Leandro,Alameda,CA,94577,510-503-7169,510-452-4835,carma@cox.net,http://www.springfielddivohedisonco.com +Malinda,Hochard,Logan Memorial Hospital,55 Riverside Ave,Indianapolis,Marion,IN,46202,317-722-5066,317-472-2412,malinda.hochard@yahoo.com,http://www.loganmemorialhospital.com +Natalie,Fern,"Kelly, Charles G Esq",7140 University Ave,Rock Springs,Sweetwater,WY,82901,307-704-8713,307-279-3793,natalie.fern@hotmail.com,http://www.kellycharlesgesq.com +Lisha,Centini,Industrial Paper Shredders Inc,64 5th Ave #1153,Mc Lean,Fairfax,VA,22102,703-235-3937,703-475-7568,lisha@centini.org,http://www.industrialpapershreddersinc.com +Arlene,Klusman,Beck Horizon Builders,3 Secor Rd,New Orleans,Orleans,LA,70112,504-710-5840,504-946-1807,arlene_klusman@gmail.com,http://www.beckhorizonbuilders.com +Alease,Buemi,Porto Cayo At Hawks Cay,4 Webbs Chapel Rd,Boulder,Boulder,CO,80303,303-301-4946,303-521-9860,alease@buemi.com,http://www.portocayoathawkscay.com +Louisa,Cronauer,Pacific Grove Museum Ntrl Hist,524 Louisiana Ave Nw,San Leandro,Alameda,CA,94577,510-828-7047,510-472-7758,louisa@cronauer.com,http://www.pacificgrovemuseumntrlhist.com +Angella,Cetta,Bender & Hatley Pc,185 Blackstone Bldge,Honolulu,Honolulu,HI,96817,808-892-7943,808-475-2310,angella.cetta@hotmail.com,http://www.benderhatleypc.com +Cyndy,Goldammer,Di Cristina J & Son,170 Wyoming Ave,Burnsville,Dakota,MN,55337,952-334-9408,952-938-9457,cgoldammer@cox.net,http://www.dicristinajson.com +Rosio,Cork,Green Goddess,4 10th St W,High Point,Guilford,NC,27263,336-243-5659,336-497-4407,rosio.cork@gmail.com,http://www.greengoddess.com +Celeste,Korando,American Arts & Graphics,7 W Pinhook Rd,Lynbrook,Nassau,NY,11563,516-509-2347,516-365-7266,ckorando@hotmail.com,http://www.americanartsgraphics.com +Twana,Felger,Opryland Hotel,1 Commerce Way,Portland,Washington,OR,97224,503-939-3153,503-909-7167,twana.felger@felger.org,http://www.oprylandhotel.com +Estrella,Samu,Marking Devices Pubg Co,64 Lakeview Ave,Beloit,Rock,WI,53511,608-976-7199,608-942-8836,estrella@aol.com,http://www.markingdevicespubgco.com +Donte,Kines,W Tc Industries Inc,3 Aspen St,Worcester,Worcester,MA,1602,508-429-8576,508-843-1426,dkines@hotmail.com,http://www.wtcindustriesinc.com +Tiffiny,Steffensmeier,Whitehall Robbins Labs Divsn,32860 Sierra Rd,Miami,Miami-Dade,FL,33133,305-385-9695,305-304-6573,tiffiny_steffensmeier@cox.net,http://www.whitehallrobbinslabsdivsn.com +Edna,Miceli,Sampler,555 Main St,Erie,Erie,PA,16502,814-460-2655,814-299-2877,emiceli@miceli.org,http://www.sampler.com +Sue,Kownacki,Juno Chefs Incorporated,2 Se 3rd Ave,Mesquite,Dallas,TX,75149,972-666-3413,972-742-4000,sue@aol.com,http://www.junochefsincorporated.com +Jesusa,Shin,"Carroccio, A Thomas Esq",2239 Shawnee Mission Pky,Tullahoma,Coffee,TN,37388,931-273-8709,931-739-1551,jshin@shin.com,http://www.carroccioathomasesq.com +Rolland,Francescon,"Stanley, Richard L Esq",2726 Charcot Ave,Paterson,Passaic,NJ,7501,973-649-2922,973-284-4048,rolland@cox.net,http://www.stanleyrichardlesq.com +Pamella,Schmierer,K Cs Cstm Mouldings Windows,5161 Dorsett Rd,Homestead,Miami-Dade,FL,33030,305-420-8970,305-575-8481,pamella.schmierer@schmierer.org,http://www.kcscstmmouldingswindows.com +Glory,Kulzer,Comfort Inn,55892 Jacksonville Rd,Owings Mills,Baltimore,MD,21117,410-224-9462,410-916-8015,gkulzer@kulzer.org,http://www.comfortinn.com +Shawna,Palaspas,"Windsor, James L Esq",5 N Cleveland Massillon Rd,Thousand Oaks,Ventura,CA,91362,805-275-3566,805-638-6617,shawna_palaspas@palaspas.org,http://www.windsorjameslesq.com +Brandon,Callaro,Jackson Shields Yeiser,7 Benton Dr,Honolulu,Honolulu,HI,96819,808-215-6832,808-240-5168,brandon_callaro@hotmail.com,http://www.jacksonshieldsyeiser.com +Scarlet,Cartan,"Box, J Calvin Esq",9390 S Howell Ave,Albany,Dougherty,GA,31701,229-735-3378,229-365-9658,scarlet.cartan@yahoo.com,http://www.boxjcalvinesq.com +Oretha,Menter,Custom Engineering Inc,8 County Center Dr #647,Boston,Suffolk,MA,2210,617-418-5043,617-697-6024,oretha_menter@yahoo.com,http://www.customengineeringinc.com +Ty,Smith,Bresler Eitel Framg Gllry Ltd,4646 Kaahumanu St,Hackensack,Bergen,NJ,7601,201-672-1553,201-995-3149,tsmith@aol.com,http://www.breslereitelframggllryltd.com +Xuan,Rochin,"Carol, Drake Sparks Esq",2 Monroe St,San Mateo,San Mateo,CA,94403,650-933-5072,650-247-2625,xuan@gmail.com,http://www.caroldrakesparksesq.com +Lindsey,Dilello,Biltmore Investors Bank,52777 Leaders Heights Rd,Ontario,San Bernardino,CA,91761,909-639-9887,909-589-1693,lindsey.dilello@hotmail.com,http://www.biltmoreinvestorsbank.com +Devora,Perez,Desco Equipment Corp,72868 Blackington Ave,Oakland,Alameda,CA,94606,510-955-3016,510-755-9274,devora_perez@perez.org,http://www.descoequipmentcorp.com +Herman,Demesa,Merlin Electric Co,9 Norristown Rd,Troy,Rensselaer,NY,12180,518-497-2940,518-931-7852,hdemesa@cox.net,http://www.merlinelectricco.com +Rory,Papasergi,Bailey Cntl Co Div Babcock,83 County Road 437 #8581,Clarks Summit,Lackawanna,PA,18411,570-867-7489,570-469-8401,rpapasergi@cox.net,http://www.baileycntlcodivbabcock.com +Talia,Riopelle,Ford Brothers Wholesale Inc,1 N Harlem Ave #9,Orange,Essex,NJ,7050,973-245-2133,973-818-9788,talia_riopelle@aol.com,http://www.fordbrotherswholesaleinc.com +Van,Shire,Cambridge Inn,90131 J St,Pittstown,Hunterdon,NJ,8867,908-409-2890,908-448-1209,van.shire@shire.com,http://www.cambridgeinn.com +Lucina,Lary,"Matricciani, Albert J Jr",8597 W National Ave,Cocoa,Brevard,FL,32922,321-749-4981,321-632-4668,lucina_lary@cox.net,http://www.matriccianialbertjjr.com +Bok,Isaacs,Nelson Hawaiian Ltd,6 Gilson St,Bronx,Bronx,NY,10468,718-809-3762,718-478-8568,bok.isaacs@aol.com,http://www.nelsonhawaiianltd.com +Rolande,Spickerman,Neland Travel Agency,65 W Maple Ave,Pearl City,Honolulu,HI,96782,808-315-3077,808-526-5863,rolande.spickerman@spickerman.com,http://www.nelandtravelagency.com +Howard,Paulas,"Asendorf, J Alan Esq",866 34th Ave,Denver,Denver,CO,80231,303-623-4241,303-692-3118,hpaulas@gmail.com,http://www.asendorfjalanesq.com +Kimbery,Madarang,"Silberman, Arthur L Esq",798 Lund Farm Way,Rockaway,Morris,NJ,7866,973-310-1634,973-225-6259,kimbery_madarang@cox.net,http://www.silbermanarthurlesq.com +Thurman,Manno,Honey Bee Breeding Genetics &,9387 Charcot Ave,Absecon,Atlantic,NJ,8201,609-524-3586,609-234-8376,thurman.manno@yahoo.com,http://www.honeybeebreedinggenetics.com +Becky,Mirafuentes,Wells Kravitz Schnitzer,30553 Washington Rd,Plainfield,Union,NJ,7062,908-877-8409,908-426-8272,becky.mirafuentes@mirafuentes.com,http://www.wellskravitzschnitzer.com +Beatriz,Corrington,Prohab Rehabilitation Servs,481 W Lemon St,Middleboro,Plymouth,MA,2346,508-584-4279,508-315-3867,beatriz@yahoo.com,http://www.prohabrehabilitationservs.com +Marti,Maybury,"Eldridge, Kristin K Esq",4 Warehouse Point Rd #7,Chicago,Cook,IL,60638,773-775-4522,773-539-1058,marti.maybury@yahoo.com,http://www.eldridgekristinkesq.com +Nieves,Gotter,"Vlahos, John J Esq",4940 Pulaski Park Dr,Portland,Multnomah,OR,97202,503-527-5274,503-455-3094,nieves_gotter@gmail.com,http://www.vlahosjohnjesq.com +Leatha,Hagele,Ninas Indian Grs & Videos,627 Walford Ave,Dallas,Dallas,TX,75227,214-339-1809,214-225-5850,lhagele@cox.net,http://www.ninasindiangrsvideos.com +Valentin,Klimek,"Schmid, Gayanne K Esq",137 Pioneer Way,Chicago,Cook,IL,60604,312-303-5453,312-512-2338,vklimek@klimek.org,http://www.schmidgayannekesq.com +Melissa,Wiklund,Moapa Valley Federal Credit Un,61 13 Stoneridge #835,Findlay,Hancock,OH,45840,419-939-3613,419-254-4591,melissa@cox.net,http://www.moapavalleyfederalcreditun.com +Sheridan,Zane,Kentucky Tennessee Clay Co,2409 Alabama Rd,Riverside,Riverside,CA,92501,951-645-3605,951-248-6822,sheridan.zane@zane.com,http://www.kentuckytennesseeclayco.com +Bulah,Padilla,Admiral Party Rentals & Sales,8927 Vandever Ave,Waco,McLennan,TX,76707,254-463-4368,254-816-8417,bulah_padilla@hotmail.com,http://www.admiralpartyrentalssales.com +Audra,Kohnert,"Nelson, Karolyn King Esq",134 Lewis Rd,Nashville,Davidson,TN,37211,615-406-7854,615-448-9249,audra@kohnert.com,http://www.nelsonkarolynkingesq.com +Daren,Weirather,Panasystems,9 N College Ave #3,Milwaukee,Milwaukee,WI,53216,414-959-2540,414-838-3151,dweirather@aol.com,http://www.panasystems.com +Fernanda,Jillson,"Shank, Edward L Esq",60480 Old Us Highway 51,Preston,Caroline,MD,21655,410-387-5260,410-724-6472,fjillson@aol.com,http://www.shankedwardlesq.com +Gearldine,Gellinger,Megibow & Edwards,4 Bloomfield Ave,Irving,Dallas,TX,75061,972-934-6914,972-821-7118,gearldine_gellinger@gellinger.com,http://www.megibowedwards.com +Chau,Kitzman,"Benoff, Edward Esq",429 Tiger Ln,Beverly Hills,Los Angeles,CA,90212,310-560-8022,310-969-7230,chau@gmail.com,http://www.benoffedwardesq.com +Theola,Frey,Woodbridge Free Public Library,54169 N Main St,Massapequa,Nassau,NY,11758,516-948-5768,516-357-3362,theola_frey@frey.com,http://www.woodbridgefreepubliclibrary.com +Cheryl,Haroldson,New York Life John Thune,92 Main St,Atlantic City,Atlantic,NJ,8401,609-518-7697,609-263-9243,cheryl@haroldson.org,http://www.newyorklifejohnthune.com +Laticia,Merced,Alinabal Inc,72 Mannix Dr,Cincinnati,Hamilton,OH,45203,513-508-7371,513-418-1566,lmerced@gmail.com,http://www.alinabalinc.com +Carissa,Batman,"Poletto, Kim David Esq",12270 Caton Center Dr,Eugene,Lane,OR,97401,541-326-4074,541-801-5717,carissa.batman@yahoo.com,http://www.polettokimdavidesq.com +Lezlie,Craghead,"Chang, Carolyn Esq",749 W 18th St #45,Smithfield,Johnston,NC,27577,919-533-3762,919-885-2453,lezlie.craghead@craghead.org,http://www.changcarolynesq.com +Ozell,Shealy,Silver Bros Inc,8 Industry Ln,New York,New York,NY,10002,212-332-8435,212-880-8865,oshealy@hotmail.com,http://www.silverbrosinc.com +Arminda,Parvis,Newtec Inc,1 Huntwood Ave,Phoenix,Maricopa,AZ,85017,602-906-9419,602-277-3025,arminda@parvis.com,http://www.newtecinc.com +Reita,Leto,Creative Business Systems,55262 N French Rd,Indianapolis,Marion,IN,46240,317-234-1135,317-787-5514,reita.leto@gmail.com,http://www.creativebusinesssystems.com +Yolando,Luczki,Dal Tile Corporation,422 E 21st St,Syracuse,Onondaga,NY,13214,315-304-4759,315-640-6357,yolando@cox.net,http://www.daltilecorporation.com +Lizette,Stem,Edward S Katz,501 N 19th Ave,Cherry Hill,Camden,NJ,8002,856-487-5412,856-702-3676,lizette.stem@aol.com,http://www.edwardskatz.com +Gregoria,Pawlowicz,Oh My Goodknits Inc,455 N Main Ave,Garden City,Nassau,NY,11530,516-212-1915,516-376-4230,gpawlowicz@yahoo.com,http://www.ohmygoodknitsinc.com +Carin,Deleo,"Redeker, Debbie",1844 Southern Blvd,Little Rock,Pulaski,AR,72202,501-308-1040,501-409-6072,cdeleo@deleo.com,http://www.redekerdebbie.com +Chantell,Maynerich,Desert Sands Motel,2023 Greg St,Saint Paul,Ramsey,MN,55101,651-591-2583,651-776-9688,chantell@yahoo.com,http://www.desertsandsmotel.com +Dierdre,Yum,Cummins Southern Plains Inc,63381 Jenks Ave,Philadelphia,Philadelphia,PA,19134,215-325-3042,215-346-4666,dyum@yahoo.com,http://www.cumminssouthernplainsinc.com +Larae,Gudroe,Lehigh Furn Divsn Lehigh,6651 Municipal Rd,Houma,Terrebonne,LA,70360,985-890-7262,985-261-5783,larae_gudroe@gmail.com,http://www.lehighfurndivsnlehigh.com +Latrice,Tolfree,United Van Lines Agent,81 Norris Ave #525,Ronkonkoma,Suffolk,NY,11779,631-957-7624,631-998-2102,latrice.tolfree@hotmail.com,http://www.unitedvanlinesagent.com +Kerry,Theodorov,Capitol Reporters,6916 W Main St,Sacramento,Sacramento,CA,95827,916-591-3277,916-770-7448,kerry.theodorov@gmail.com,http://www.capitolreporters.com +Dorthy,Hidvegi,Kwik Kopy Printing,9635 S Main St,Boise,Ada,ID,83704,208-649-2373,208-690-3315,dhidvegi@yahoo.com,http://www.kwikkopyprinting.com +Fannie,Lungren,Centro Inc,17 Us Highway 111,Round Rock,Williamson,TX,78664,512-587-5746,512-528-9933,fannie.lungren@yahoo.com,http://www.centroinc.com +Evangelina,Radde,"Campbell, Jan Esq",992 Civic Center Dr,Philadelphia,Philadelphia,PA,19123,215-964-3284,215-417-5612,evangelina@aol.com,http://www.campbelljanesq.com +Novella,Degroot,"Evans, C Kelly Esq",303 N Radcliffe St,Hilo,Hawaii,HI,96720,808-477-4775,808-746-1865,novella_degroot@degroot.org,http://www.evansckellyesq.com +Clay,Hoa,Scat Enterprises,73 Saint Ann St #86,Reno,Washoe,NV,89502,775-501-8109,775-848-9135,choa@hoa.org,http://www.scatenterprises.com +Jennifer,Fallick,"Nagle, Daniel J Esq",44 58th St,Wheeling,Cook,IL,60090,847-979-9545,847-800-3054,jfallick@yahoo.com,http://www.nagledanieljesq.com +Irma,Wolfgramm,Serendiquity Bed & Breakfast,9745 W Main St,Randolph,Morris,NJ,7869,973-545-7355,973-868-8660,irma.wolfgramm@hotmail.com,http://www.serendiquitybedbreakfast.com +Eun,Coody,Ray Carolyne Realty,84 Bloomfield Ave,Spartanburg,Spartanburg,SC,29301,864-256-3620,864-594-4578,eun@yahoo.com,http://www.raycarolynerealty.com +Sylvia,Cousey,"Berg, Charles E",287 Youngstown Warren Rd,Hampstead,Carroll,MD,21074,410-209-9545,410-863-8263,sylvia_cousey@cousey.org,http://www.bergcharlese.com +Nana,Wrinkles,"Ray, Milbern D",6 Van Buren St,Mount Vernon,Westchester,NY,10553,914-855-2115,914-796-3775,nana@aol.com,http://www.raymilbernd.com +Layla,Springe,Chadds Ford Winery,229 N Forty Driv,New York,New York,NY,10011,212-260-3151,212-253-7448,layla.springe@cox.net,http://www.chaddsfordwinery.com +Joesph,Degonia,A R Packaging,2887 Knowlton St #5435,Berkeley,Alameda,CA,94710,510-677-9785,510-942-5916,joesph_degonia@degonia.org,http://www.arpackaging.com +Annabelle,Boord,Corn Popper,523 Marquette Ave,Concord,Middlesex,MA,1742,978-697-6263,978-289-7717,annabelle.boord@cox.net,http://www.cornpopper.com +Stephaine,Vinning,Birite Foodservice Distr,3717 Hamann Industrial Pky,San Francisco,San Francisco,CA,94104,415-767-6596,415-712-9530,stephaine@cox.net,http://www.biritefoodservicedistr.com +Nelida,Sawchuk,Anchorage Museum Of Hist & Art,3 State Route 35 S,Paramus,Bergen,NJ,7652,201-971-1638,201-247-8925,nelida@gmail.com,http://www.anchoragemuseumofhistart.com +Marguerita,Hiatt,"Haber, George D Md",82 N Highway 67,Oakley,Contra Costa,CA,94561,925-634-7158,925-541-8521,marguerita.hiatt@gmail.com,http://www.habergeorgedmd.com +Carmela,Cookey,Royal Pontiac Olds Inc,9 Murfreesboro Rd,Chicago,Cook,IL,60623,773-494-4195,773-297-9391,ccookey@cookey.org,http://www.royalpontiacoldsinc.com +Junita,Brideau,Leonards Antiques Inc,6 S Broadway St,Cedar Grove,Essex,NJ,7009,973-943-3423,973-582-5469,jbrideau@aol.com,http://www.leonardsantiquesinc.com +Claribel,Varriano,Meca,6 Harry L Dr #6327,Perrysburg,Wood,OH,43551,419-544-4900,419-573-2033,claribel_varriano@cox.net,http://www.meca.com +Benton,Skursky,Nercon Engineering & Mfg Inc,47939 Porter Ave,Gardena,Los Angeles,CA,90248,310-579-2907,310-694-8466,benton.skursky@aol.com,http://www.nerconengineeringmfginc.com +Hillary,Skulski,Replica I,9 Wales Rd Ne #914,Homosassa,Citrus,FL,34448,352-242-2570,352-990-5946,hillary.skulski@aol.com,http://www.replicai.com +Merilyn,Bayless,20 20 Printing Inc,195 13n N,Santa Clara,Santa Clara,CA,95054,408-758-5015,408-346-2180,merilyn_bayless@cox.net,http://www.printinginc.com +Teri,Ennaco,Publishers Group West,99 Tank Farm Rd,Hazleton,Luzerne,PA,18201,570-889-5187,570-355-1665,tennaco@gmail.com,http://www.publishersgroupwest.com +Merlyn,Lawler,"Nischwitz, Jeffrey L Esq",4671 Alemany Blvd,Jersey City,Hudson,NJ,7304,201-588-7810,201-858-9960,merlyn_lawler@hotmail.com,http://www.nischwitzjeffreylesq.com +Georgene,Montezuma,Payne Blades & Wellborn Pa,98 University Dr,San Ramon,Contra Costa,CA,94583,925-615-5185,925-943-3449,gmontezuma@cox.net,http://www.paynebladeswellbornpa.com +Jettie,Mconnell,Coldwell Bnkr Wright Real Est,50 E Wacker Dr,Bridgewater,Somerset,NJ,8807,908-802-3564,908-602-5258,jmconnell@hotmail.com,http://www.coldwellbnkrwrightrealest.com +Lemuel,Latzke,Computer Repair Service,70 Euclid Ave #722,Bohemia,Suffolk,NY,11716,631-748-6479,631-291-4976,lemuel.latzke@gmail.com,http://www.computerrepairservice.com +Melodie,Knipp,Fleetwood Building Block Inc,326 E Main St #6496,Thousand Oaks,Ventura,CA,91362,805-690-1682,805-810-8964,mknipp@gmail.com,http://www.fleetwoodbuildingblockinc.com +Candida,Corbley,Colts Neck Medical Assocs Inc,406 Main St,Somerville,Somerset,NJ,8876,908-275-8357,908-943-6103,candida_corbley@hotmail.com,http://www.coltsneckmedicalassocsinc.com +Karan,Karpin,New England Taxidermy,3 Elmwood Dr,Beaverton,Washington,OR,97005,503-940-8327,503-707-5812,karan_karpin@gmail.com,http://www.newenglandtaxidermy.com +Andra,Scheyer,"Ludcke, George O Esq",9 Church St,Salem,Marion,OR,97302,503-516-2189,503-950-3068,andra@gmail.com,http://www.ludckegeorgeoesq.com +Felicidad,Poullion,"Mccorkle, Tom S Esq",9939 N 14th St,Riverton,Burlington,NJ,8077,856-305-9731,856-828-6021,fpoullion@poullion.com,http://www.mccorkletomsesq.com +Belen,Strassner,Eagle Software Inc,5384 Southwyck Blvd,Douglasville,Douglas,GA,30135,770-507-8791,770-802-4003,belen_strassner@aol.com,http://www.eaglesoftwareinc.com +Gracia,Melnyk,Juvenile & Adult Super,97 Airport Loop Dr,Jacksonville,Duval,FL,32216,904-235-3633,904-627-4341,gracia@melnyk.com,http://www.juvenileadultsuper.com +Jolanda,Hanafan,"Perez, Joseph J Esq",37855 Nolan Rd,Bangor,Penobscot,ME,4401,207-458-9196,207-233-6185,jhanafan@gmail.com,http://www.perezjosephjesq.com +Barrett,Toyama,Case Foundation Co,4252 N Washington Ave #9,Kennedale,Tarrant,TX,76060,817-765-5781,817-577-6151,barrett.toyama@toyama.org,http://www.casefoundationco.com +Helga,Fredicks,Eis Environmental Engrs Inc,42754 S Ash Ave,Buffalo,Erie,NY,14228,716-752-4114,716-854-9845,helga_fredicks@yahoo.com,http://www.eisenvironmentalengrsinc.com +Ashlyn,Pinilla,Art Crafters,703 Beville Rd,Opa Locka,Miami-Dade,FL,33054,305-670-9628,305-857-5489,apinilla@cox.net,http://www.artcrafters.com +Fausto,Agramonte,Marriott Hotels Resorts Suites,5 Harrison Rd,New York,New York,NY,10038,212-313-1783,212-778-3063,fausto_agramonte@yahoo.com,http://www.marriotthotelsresortssuites.com +Ronny,Caiafa,Remaco Inc,73 Southern Blvd,Philadelphia,Philadelphia,PA,19103,215-605-7570,215-511-3531,ronny.caiafa@caiafa.org,http://www.remacoinc.com +Marge,Limmel,"Bjork, Robert D Jr",189 Village Park Rd,Crestview,Okaloosa,FL,32536,850-430-1663,850-330-8079,marge@gmail.com,http://www.bjorkrobertdjr.com +Norah,Waymire,"Carmichael, Jeffery L Esq",6 Middlegate Rd #106,San Francisco,San Francisco,CA,94107,415-306-7897,415-874-2984,norah.waymire@gmail.com,http://www.carmichaeljefferylesq.com +Aliza,Baltimore,"Andrews, J Robert Esq",1128 Delaware St,San Jose,Santa Clara,CA,95132,408-504-3552,408-425-1994,aliza@aol.com,http://www.andrewsjrobertesq.com +Mozell,Pelkowski,Winship & Byrne,577 Parade St,South San Francisco,San Mateo,CA,94080,650-947-1215,650-960-1069,mpelkowski@pelkowski.org,http://www.winshipbyrne.com +Viola,Bitsuie,Burton & Davis,70 Mechanic St,Northridge,Los Angeles,CA,91325,818-864-4875,818-481-5787,viola@gmail.com,http://www.burtondavis.com +Franklyn,Emard,Olympic Graphic Arts,4379 Highway 116,Philadelphia,Philadelphia,PA,19103,215-558-8189,215-483-3003,femard@emard.com,http://www.olympicgraphicarts.com +Willodean,Konopacki,Magnuson,55 Hawthorne Blvd,Lafayette,Lafayette,LA,70506,337-253-8384,337-774-7564,willodean_konopacki@konopacki.org,http://www.magnuson.com +Beckie,Silvestrini,A All American Travel Inc,7116 Western Ave,Dearborn,Wayne,MI,48126,313-533-4884,313-390-7855,beckie.silvestrini@silvestrini.com,http://www.aallamericantravelinc.com +Rebecka,Gesick,Polykote Inc,2026 N Plankinton Ave #3,Austin,Travis,TX,78754,512-213-8574,512-693-8345,rgesick@gesick.org,http://www.polykoteinc.com +Frederica,Blunk,Jets Cybernetics,99586 Main St,Dallas,Dallas,TX,75207,214-428-2285,214-529-1949,frederica_blunk@gmail.com,http://www.jetscybernetics.com +Glen,Bartolet,Metlab Testing Services,8739 Hudson St,Vashon,King,WA,98070,206-697-5796,206-389-1482,glen_bartolet@hotmail.com,http://www.metlabtestingservices.com +Freeman,Gochal,"Kellermann, William T Esq",383 Gunderman Rd #197,Coatesville,Chester,PA,19320,610-476-3501,610-752-2683,freeman_gochal@aol.com,http://www.kellermannwilliamtesq.com +Vincent,Meinerding,"Arturi, Peter D Esq",4441 Point Term Mkt,Philadelphia,Philadelphia,PA,19143,215-372-1718,215-829-4221,vincent.meinerding@hotmail.com,http://www.arturipeterdesq.com +Rima,Bevelacqua,Mcauley Mfg Co,2972 Lafayette Ave,Gardena,Los Angeles,CA,90248,310-858-5079,310-499-4200,rima@cox.net,http://www.mcauleymfgco.com +Glendora,Sarbacher,Defur Voran Hanley Radcliff,2140 Diamond Blvd,Rohnert Park,Sonoma,CA,94928,707-653-8214,707-881-3154,gsarbacher@gmail.com,http://www.defurvoranhanleyradcliff.com +Avery,Steier,Dill Dill Carr & Stonbraker Pc,93 Redmond Rd #492,Orlando,Orange,FL,32803,407-808-9439,407-945-8566,avery@cox.net,http://www.dilldillcarrstonbrakerpc.com +Cristy,Lother,Kleensteel,3989 Portage Tr,Escondido,San Diego,CA,92025,760-971-4322,760-465-4762,cristy@lother.com,http://www.kleensteel.com +Nicolette,Brossart,Goulds Pumps Inc Slurry Pump,1 Midway Rd,Westborough,Worcester,MA,1581,508-837-9230,508-504-6388,nicolette_brossart@brossart.com,http://www.gouldspumpsincslurrypump.com +Tracey,Modzelewski,Kansas City Insurance Report,77132 Coon Rapids Blvd Nw,Conroe,Montgomery,TX,77301,936-264-9294,936-988-8171,tracey@hotmail.com,http://www.kansascityinsurancereport.com +Virgina,Tegarden,Berhanu International Foods,755 Harbor Way,Milwaukee,Milwaukee,WI,53226,414-214-8697,414-411-5744,virgina_tegarden@tegarden.com,http://www.berhanuinternationalfoods.com +Tiera,Frankel,Roland Ashcroft,87 Sierra Rd,El Monte,Los Angeles,CA,91731,626-636-4117,626-638-4241,tfrankel@aol.com,http://www.rolandashcroft.com +Alaine,Bergesen,Hispanic Magazine,7667 S Hulen St #42,Yonkers,Westchester,NY,10701,914-300-9193,914-654-1426,alaine_bergesen@cox.net,http://www.hispanicmagazine.com +Earleen,Mai,Little Sheet Metal Co,75684 S Withlapopka Dr #32,Dallas,Dallas,TX,75227,214-289-1973,214-785-6750,earleen_mai@cox.net,http://www.littlesheetmetalco.com +Leonida,Gobern,"Holmes, Armstead J Esq",5 Elmwood Park Blvd,Biloxi,Harrison,MS,39530,228-235-5615,228-432-4635,leonida@gobern.org,http://www.holmesarmsteadjesq.com +Ressie,Auffrey,"Faw, James C Cpa",23 Palo Alto Sq,Miami,Miami-Dade,FL,33134,305-604-8981,305-287-4743,ressie.auffrey@yahoo.com,http://www.fawjamesccpa.com +Justine,Mugnolo,Evans Rule Company,38062 E Main St,New York,New York,NY,10048,212-304-9225,212-311-6377,jmugnolo@yahoo.com,http://www.evansrulecompany.com +Eladia,Saulter,Tyee Productions Inc,3958 S Dupont Hwy #7,Ramsey,Bergen,NJ,7446,201-474-4924,201-365-8698,eladia@saulter.com,http://www.tyeeproductionsinc.com +Chaya,Malvin,Dunnells & Duvall,560 Civic Center Dr,Ann Arbor,Washtenaw,MI,48103,734-928-5182,734-408-8174,chaya@malvin.com,http://www.dunnellsduvall.com +Gwenn,Suffield,Deltam Systems Inc,3270 Dequindre Rd,Deer Park,Suffolk,NY,11729,631-258-6558,631-295-9879,gwenn_suffield@suffield.org,http://www.deltamsystemsinc.com +Salena,Karpel,Hammill Mfg Co,1 Garfield Ave #7,Canton,Stark,OH,44707,330-791-8557,330-618-2579,skarpel@cox.net,http://www.hammillmfgco.com +Yoko,Fishburne,Sams Corner Store,9122 Carpenter Ave,New Haven,New Haven,CT,6511,203-506-4706,203-840-8634,yoko@fishburne.com,http://www.samscornerstore.com +Taryn,Moyd,"Siskin, Mark J Esq",48 Lenox St,Fairfax,Fairfax City,VA,22030,703-322-4041,703-938-7939,taryn.moyd@hotmail.com,http://www.siskinmarkjesq.com +Katina,Polidori,Cape & Associates Real Estate,5 Little River Tpke,Wilmington,Middlesex,MA,1887,978-626-2978,978-679-7429,katina_polidori@aol.com,http://www.capeassociatesrealestate.com +Rickie,Plumer,Merrill Lynch,3 N Groesbeck Hwy,Toledo,Lucas,OH,43613,419-693-1334,419-313-5571,rickie.plumer@aol.com,http://www.merrilllynch.com +Alex,Loader,"Sublett, Scott Esq",37 N Elm St #916,Tacoma,Pierce,WA,98409,253-660-7821,253-875-9222,alex@loader.com,http://www.sublettscottesq.com +Lashon,Vizarro,Sentry Signs,433 Westminster Blvd #590,Roseville,Placer,CA,95661,916-741-7884,916-289-4526,lashon@aol.com,http://www.sentrysigns.com +Lauran,Burnard,Professionals Unlimited,66697 Park Pl #3224,Riverton,Fremont,WY,82501,307-342-7795,307-453-7589,lburnard@burnard.com,http://www.professionalsunlimited.com +Ceola,Setter,Southern Steel Shelving Co,96263 Greenwood Pl,Warren,Knox,ME,4864,207-627-7565,207-297-5029,ceola.setter@setter.org,http://www.southernsteelshelvingco.com +My,Rantanen,"Bosco, Paul J",8 Mcarthur Ln,Richboro,Bucks,PA,18954,215-491-5633,215-647-2158,my@hotmail.com,http://www.boscopaulj.com +Lorrine,Worlds,"Longo, Nicholas J Esq",8 Fair Lawn Ave,Tampa,Hillsborough,FL,33614,813-769-2939,813-863-6467,lorrine.worlds@worlds.com,http://www.longonicholasjesq.com +Peggie,Sturiale,Henry County Middle School,9 N 14th St,El Cajon,San Diego,CA,92020,619-608-1763,619-695-8086,peggie@cox.net,http://www.henrycountymiddleschool.com +Marvel,Raymo,Edison Supply & Equipment Co,9 Vanowen St,College Station,Brazos,TX,77840,979-718-8968,979-809-5770,mraymo@yahoo.com,http://www.edisonsupplyequipmentco.com +Daron,Dinos,"Wolf, Warren R Esq",18 Waterloo Geneva Rd,Highland Park,Lake,IL,60035,847-233-3075,847-265-6609,daron_dinos@cox.net,http://www.wolfwarrenresq.com +An,Fritz,Linguistic Systems Inc,506 S Hacienda Dr,Atlantic City,Atlantic,NJ,8401,609-228-5265,609-854-7156,an_fritz@hotmail.com,http://www.linguisticsystemsinc.com +Portia,Stimmel,Peace Christian Center,3732 Sherman Ave,Bridgewater,Somerset,NJ,8807,908-722-7128,908-670-4712,portia.stimmel@aol.com,http://www.peacechristiancenter.com +Rhea,Aredondo,Double B Foods Inc,25657 Live Oak St,Brooklyn,Kings,NY,11226,718-560-9537,718-280-4183,rhea_aredondo@cox.net,http://www.doublebfoodsinc.com +Benedict,Sama,Alexander & Alexander Inc,4923 Carey Ave,Saint Louis,Saint Louis City,MO,63104,314-787-1588,314-858-4832,bsama@cox.net,http://www.alexanderalexanderinc.com +Alyce,Arias,Fairbanks Scales,3196 S Rider Trl,Stockton,San Joaquin,CA,95207,209-317-1801,209-242-7022,alyce@arias.org,http://www.fairbanksscales.com +Heike,Berganza,Cali Sportswear Cutting Dept,3 Railway Ave #75,Little Falls,Passaic,NJ,7424,973-936-5095,973-822-8827,heike@gmail.com,http://www.calisportswearcuttingdept.com +Carey,Dopico,"Garofani, John Esq",87393 E Highland Rd,Indianapolis,Marion,IN,46220,317-578-2453,317-441-5848,carey_dopico@dopico.org,http://www.garofanijohnesq.com +Dottie,Hellickson,Thompson Fabricating Co,67 E Chestnut Hill Rd,Seattle,King,WA,98133,206-540-6076,206-295-5631,dottie@hellickson.org,http://www.thompsonfabricatingco.com +Deandrea,Hughey,Century 21 Krall Real Estate,33 Lewis Rd #46,Burlington,Alamance,NC,27215,336-822-7652,336-467-3095,deandrea@yahoo.com,http://www.centurykrallrealestate.com +Kimberlie,Duenas,Mid Contntl Rlty & Prop Mgmt,8100 Jacksonville Rd #7,Hays,Ellis,KS,67601,785-629-8542,785-616-1685,kimberlie_duenas@yahoo.com,http://www.midcontntlrltypropmgmt.com +Martina,Staback,Ace Signs Inc,7 W Wabansia Ave #227,Orlando,Orange,FL,32822,407-471-6908,407-429-2145,martina_staback@staback.com,http://www.acesignsinc.com +Skye,Fillingim,Rodeway Inn,25 Minters Chapel Rd #9,Minneapolis,Hennepin,MN,55401,612-508-2655,612-664-6304,skye_fillingim@yahoo.com,http://www.rodewayinn.com +Jade,Farrar,Bonnet & Daughter,6882 Torresdale Ave,Columbia,Richland,SC,29201,803-352-5387,803-975-3405,jade.farrar@yahoo.com,http://www.bonnetdaughter.com +Charlene,Hamilton,Oshins & Gibbons,985 E 6th Ave,Santa Rosa,Sonoma,CA,95407,707-300-1771,707-821-8037,charlene.hamilton@hotmail.com,http://www.oshinsgibbons.com +Geoffrey,Acey,Price Business Services,7 West Ave #1,Palatine,Cook,IL,60067,847-222-1734,847-556-2909,geoffrey@gmail.com,http://www.pricebusinessservices.com +Stevie,Westerbeck,"Wise, Dennis W Md",26659 N 13th St,Costa Mesa,Orange,CA,92626,949-867-4077,949-903-3898,stevie.westerbeck@yahoo.com,http://www.wisedenniswmd.com +Pamella,Fortino,Super 8 Motel,669 Packerland Dr #1438,Denver,Denver,CO,80212,303-404-2210,303-794-1341,pamella@fortino.com,http://www.supermotel.com +Harrison,Haufler,John Wagner Associates,759 Eldora St,New Haven,New Haven,CT,6515,203-801-6193,203-801-8497,hhaufler@hotmail.com,http://www.johnwagnerassociates.com +Johnna,Engelberg,Thrifty Oil Co,5 S Colorado Blvd #449,Bothell,Snohomish,WA,98021,425-986-7573,425-700-3751,jengelberg@engelberg.org,http://www.thriftyoilco.com +Buddy,Cloney,Larkfield Photo,944 Gaither Dr,Strongsville,Cuyahoga,OH,44136,440-989-5826,440-327-2093,buddy.cloney@yahoo.com,http://www.larkfieldphoto.com +Dalene,Riden,Silverman Planetarium,66552 Malone Rd,Plaistow,Rockingham,NH,3865,603-315-6839,603-745-7497,dalene.riden@aol.com,http://www.silvermanplanetarium.com +Jerry,Zurcher,J & F Lumber,77 Massillon Rd #822,Satellite Beach,Brevard,FL,32937,321-518-5938,321-597-2159,jzurcher@zurcher.org,http://www.jflumber.com +Haydee,Denooyer,Cleaning Station Inc,25346 New Rd,New York,New York,NY,10016,212-792-8658,212-782-3493,hdenooyer@denooyer.org,http://www.cleaningstationinc.com +Joseph,Cryer,Ames Stationers,60 Fillmore Ave,Huntington Beach,Orange,CA,92647,714-584-2237,714-698-2170,joseph_cryer@cox.net,http://www.amesstationers.com +Deonna,Kippley,Midas Muffler Shops,57 Haven Ave #90,Southfield,Oakland,MI,48075,248-913-4677,248-793-4966,deonna_kippley@hotmail.com,http://www.midasmufflershops.com +Raymon,Calvaresi,Seaboard Securities Inc,6538 E Pomona St #60,Indianapolis,Marion,IN,46222,317-825-4724,317-342-1532,raymon.calvaresi@gmail.com,http://www.seaboardsecuritiesinc.com +Alecia,Bubash,"Petersen, James E Esq",6535 Joyce St,Wichita Falls,Wichita,TX,76301,940-276-7922,940-302-3036,alecia@aol.com,http://www.petersenjameseesq.com +Ma,Layous,Development Authority,78112 Morris Ave,North Haven,New Haven,CT,6473,203-721-3388,203-564-1543,mlayous@hotmail.com,http://www.developmentauthority.com +Detra,Coyier,Schott Fiber Optics Inc,96950 Hidden Ln,Aberdeen,Harford,MD,21001,410-739-9277,410-259-2118,detra@aol.com,http://www.schottfiberopticsinc.com +Terrilyn,Rodeigues,Stuart J Agins,3718 S Main St,New Orleans,Orleans,LA,70130,504-463-4384,504-635-8518,terrilyn.rodeigues@cox.net,http://www.stuartjagins.com +Salome,Lacovara,Mitsumi Electronics Corp,9677 Commerce Dr,Richmond,Richmond City,VA,23219,804-550-5097,804-858-1011,slacovara@gmail.com,http://www.mitsumielectronicscorp.com +Garry,Keetch,Italian Express Franchise Corp,5 Green Pond Rd #4,Southampton,Bucks,PA,18966,215-979-8776,215-846-9046,garry_keetch@hotmail.com,http://www.italianexpressfranchisecorp.com +Matthew,Neither,American Council On Sci & Hlth,636 Commerce Dr #42,Shakopee,Scott,MN,55379,952-651-7597,952-906-4597,mneither@yahoo.com,http://www.americancouncilonscihlth.com +Theodora,Restrepo,"Kleri, Patricia S Esq",42744 Hamann Industrial Pky #82,Miami,Miami-Dade,FL,33136,305-936-8226,305-573-1085,theodora.restrepo@restrepo.com,http://www.kleripatriciasesq.com +Noah,Kalafatis,Twiggs Abrams Blanchard,1950 5th Ave,Milwaukee,Milwaukee,WI,53209,414-263-5287,414-660-9766,noah.kalafatis@aol.com,http://www.twiggsabramsblanchard.com +Carmen,Sweigard,Maui Research & Technology Pk,61304 N French Rd,Somerset,Somerset,NJ,8873,732-941-2621,732-445-6940,csweigard@sweigard.com,http://www.mauiresearchtechnologypk.com +Lavonda,Hengel,Bradley Nameplate Corp,87 Imperial Ct #79,Fargo,Cass,ND,58102,701-898-2154,701-421-7080,lavonda@cox.net,http://www.bradleynameplatecorp.com +Junita,Stoltzman,Geonex Martel Inc,94 W Dodge Rd,Carson City,Carson City,NV,89701,775-638-9963,775-578-1214,junita@aol.com,http://www.geonexmartelinc.com +Herminia,Nicolozakes,Sea Island Div Of Fstr Ind Inc,4 58th St #3519,Scottsdale,Maricopa,AZ,85254,602-954-5141,602-304-6433,herminia@nicolozakes.org,http://www.seaislanddivoffstrindinc.com +Casie,Good,"Papay, Debbie J Esq",5221 Bear Valley Rd,Nashville,Davidson,TN,37211,615-390-2251,615-825-4297,casie.good@aol.com,http://www.papaydebbiejesq.com +Reena,Maisto,Lane Promotions,9648 S Main,Salisbury,Wicomico,MD,21801,410-351-1863,410-951-2667,reena@hotmail.com,http://www.lanepromotions.com +Mirta,Mallett,Stephen Kennerly Archts Inc Pc,7 S San Marcos Rd,New York,New York,NY,10004,212-870-1286,212-745-6948,mirta_mallett@gmail.com,http://www.stephenkennerlyarchtsincpc.com +Cathrine,Pontoriero,Business Systems Of Wis Inc,812 S Haven St,Amarillo,Randall,TX,79109,806-703-1435,806-558-5848,cathrine.pontoriero@pontoriero.com,http://www.businesssystemsofwisinc.com +Filiberto,Tawil,"Flash, Elena Salerno Esq",3882 W Congress St #799,Los Angeles,Los Angeles,CA,90016,323-765-2528,323-842-8226,ftawil@hotmail.com,http://www.flashelenasalernoesq.com +Raul,Upthegrove,"Neeley, Gregory W Esq",4 E Colonial Dr,La Mesa,San Diego,CA,91942,619-509-5282,619-666-4765,rupthegrove@yahoo.com,http://www.neeleygregorywesq.com +Sarah,Candlish,Alabama Educational Tv Comm,45 2nd Ave #9759,Atlanta,Fulton,GA,30328,770-732-1194,770-531-2842,sarah.candlish@gmail.com,http://www.alabamaeducationaltvcomm.com +Lucy,Treston,Franz Inc,57254 Brickell Ave #372,Worcester,Worcester,MA,1602,508-769-5250,508-502-5634,lucy@cox.net,http://www.franzinc.com +Judy,Aquas,Plantation Restaurant,8977 Connecticut Ave Nw #3,Niles,Berrien,MI,49120,269-756-7222,269-431-9464,jaquas@aquas.com,http://www.plantationrestaurant.com +Yvonne,Tjepkema,Radio Communications Co,9 Waydell St,Fairfield,Essex,NJ,7004,973-714-1721,973-976-8627,yvonne.tjepkema@hotmail.com,http://www.radiocommunicationsco.com +Kayleigh,Lace,Dentalaw Divsn Hlth Care,43 Huey P Long Ave,Lafayette,Lafayette,LA,70508,337-740-9323,337-751-2326,kayleigh.lace@yahoo.com,http://www.dentalawdivsnhlthcare.com +Felix,Hirpara,American Speedy Printing Ctrs,7563 Cornwall Rd #4462,Denver,Lancaster,PA,17517,717-491-5643,717-583-1497,felix_hirpara@cox.net,http://www.americanspeedyprintingctrs.com +Tresa,Sweely,"Grayson, Grant S Esq",22 Bridle Ln,Valley Park,Saint Louis,MO,63088,314-359-9566,314-231-3514,tresa_sweely@hotmail.com,http://www.graysongrantsesq.com +Kristeen,Turinetti,Jeanerette Middle School,70099 E North Ave,Arlington,Tarrant,TX,76013,817-213-8851,817-947-9480,kristeen@gmail.com,http://www.jeanerettemiddleschool.com +Jenelle,Regusters,"Haavisto, Brian F Esq",3211 E Northeast Loop,Tampa,Hillsborough,FL,33619,813-932-8715,813-357-7296,jregusters@regusters.com,http://www.haavistobrianfesq.com +Renea,Monterrubio,Wmmt Radio Station,26 Montgomery St,Atlanta,Fulton,GA,30328,770-679-4752,770-930-9967,renea@hotmail.com,http://www.wmmtradiostation.com +Olive,Matuszak,Colony Paints Sales Ofc & Plnt,13252 Lighthouse Ave,Cathedral City,Riverside,CA,92234,760-938-6069,760-745-2649,olive@aol.com,http://www.colonypaintssalesofcplnt.com +Ligia,Reiber,Floral Expressions,206 Main St #2804,Lansing,Ingham,MI,48933,517-906-1108,517-747-7664,lreiber@cox.net,http://www.floralexpressions.com +Christiane,Eschberger,Casco Services Inc,96541 W Central Blvd,Phoenix,Maricopa,AZ,85034,602-390-4944,602-330-6894,christiane.eschberger@yahoo.com,http://www.cascoservicesinc.com +Goldie,Schirpke,"Reuter, Arthur C Jr",34 Saint George Ave #2,Bangor,Penobscot,ME,4401,207-295-7569,207-748-3722,goldie.schirpke@yahoo.com,http://www.reuterarthurcjr.com +Loreta,Timenez,"Kaminski, Katherine Andritsaki",47857 Coney Island Ave,Clinton,Prince Georges,MD,20735,301-696-6420,301-392-6698,loreta.timenez@hotmail.com,http://www.kaminskikatherineandritsaki.com +Fabiola,Hauenstein,Sidewinder Products Corp,8573 Lincoln Blvd,York,York,PA,17404,717-809-3119,717-344-2804,fabiola.hauenstein@hauenstein.org,http://www.sidewinderproductscorp.com +Amie,Perigo,General Foam Corporation,596 Santa Maria Ave #7913,Mesquite,Dallas,TX,75150,972-419-7946,972-898-1033,amie.perigo@yahoo.com,http://www.generalfoamcorporation.com +Raina,Brachle,Ikg Borden Divsn Harsco Corp,3829 Ventura Blvd,Butte,Silver Bow,MT,59701,406-318-1515,406-374-7752,raina.brachle@brachle.org,http://www.ikgbordendivsnharscocorp.com +Erinn,Canlas,Anchor Computer Inc,13 S Hacienda Dr,Livingston,Essex,NJ,7039,973-767-3008,973-563-9502,erinn.canlas@canlas.com,http://www.anchorcomputerinc.com +Cherry,Lietz,Sebring & Co,40 9th Ave Sw #91,Waterford,Oakland,MI,48329,248-980-6904,248-697-7722,cherry@lietz.com,http://www.sebringco.com +Kattie,Vonasek,H A C Farm Lines Co Optv Assoc,2845 Boulder Crescent St,Cleveland,Cuyahoga,OH,44103,216-923-3715,216-270-9653,kattie@vonasek.org,http://www.hacfarmlinescooptvassoc.com +Lilli,Scriven,"Hunter, John J Esq",33 State St,Abilene,Taylor,TX,79601,325-631-1560,325-667-7868,lilli@aol.com,http://www.hunterjohnjesq.com +Whitley,Tomasulo,Freehold Fence Co,2 S 15th St,Fort Worth,Tarrant,TX,76107,817-526-4408,817-819-7799,whitley.tomasulo@aol.com,http://www.freeholdfenceco.com +Barbra,Adkin,Binswanger,4 Kohler Memorial Dr,Brooklyn,Kings,NY,11230,718-201-3751,718-732-9475,badkin@hotmail.com,http://www.binswanger.com +Hermila,Thyberg,Chilton Malting Co,1 Rancho Del Mar Shopping C,Providence,Providence,RI,2903,401-893-4882,401-885-7681,hermila_thyberg@hotmail.com,http://www.chiltonmaltingco.com +Jesusita,Flister,"Schoen, Edward J Jr",3943 N Highland Ave,Lancaster,Lancaster,PA,17601,717-885-9118,717-686-7564,jesusita.flister@hotmail.com,http://www.schoenedwardjjr.com +Caitlin,Julia,"Helderman, Seymour Cpa",5 Williams St,Johnston,Providence,RI,2919,401-948-4982,401-552-9059,caitlin.julia@julia.org,http://www.heldermanseymourcpa.com +Roosevelt,Hoffis,"Denbrook, Myron",60 Old Dover Rd,Hialeah,Miami-Dade,FL,33014,305-622-4739,305-302-1135,roosevelt.hoffis@aol.com,http://www.denbrookmyron.com +Helaine,Halter,"Lippitt, Mike",8 Sheridan Rd,Jersey City,Hudson,NJ,7304,201-832-4168,201-412-3040,hhalter@yahoo.com,http://www.lippittmike.com +Lorean,Martabano,"Hiram, Hogg P Esq",85092 Southern Blvd,San Antonio,Bexar,TX,78204,210-856-4979,210-634-2447,lorean.martabano@hotmail.com,http://www.hiramhoggpesq.com +France,Buzick,In Travel Agency,64 Newman Springs Rd E,Brooklyn,Kings,NY,11219,718-478-8504,718-853-3740,france.buzick@yahoo.com,http://www.intravelagency.com +Justine,Ferrario,Newhart Foods Inc,48 Stratford Ave,Pomona,Los Angeles,CA,91768,909-993-3242,909-631-5703,jferrario@hotmail.com,http://www.newhartfoodsinc.com +Adelina,Nabours,Courtyard By Marriott,80 Pittsford Victor Rd #9,Cleveland,Cuyahoga,OH,44103,216-230-4892,216-937-5320,adelina_nabours@gmail.com,http://www.courtyardbymarriott.com +Derick,Dhamer,"Studer, Eugene A Esq",87163 N Main Ave,New York,New York,NY,10013,212-304-4515,212-225-9676,ddhamer@cox.net,http://www.studereugeneaesq.com +Jerry,Dallen,Seashore Supply Co Waretown,393 Lafayette Ave,Richmond,Richmond City,VA,23219,804-762-9576,804-808-9574,jerry.dallen@yahoo.com,http://www.seashoresupplycowaretown.com +Leota,Ragel,Mayar Silk Inc,99 5th Ave #33,Trion,Chattooga,GA,30753,706-221-4243,706-616-5131,leota.ragel@gmail.com,http://www.mayarsilkinc.com +Jutta,Amyot,National Medical Excess Corp,49 N Mays St,Broussard,Lafayette,LA,70518,337-515-1438,337-991-8070,jamyot@hotmail.com,http://www.nationalmedicalexcesscorp.com +Aja,Gehrett,Stero Company,993 Washington Ave,Nutley,Essex,NJ,7110,973-544-2677,973-986-4456,aja_gehrett@hotmail.com,http://www.sterocompany.com +Kirk,Herritt,"Hasting, H Duane Esq",88 15th Ave Ne,Vestal,Broome,NY,13850,607-407-3716,607-350-7690,kirk.herritt@aol.com,http://www.hastinghduaneesq.com +Leonora,Mauson,Insty Prints,3381 E 40th Ave,Passaic,Passaic,NJ,7055,973-412-2995,973-355-2120,leonora@yahoo.com,http://www.instyprints.com +Winfred,Brucato,Glenridge Manor Mobile Home Pk,201 Ridgewood Rd,Moscow,Latah,ID,83843,208-252-4552,208-793-4108,winfred_brucato@hotmail.com,http://www.glenridgemanormobilehomepk.com +Tarra,Nachor,Circuit Solution Inc,39 Moccasin Dr,San Francisco,San Francisco,CA,94104,415-411-1775,415-284-2730,tarra.nachor@cox.net,http://www.circuitsolutioninc.com +Corinne,Loder,Local Office,4 Carroll St,North Attleboro,Bristol,MA,2760,508-942-4186,508-618-7826,corinne@loder.org,http://www.localoffice.com +Dulce,Labreche,Lee Kilkelly Paulson & Kabaker,9581 E Arapahoe Rd,Rochester,Oakland,MI,48307,248-357-8718,248-811-5696,dulce_labreche@yahoo.com,http://www.leekilkellypaulsonkabaker.com +Kate,Keneipp,"Davis, Maxon R Esq",33 N Michigan Ave,Green Bay,Brown,WI,54301,920-353-6377,920-355-1610,kate_keneipp@yahoo.com,http://www.davismaxonresq.com +Kaitlyn,Ogg,"Garrison, Paul E Esq",2 S Biscayne Blvd,Baltimore,Baltimore City,MD,21230,410-665-4903,410-773-3862,kaitlyn.ogg@gmail.com,http://www.garrisonpauleesq.com +Sherita,Saras,Black History Resource Center,8 Us Highway 22,Colorado Springs,El Paso,CO,80937,719-669-1664,719-547-9543,sherita.saras@cox.net,http://www.blackhistoryresourcecenter.com +Lashawnda,Stuer,"Rodriguez, J Christopher Esq",7422 Martin Ave #8,Toledo,Lucas,OH,43607,419-588-8719,419-399-1744,lstuer@cox.net,http://www.rodriguezjchristopheresq.com +Ernest,Syrop,Grant Family Health Center,94 Chase Rd,Hyattsville,Prince Georges,MD,20785,301-998-9644,301-257-4883,ernest@cox.net,http://www.grantfamilyhealthcenter.com +Nobuko,Halsey,Goeman Wood Products Inc,8139 I Hwy 10 #92,New Bedford,Bristol,MA,2745,508-855-9887,508-897-7916,nobuko.halsey@yahoo.com,http://www.goemanwoodproductsinc.com +Lavonna,Wolny,"Linhares, Kenneth A Esq",5 Cabot Rd,Mc Lean,Fairfax,VA,22102,703-483-1970,703-892-2914,lavonna.wolny@hotmail.com,http://www.linhareskennethaesq.com +Lashaunda,Lizama,Earnhardt Printing,3387 Ryan Dr,Hanover,Anne Arundel,MD,21076,410-678-2473,410-912-6032,llizama@cox.net,http://www.earnhardtprinting.com +Mariann,Bilden,H P G Industrys Inc,3125 Packer Ave #9851,Austin,Travis,TX,78753,512-223-4791,512-742-1149,mariann.bilden@aol.com,http://www.hpgindustrysinc.com +Helene,Rodenberger,Bailey Transportation Prod Inc,347 Chestnut St,Peoria,Maricopa,AZ,85381,623-461-8551,623-426-4907,helene@aol.com,http://www.baileytransportationprodinc.com +Roselle,Estell,Mcglynn Bliss Pc,8116 Mount Vernon Ave,Bucyrus,Crawford,OH,44820,419-571-5920,419-488-6648,roselle.estell@hotmail.com,http://www.mcglynnblisspc.com +Samira,Heintzman,Mutual Fish Co,8772 Old County Rd #5410,Kent,King,WA,98032,206-311-4137,206-923-6042,sheintzman@hotmail.com,http://www.mutualfishco.com +Margart,Meisel,"Yeates, Arthur L Aia",868 State St #38,Cincinnati,Hamilton,OH,45251,513-617-2362,513-747-9603,margart_meisel@yahoo.com,http://www.yeatesarthurlaia.com +Kristofer,Bennick,"Logan, Ronald J Esq",772 W River Dr,Bloomington,Monroe,IN,47404,812-368-1511,812-442-8544,kristofer.bennick@yahoo.com,http://www.loganronaldjesq.com +Weldon,Acuff,Advantage Martgage Company,73 W Barstow Ave,Arlington Heights,Cook,IL,60004,847-353-2156,847-613-5866,wacuff@gmail.com,http://www.advantagemartgagecompany.com +Shalon,Shadrick,Germer And Gertz Llp,61047 Mayfield Ave,Brooklyn,Kings,NY,11223,718-232-2337,718-394-4974,shalon@cox.net,http://www.germerandgertzllp.com +Denise,Patak,Spence Law Offices,2139 Santa Rosa Ave,Orlando,Orange,FL,32801,407-446-4358,407-808-3254,denise@patak.org,http://www.spencelawoffices.com +Louvenia,Beech,John Ortiz Nts Therapy Center,598 43rd St,Beverly Hills,Los Angeles,CA,90210,310-820-2117,310-652-2379,louvenia.beech@beech.com,http://www.johnortizntstherapycenter.com +Audry,Yaw,Mike Uchrin Htg & Air Cond Inc,70295 Pioneer Ct,Brandon,Hillsborough,FL,33511,813-797-4816,813-744-7100,audry.yaw@yaw.org,http://www.mikeuchrinhtgaircondinc.com +Kristel,Ehmann,"Mccoy, Joy Reynolds Esq",92899 Kalakaua Ave,El Paso,El Paso,TX,79925,915-452-1290,915-300-6100,kristel.ehmann@aol.com,http://www.mccoyjoyreynoldsesq.com +Vincenza,Zepp,Kbor 1600 Am,395 S 6th St #2,El Cajon,San Diego,CA,92020,619-603-5125,619-935-6661,vzepp@gmail.com,http://www.kboram.com +Elouise,Gwalthney,Quality Inn Northwest,9506 Edgemore Ave,Bladensburg,Prince Georges,MD,20710,301-841-5012,301-591-3034,egwalthney@yahoo.com,http://www.qualityinnnorthwest.com +Venita,Maillard,Wallace Church Assoc Inc,72119 S Walker Ave #63,Anaheim,Orange,CA,92801,714-523-6653,714-663-9740,venita_maillard@gmail.com,http://www.wallacechurchassocinc.com +Kasandra,Semidey,Can Tron,369 Latham St #500,Saint Louis,Saint Louis City,MO,63102,314-732-9131,314-697-3652,kasandra_semidey@semidey.com,http://www.cantron.com +Xochitl,Discipio,Ravaal Enterprises Inc,3158 Runamuck Pl,Round Rock,Williamson,TX,78664,512-233-1831,512-942-3411,xdiscipio@gmail.com,http://www.ravaalenterprisesinc.com +Maile,Linahan,Thompson Steel Company Inc,9 Plainsboro Rd #598,Greensboro,Guilford,NC,27409,336-670-2640,336-364-6037,mlinahan@yahoo.com,http://www.thompsonsteelcompanyinc.com +Krissy,Rauser,"Anderson, Mark A Esq",8728 S Broad St,Coram,Suffolk,NY,11727,631-443-4710,631-288-2866,krauser@cox.net,http://www.andersonmarkaesq.com +Pete,Dubaldi,Womack & Galich,2215 Prosperity Dr,Lyndhurst,Bergen,NJ,7071,201-825-2514,201-749-8866,pdubaldi@hotmail.com,http://www.womackgalich.com +Linn,Paa,Valerie & Company,1 S Pine St,Memphis,Shelby,TN,38112,901-412-4381,901-573-9024,linn_paa@paa.com,http://www.valeriecompany.com +Paris,Wide,Gehring Pumps Inc,187 Market St,Atlanta,Fulton,GA,30342,404-505-4445,404-607-8435,paris@hotmail.com,http://www.gehringpumpsinc.com +Wynell,Dorshorst,"Haehnel, Craig W Esq",94290 S Buchanan St,Pacifica,San Mateo,CA,94044,650-473-1262,650-749-9879,wynell_dorshorst@dorshorst.org,http://www.haehnelcraigwesq.com +Quentin,Birkner,Spoor Behrins Campbell & Young,7061 N 2nd St,Burnsville,Dakota,MN,55337,952-702-7993,952-314-5871,qbirkner@aol.com,http://www.spoorbehrinscampbellyoung.com +Regenia,Kannady,Ken Jeter Store Equipment Inc,10759 Main St,Scottsdale,Maricopa,AZ,85260,480-726-1280,480-205-5121,regenia.kannady@cox.net,http://www.kenjeterstoreequipmentinc.com +Sheron,Louissant,"Potter, Brenda J Cpa",97 E 3rd St #9,Long Island City,Queens,NY,11101,718-976-8610,718-613-9994,sheron@aol.com,http://www.potterbrendajcpa.com +Izetta,Funnell,Baird Kurtz & Dobson,82 Winsor St #54,Atlanta,Dekalb,GA,30340,770-844-3447,770-584-4119,izetta.funnell@hotmail.com,http://www.bairdkurtzdobson.com +Rodolfo,Butzen,"Minor, Cynthia A Esq",41 Steel Ct,Northfield,Rice,MN,55057,507-210-3510,507-590-5237,rodolfo@hotmail.com,http://www.minorcynthiaaesq.com +Zona,Colla,"Solove, Robert A Esq",49440 Dearborn St,Norwalk,Fairfield,CT,6854,203-461-1949,203-938-2557,zona@hotmail.com,http://www.soloverobertaesq.com +Serina,Zagen,Mark Ii Imports Inc,7 S Beverly Dr,Fort Wayne,Allen,IN,46802,260-273-3725,260-382-4869,szagen@aol.com,http://www.markiiimportsinc.com +Paz,Sahagun,White Sign Div Ctrl Equip Co,919 Wall Blvd,Meridian,Lauderdale,MS,39307,601-927-8287,601-249-4511,paz_sahagun@cox.net,http://www.whitesigndivctrlequipco.com +Markus,Lukasik,M & M Store Fixtures Co Inc,89 20th St E #779,Sterling Heights,Macomb,MI,48310,586-970-7380,586-247-1614,markus@yahoo.com,http://www.mmstorefixturescoinc.com +Jaclyn,Bachman,Judah Caster & Wheel Co,721 Interstate 45 S,Colorado Springs,El Paso,CO,80919,719-853-3600,719-223-2074,jaclyn@aol.com,http://www.judahcasterwheelco.com +Cyril,Daufeldt,Galaxy International Inc,3 Lawton St,New York,New York,NY,10013,212-745-8484,212-422-5427,cyril_daufeldt@daufeldt.com,http://www.galaxyinternationalinc.com +Gayla,Schnitzler,Sigma Corp Of America,38 Pleasant Hill Rd,Hayward,Alameda,CA,94545,510-686-3407,510-441-4055,gschnitzler@gmail.com,http://www.sigmacorpofamerica.com +Erick,Nievas,"Soward, Anne Esq",45 E Acacia Ct,Chicago,Cook,IL,60624,773-704-9903,773-359-6109,erick_nievas@aol.com,http://www.sowardanneesq.com +Jennie,Drymon,"Osborne, Michelle M Esq",63728 Poway Rd #1,Scranton,Lackawanna,PA,18509,570-218-4831,570-868-8688,jennie@cox.net,http://www.osbornemichellemesq.com +Mitsue,Scipione,Students In Free Entrprs Natl,77 222 Dr,Oroville,Butte,CA,95965,530-986-9272,530-399-3254,mscipione@scipione.com,http://www.studentsinfreeentrprsnatl.com +Ciara,Ventura,"Johnson, Robert M Esq",53 W Carey St,Port Jervis,Orange,NY,12771,845-823-8877,845-694-7919,cventura@yahoo.com,http://www.johnsonrobertmesq.com +Galen,Cantres,Del Charro Apartments,617 Nw 36th Ave,Brook Park,Cuyahoga,OH,44142,216-600-6111,216-871-6876,galen@yahoo.com,http://www.delcharroapartments.com +Truman,Feichtner,Legal Search Inc,539 Coldwater Canyon Ave,Bloomfield,Essex,NJ,7003,973-852-2736,973-473-5108,tfeichtner@yahoo.com,http://www.legalsearchinc.com +Gail,Kitty,Service Supply Co Inc,735 Crawford Dr,Anchorage,Anchorage,AK,99501,907-435-9166,907-770-3542,gail@kitty.com,http://www.servicesupplycoinc.com +Dalene,Schoeneck,"Sameshima, Douglas J Esq",910 Rahway Ave,Philadelphia,Philadelphia,PA,19102,215-268-1275,215-380-8820,dalene@schoeneck.org,http://www.sameshimadouglasjesq.com +Gertude,Witten,"Thompson, John Randolph Jr",7 Tarrytown Rd,Cincinnati,Hamilton,OH,45217,513-977-7043,513-863-9471,gertude.witten@gmail.com,http://www.thompsonjohnrandolphjr.com +Lizbeth,Kohl,E T Balancing Co Inc,35433 Blake St #588,Gardena,Los Angeles,CA,90248,310-699-1222,310-955-5788,lizbeth@yahoo.com,http://www.etbalancingcoinc.com +Glenn,Berray,"Griswold, John E Esq",29 Cherry St #7073,Des Moines,Polk,IA,50315,515-370-7348,515-372-1738,gberray@gmail.com,http://www.griswoldjohneesq.com +Lashandra,Klang,Acqua Group,810 N La Brea Ave,King of Prussia,Montgomery,PA,19406,610-809-1818,610-378-7332,lashandra@yahoo.com,http://www.acquagroup.com +Lenna,Newville,"Brooks, Morris J Jr",987 Main St,Raleigh,Wake,NC,27601,919-623-2524,919-254-5987,lnewville@newville.com,http://www.brooksmorrisjjr.com +Laurel,Pagliuca,Printing Images Corp,36 Enterprise St Se,Richland,Benton,WA,99352,509-695-5199,509-595-6485,laurel@yahoo.com,http://www.printingimagescorp.com +Mireya,Frerking,Roberts Supply Co Inc,8429 Miller Rd,Pelham,Westchester,NY,10803,914-868-5965,914-883-3061,mireya.frerking@hotmail.com,http://www.robertssupplycoinc.com +Annelle,Tagala,Vico Products Mfg Co,5 W 7th St,Parkville,Baltimore,MD,21234,410-757-1035,410-234-2267,annelle@yahoo.com,http://www.vicoproductsmfgco.com +Dean,Ketelsen,J M Custom Design Millwork,2 Flynn Rd,Hicksville,Nassau,NY,11801,516-847-4418,516-732-6649,dean_ketelsen@gmail.com,http://www.jmcustomdesignmillwork.com +Levi,Munis,Farrell & Johnson Office Equip,2094 Ne 36th Ave,Worcester,Worcester,MA,1603,508-456-4907,508-658-7802,levi.munis@gmail.com,http://www.farrelljohnsonofficeequip.com +Sylvie,Ryser,Millers Market & Deli,649 Tulane Ave,Tulsa,Tulsa,OK,74105,918-644-9555,918-565-1706,sylvie@aol.com,http://www.millersmarketdeli.com +Sharee,Maile,Holiday Inn Naperville,2094 Montour Blvd,Muskegon,Muskegon,MI,49442,231-467-9978,231-265-6940,sharee_maile@aol.com,http://www.holidayinnnaperville.com +Cordelia,Storment,"Burrows, Jon H Esq",393 Hammond Dr,Lafayette,Lafayette,LA,70506,337-566-6001,337-255-3427,cordelia_storment@aol.com,http://www.burrowsjonhesq.com +Mollie,Mcdoniel,Dock Seal Specialty,8590 Lake Lizzie Dr,Bowling Green,Wood,OH,43402,419-975-3182,419-417-4674,mollie_mcdoniel@yahoo.com,http://www.docksealspecialty.com +Brett,Mccullan,Five Star Limousines Of Tx Inc,87895 Concord Rd,La Mesa,San Diego,CA,91942,619-461-9984,619-727-3892,brett.mccullan@mccullan.com,http://www.fivestarlimousinesoftxinc.com +Teddy,Pedrozo,"Barkan, Neal J Esq",46314 Route 130,Bridgeport,Fairfield,CT,6610,203-892-3863,203-918-3939,teddy_pedrozo@aol.com,http://www.barkannealjesq.com +Tasia,Andreason,"Campbell, Robert A",4 Cowesett Ave,Kearny,Hudson,NJ,7032,201-920-9002,201-969-7063,tasia_andreason@yahoo.com,http://www.campbellroberta.com +Hubert,Walthall,"Dee, Deanna",95 Main Ave #2,Barberton,Summit,OH,44203,330-903-1345,330-566-8898,hubert@walthall.org,http://www.deedeanna.com +Arthur,Farrow,"Young, Timothy L Esq",28 S 7th St #2824,Englewood,Bergen,NJ,7631,201-238-5688,201-772-4377,arthur.farrow@yahoo.com,http://www.youngtimothylesq.com +Vilma,Berlanga,"Wells, D Fred Esq",79 S Howell Ave,Grand Rapids,Kent,MI,49546,616-737-3085,616-568-4113,vberlanga@berlanga.com,http://www.wellsdfredesq.com +Billye,Miro,"Gray, Francine H Esq",36 Lancaster Dr Se,Pearl,Rankin,MS,39208,601-567-5386,601-637-5479,billye_miro@cox.net,http://www.grayfrancinehesq.com +Glenna,Slayton,Toledo Iv Care,2759 Livingston Ave,Memphis,Shelby,TN,38118,901-640-9178,901-869-4314,glenna_slayton@cox.net,http://www.toledoivcare.com +Mitzie,Hudnall,Cangro Transmission Co,17 Jersey Ave,Englewood,Arapahoe,CO,80110,303-402-1940,303-997-7760,mitzie_hudnall@yahoo.com,http://www.cangrotransmissionco.com +Bernardine,Rodefer,Sat Poly Inc,2 W Grand Ave,Memphis,Shelby,TN,38112,901-901-4726,901-739-5892,bernardine_rodefer@yahoo.com,http://www.satpolyinc.com +Staci,Schmaltz,Midwest Contracting & Mfg Inc,18 Coronado Ave #563,Pasadena,Los Angeles,CA,91106,626-866-2339,626-293-7678,staci_schmaltz@aol.com,http://www.midwestcontractingmfginc.com +Nichelle,Meteer,Print Doctor,72 Beechwood Ter,Chicago,Cook,IL,60657,773-225-9985,773-857-2231,nichelle_meteer@meteer.com,http://www.printdoctor.com +Janine,Rhoden,Nordic Group Inc,92 Broadway,Astoria,Queens,NY,11103,718-228-5894,718-728-5051,jrhoden@yahoo.com,http://www.nordicgroupinc.com +Ettie,Hoopengardner,Jackson Millwork Co,39 Franklin Ave,Richland,Benton,WA,99352,509-755-5393,509-847-3352,ettie.hoopengardner@hotmail.com,http://www.jacksonmillworkco.com +Eden,Jayson,Harris Corporation,4 Iwaena St,Baltimore,Baltimore City,MD,21202,410-890-7866,410-429-4888,eden_jayson@yahoo.com,http://www.harriscorporation.com +Lynelle,Auber,United Cerebral Palsy Of Ne Pa,32820 Corkwood Rd,Newark,Essex,NJ,7104,973-860-8610,973-605-6492,lynelle_auber@gmail.com,http://www.unitedcerebralpalsyofnepa.com +Merissa,Tomblin,One Day Surgery Center Inc,34 Raritan Center Pky,Bellflower,Los Angeles,CA,90706,562-579-6900,562-719-7922,merissa.tomblin@gmail.com,http://www.onedaysurgerycenterinc.com +Golda,Kaniecki,Calaveras Prospect,6201 S Nevada Ave,Toms River,Ocean,NJ,8755,732-628-9909,732-617-5310,golda_kaniecki@yahoo.com,http://www.calaverasprospect.com +Catarina,Gleich,"Terk, Robert E Esq",78 Maryland Dr #146,Denville,Morris,NJ,7834,973-210-3994,973-491-8723,catarina_gleich@hotmail.com,http://www.terkroberteesq.com +Virgie,Kiel,"Cullen, Terrence P Esq",76598 Rd I 95 #1,Denver,Denver,CO,80216,303-776-7548,303-845-5408,vkiel@hotmail.com,http://www.cullenterrencepesq.com +Jolene,Ostolaza,Central Die Casting Mfg Co Inc,1610 14th St Nw,Newport News,Newport News City,VA,23608,757-682-7116,757-940-1741,jolene@yahoo.com,http://www.centraldiecastingmfgcoinc.com +Keneth,Borgman,Centerline Engineering,86350 Roszel Rd,Phoenix,Maricopa,AZ,85012,602-919-4211,602-442-3092,keneth@yahoo.com,http://www.centerlineengineering.com +Rikki,Nayar,Targan & Kievit Pa,1644 Clove Rd,Miami,Miami-Dade,FL,33155,305-968-9487,305-978-2069,rikki@nayar.com,http://www.targankievitpa.com +Elke,Sengbusch,Riley Riper Hollin & Colagreco,9 W Central Ave,Phoenix,Maricopa,AZ,85013,602-896-2993,602-575-3457,elke_sengbusch@yahoo.com,http://www.rileyriperhollincolagreco.com +Hoa,Sarao,"Kaplan, Joel S Esq",27846 Lafayette Ave,Oak Hill,Volusia,FL,32759,386-526-7800,386-599-7296,hoa@sarao.org,http://www.kaplanjoelsesq.com +Trinidad,Mcrae,Water Office,10276 Brooks St,San Francisco,San Francisco,CA,94105,415-331-9634,415-419-1597,trinidad_mcrae@yahoo.com,http://www.wateroffice.com +Mari,Lueckenbach,"Westbrooks, Nelson E Jr",1 Century Park E,San Diego,San Diego,CA,92110,858-793-9684,858-228-5683,mari_lueckenbach@yahoo.com,http://www.westbrooksnelsonejr.com +Selma,Husser,Armon Communications,9 State Highway 57 #22,Jersey City,Hudson,NJ,7306,201-991-8369,201-772-7699,selma.husser@cox.net,http://www.armoncommunications.com +Antione,Onofrio,Jacobs & Gerber Inc,4 S Washington Ave,San Bernardino,San Bernardino,CA,92410,909-430-7765,909-665-3223,aonofrio@onofrio.com,http://www.jacobsgerberinc.com +Luisa,Jurney,Forest Fire Laboratory,25 Se 176th Pl,Cambridge,Middlesex,MA,2138,617-365-2134,617-544-2541,ljurney@hotmail.com,http://www.forestfirelaboratory.com +Clorinda,Heimann,"Haughey, Charles Jr",105 Richmond Valley Rd,Escondido,San Diego,CA,92025,760-291-5497,760-261-4786,clorinda.heimann@hotmail.com,http://www.haugheycharlesjr.com +Dick,Wenzinger,Wheaton Plastic Products,22 Spruce St #595,Gardena,Los Angeles,CA,90248,310-510-9713,310-936-2258,dick@yahoo.com,http://www.wheatonplasticproducts.com +Ahmed,Angalich,Reese Plastics,2 W Beverly Blvd,Harrisburg,Dauphin,PA,17110,717-528-8996,717-632-5831,ahmed.angalich@angalich.com,http://www.reeseplastics.com +Iluminada,Ohms,Nazette Marner Good Wendt,72 Southern Blvd,Mesa,Maricopa,AZ,85204,480-293-2882,480-866-6544,iluminada.ohms@yahoo.com,http://www.nazettemarnergoodwendt.com +Joanna,Leinenbach,Levinson Axelrod Wheaton,1 Washington St,Lake Worth,Palm Beach,FL,33461,561-470-4574,561-951-9734,joanna_leinenbach@hotmail.com,http://www.levinsonaxelrodwheaton.com +Caprice,Suell,"Egnor, W Dan Esq",90177 N 55th Ave,Nashville,Davidson,TN,37211,615-246-1824,615-726-4537,caprice@aol.com,http://www.egnorwdanesq.com +Stephane,Myricks,Portland Central Thriftlodge,9 Tower Ave,Burlington,Boone,KY,41005,859-717-7638,859-308-4286,stephane_myricks@cox.net,http://www.portlandcentralthriftlodge.com +Quentin,Swayze,Ulbrich Trucking,278 Bayview Ave,Milan,Monroe,MI,48160,734-561-6170,734-851-8571,quentin_swayze@yahoo.com,http://www.ulbrichtrucking.com +Annmarie,Castros,Tipiak Inc,80312 W 32nd St,Conroe,Montgomery,TX,77301,936-751-7961,936-937-2334,annmarie_castros@gmail.com,http://www.tipiakinc.com +Shonda,Greenbush,Saint George Well Drilling,82 Us Highway 46,Clifton,Passaic,NJ,7011,973-482-2430,973-644-2974,shonda_greenbush@cox.net,http://www.saintgeorgewelldrilling.com +Cecil,Lapage,"Hawkes, Douglas D",4 Stovall St #72,Union City,Hudson,NJ,7087,201-693-3967,201-856-2720,clapage@lapage.com,http://www.hawkesdouglasd.com +Jeanice,Claucherty,Accurel Systems Intrntl Corp,19 Amboy Ave,Miami,Miami-Dade,FL,33142,305-988-4162,305-306-7834,jeanice.claucherty@yahoo.com,http://www.accurelsystemsintrntlcorp.com +Josphine,Villanueva,Santa Cruz Community Internet,63 Smith Ln #8343,Moss,Clay,TN,38575,931-553-9774,931-486-6946,josphine_villanueva@villanueva.com,http://www.santacruzcommunityinternet.com +Daniel,Perruzza,Gersh & Danielson,11360 S Halsted St,Santa Ana,Orange,CA,92705,714-771-3880,714-531-1391,dperruzza@perruzza.com,http://www.gershdanielson.com +Cassi,Wildfong,"Cobb, James O Esq",26849 Jefferson Hwy,Rolling Meadows,Cook,IL,60008,847-633-3216,847-755-9041,cassi.wildfong@aol.com,http://www.cobbjamesoesq.com +Britt,Galam,Wheatley Trucking Company,2500 Pringle Rd Se #508,Hatfield,Montgomery,PA,19440,215-888-3304,215-351-8523,britt@galam.org,http://www.wheatleytruckingcompany.com +Adell,Lipkin,Systems Graph Inc Ab Dick Dlr,65 Mountain View Dr,Whippany,Morris,NJ,7981,973-654-1561,973-662-8988,adell.lipkin@lipkin.com,http://www.systemsgraphincabdickdlr.com +Jacqueline,Rowling,John Hancock Mutl Life Ins Co,1 N San Saba,Erie,Erie,PA,16501,814-865-8113,814-481-1700,jacqueline.rowling@yahoo.com,http://www.johnhancockmutllifeinsco.com +Lonny,Weglarz,History Division Of State,51120 State Route 18,Salt Lake City,Salt Lake,UT,84115,801-293-9853,801-892-8781,lonny_weglarz@gmail.com,http://www.historydivisionofstate.com +Lonna,Diestel,"Dimmock, Thomas J Esq",1482 College Ave,Fayetteville,Cumberland,NC,28301,910-922-3672,910-200-7912,lonna_diestel@gmail.com,http://www.dimmockthomasjesq.com +Cristal,Samara,Intermed Inc,4119 Metropolitan Dr,Los Angeles,Los Angeles,CA,90021,213-975-8026,213-696-8004,cristal@cox.net,http://www.intermedinc.com +Kenneth,Grenet,Bank Of New York,2167 Sierra Rd,East Lansing,Ingham,MI,48823,517-499-2322,517-867-8077,kenneth.grenet@grenet.org,http://www.bankofnewyork.com +Elli,Mclaird,Sportmaster Intrnatl,6 Sunrise Ave,Utica,Oneida,NY,13501,315-818-2638,315-474-5570,emclaird@mclaird.com,http://www.sportmasterintrnatl.com +Alline,Jeanty,W W John Holden Inc,55713 Lake City Hwy,South Bend,St Joseph,IN,46601,574-656-2800,574-405-1983,ajeanty@gmail.com,http://www.wwjohnholdeninc.com +Sharika,Eanes,Maccani & Delp,75698 N Fiesta Blvd,Orlando,Orange,FL,32806,407-312-1691,407-472-1332,sharika.eanes@aol.com,http://www.maccanidelp.com +Nu,Mcnease,Amazonia Film Project,88 Sw 28th Ter,Harrison,Hudson,NJ,7029,973-751-9003,973-903-4175,nu@gmail.com,http://www.amazoniafilmproject.com +Daniela,Comnick,Water & Sewer Department,7 Flowers Rd #403,Trenton,Mercer,NJ,8611,609-200-8577,609-398-2805,dcomnick@cox.net,http://www.watersewerdepartment.com +Cecilia,Colaizzo,Switchcraft Inc,4 Nw 12th St #3849,Madison,Dane,WI,53717,608-382-4541,608-302-3387,cecilia_colaizzo@colaizzo.com,http://www.switchcraftinc.com +Leslie,Threets,C W D C Metal Fabricators,2 A Kelley Dr,Katonah,Westchester,NY,10536,914-861-9748,914-396-2615,leslie@cox.net,http://www.cwdcmetalfabricators.com +Nan,Koppinger,"Shimotani, Grace T",88827 Frankford Ave,Greensboro,Guilford,NC,27401,336-370-5333,336-564-1492,nan@koppinger.com,http://www.shimotanigracet.com +Izetta,Dewar,"Lisatoni, Jean Esq",2 W Scyene Rd #3,Baltimore,Baltimore City,MD,21217,410-473-1708,410-522-7621,idewar@dewar.com,http://www.lisatonijeanesq.com +Tegan,Arceo,Ceramic Tile Sales Inc,62260 Park Stre,Monroe Township,Middlesex,NJ,8831,732-730-2692,732-705-6719,tegan.arceo@arceo.org,http://www.ceramictilesalesinc.com +Ruthann,Keener,Maiden Craft Inc,3424 29th St Se,Kerrville,Kerr,TX,78028,830-258-2769,830-919-5991,ruthann@hotmail.com,http://www.maidencraftinc.com +Joni,Breland,Carriage House Cllsn Rpr Inc,35 E Main St #43,Elk Grove Village,Cook,IL,60007,847-519-5906,847-740-5304,joni_breland@cox.net,http://www.carriagehousecllsnrprinc.com +Vi,Rentfro,Video Workshop,7163 W Clark Rd,Freehold,Monmouth,NJ,7728,732-605-4781,732-724-7251,vrentfro@cox.net,http://www.videoworkshop.com +Colette,Kardas,Fresno Tile Center Inc,21575 S Apple Creek Rd,Omaha,Douglas,NE,68124,402-896-5943,402-707-1602,colette.kardas@yahoo.com,http://www.fresnotilecenterinc.com +Malcolm,Tromblay,Versatile Sash & Woodwork,747 Leonis Blvd,Annandale,Fairfax,VA,22003,703-221-5602,703-874-4248,malcolm_tromblay@cox.net,http://www.versatilesashwoodwork.com +Ryan,Harnos,Warner Electric Brk & Cltch Co,13 Gunnison St,Plano,Collin,TX,75075,972-558-1665,972-961-4968,ryan@cox.net,http://www.warnerelectricbrkcltchco.com +Jess,Chaffins,New York Public Library,18 3rd Ave,New York,New York,NY,10016,212-510-4633,212-428-9538,jess.chaffins@chaffins.org,http://www.newyorkpubliclibrary.com +Sharen,Bourbon,"Mccaleb, John A Esq",62 W Austin St,Syosset,Nassau,NY,11791,516-816-1541,516-749-3188,sbourbon@yahoo.com,http://www.mccalebjohnaesq.com +Nickolas,Juvera,United Oil Co Inc,177 S Rider Trl #52,Crystal River,Citrus,FL,34429,352-598-8301,352-947-6152,nickolas_juvera@cox.net,http://www.unitedoilcoinc.com +Gary,Nunlee,Irving Foot Center,2 W Mount Royal Ave,Fortville,Hancock,IN,46040,317-542-6023,317-887-8486,gary_nunlee@nunlee.org,http://www.irvingfootcenter.com +Diane,Devreese,Acme Supply Co,1953 Telegraph Rd,Saint Joseph,Buchanan,MO,64504,816-557-9673,816-329-5565,diane@cox.net,http://www.acmesupplyco.com +Roslyn,Chavous,"Mcrae, James L",63517 Dupont St,Jackson,Hinds,MS,39211,601-234-9632,601-973-5754,roslyn.chavous@chavous.org,http://www.mcraejamesl.com +Glory,Schieler,Mcgraths Seafood,5 E Truman Rd,Abilene,Taylor,TX,79602,325-869-2649,325-740-3778,glory@yahoo.com,http://www.mcgrathsseafood.com +Rasheeda,Sayaphon,"Kummerer, J Michael Esq",251 Park Ave #979,Saratoga,Santa Clara,CA,95070,408-805-4309,408-997-7490,rasheeda@aol.com,http://www.kummererjmichaelesq.com +Alpha,Palaia,"Stoffer, James M Jr",43496 Commercial Dr #29,Cherry Hill,Camden,NJ,8003,856-312-2629,856-513-7024,alpha@yahoo.com,http://www.stofferjamesmjr.com +Refugia,Jacobos,North Central Fl Sfty Cncl,2184 Worth St,Hayward,Alameda,CA,94545,510-974-8671,510-509-3496,refugia.jacobos@jacobos.com,http://www.northcentralflsftycncl.com +Shawnda,Yori,Fiorucci Foods Usa Inc,50126 N Plankinton Ave,Longwood,Seminole,FL,32750,407-538-5106,407-564-8113,shawnda.yori@yahoo.com,http://www.fioruccifoodsusainc.com +Mona,Delasancha,Sign All,38773 Gravois Ave,Cheyenne,Laramie,WY,82001,307-403-1488,307-816-7115,mdelasancha@hotmail.com,http://www.signall.com +Gilma,Liukko,Sammys Steak Den,16452 Greenwich St,Garden City,Nassau,NY,11530,516-393-9967,516-407-9573,gilma_liukko@gmail.com,http://www.sammyssteakden.com +Janey,Gabisi,"Dobscha, Stephen F Esq",40 Cambridge Ave,Madison,Dane,WI,53715,608-967-7194,608-586-6912,jgabisi@hotmail.com,http://www.dobschastephenfesq.com +Lili,Paskin,Morgan Custom Homes,20113 4th Ave E,Kearny,Hudson,NJ,7032,201-431-2989,201-478-8540,lili.paskin@cox.net,http://www.morgancustomhomes.com +Loren,Asar,Olsen Payne & Company,6 Ridgewood Center Dr,Old Forge,Lackawanna,PA,18518,570-648-3035,570-569-2356,loren.asar@aol.com,http://www.olsenpaynecompany.com +Dorothy,Chesterfield,Cowan & Kelly,469 Outwater Ln,San Diego,San Diego,CA,92126,858-617-7834,858-732-1884,dorothy@cox.net,http://www.cowankelly.com +Gail,Similton,"Johnson, Wes Esq",62 Monroe St,Thousand Palms,Riverside,CA,92276,760-616-5388,760-493-9208,gail_similton@similton.com,http://www.johnsonwesesq.com +Catalina,Tillotson,Icn Pharmaceuticals Inc,3338 A Lockport Pl #6,Margate City,Atlantic,NJ,8402,609-373-3332,609-826-4990,catalina@hotmail.com,http://www.icnpharmaceuticalsinc.com +Lawrence,Lorens,New England Sec Equip Co Inc,9 Hwy,Providence,Providence,RI,2906,401-465-6432,401-893-1820,lawrence.lorens@hotmail.com,http://www.newenglandsecequipcoinc.com +Carlee,Boulter,"Tippett, Troy M Ii",8284 Hart St,Abilene,Dickinson,KS,67410,785-347-1805,785-253-7049,carlee.boulter@hotmail.com,http://www.tippetttroymii.com +Thaddeus,Ankeny,Atc Contracting,5 Washington St #1,Roseville,Placer,CA,95678,916-920-3571,916-459-2433,tankeny@ankeny.org,http://www.atccontracting.com +Jovita,Oles,"Pagano, Philip G Esq",8 S Haven St,Daytona Beach,Volusia,FL,32114,386-248-4118,386-208-6976,joles@gmail.com,http://www.paganophilipgesq.com +Alesia,Hixenbaugh,Kwikprint,9 Front St,Washington,District of Columbia,DC,20001,202-646-7516,202-276-6826,alesia_hixenbaugh@hixenbaugh.org,http://www.kwikprint.com +Lai,Harabedian,Buergi & Madden Scale,1933 Packer Ave #2,Novato,Marin,CA,94945,415-423-3294,415-926-6089,lai@gmail.com,http://www.buergimaddenscale.com +Brittni,Gillaspie,Inner Label,67 Rv Cent,Boise,Ada,ID,83709,208-709-1235,208-206-9848,bgillaspie@gillaspie.com,http://www.innerlabel.com +Raylene,Kampa,Hermar Inc,2 Sw Nyberg Rd,Elkhart,Elkhart,IN,46514,574-499-1454,574-330-1884,rkampa@kampa.org,http://www.hermarinc.com +Flo,Bookamer,Simonton Howe & Schneider Pc,89992 E 15th St,Alliance,Box Butte,NE,69301,308-726-2182,308-250-6987,flo.bookamer@cox.net,http://www.simontonhoweschneiderpc.com +Jani,Biddy,Warehouse Office & Paper Prod,61556 W 20th Ave,Seattle,King,WA,98104,206-711-6498,206-395-6284,jbiddy@yahoo.com,http://www.warehouseofficepaperprod.com +Chauncey,Motley,Affiliated With Travelodge,63 E Aurora Dr,Orlando,Orange,FL,32804,407-413-4842,407-557-8857,chauncey_motley@aol.com,http://www.affiliatedwithtravelodge.com \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml b/rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml new file mode 100644 index 000000000..eba751ca8 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml @@ -0,0 +1,946 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + DocumentDBEngineVersion: + Type: String + Default: 5.0.0 + Description: DocumentDB engine version + JavaVersion: + Type: String + Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 + AllowedValues: + - java11 + - java17 + - java21 + Default: java21 + DocumentDBDatabaseName: + Type: String + Default: DocumentDBJavaLambdaDB + Description: DocumentDB database name for Lambda function + DocumentDBCollectionName: + Type: String + Default: DocumentDBJavaLambdaCollection + Description: DocumentDB collection name for Lambda function + DocumentDBClusterAdminUser: + Type: String + Description: Password for the DocumentDB Cluster + Default: docdbadmin + DocumentDBClusterPassword: + Type: String + Description: Password for the DocumentDB Cluster + Default: docdbPassword123 + NoEcho: true + DocumentDBTrustStorePassword: + Type: String + Description: Password for the DocumentDB Client TLS Truststore Password + Default: docdbTrustPass123 + NoEcho: true + ServerlessLandGithubLocation: + Type: String + Default: https://github.com/aws-samples/serverless-patterns.git + Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PublicThree: + CIDR: '10.0.2.0/24' + PrivateSubnetDocDBOne: + CIDR: '10.0.3.0/24' + PrivateSubnetDocDBTwo: + CIDR: '10.0.4.0/24' + PrivateSubnetDocDBThree: + CIDR: '10.0.5.0/24' + +Resources: + # Secrets Manager Secret for DocumentDB credentials + DocumentDBSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonDocumentDBCredentials' + Description: DocumentDB cluster master user credentials + SecretString: !Sub | + { + "username": "${DocumentDBClusterAdminUser}", + "password": "${DocumentDBClusterPassword}" + } + + DocumentDBTrustStoreSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonDocumentDBTruststore' + Description: DocumentDB secret for truststore for SSL client to connect + SecretString: !Sub | + { + "truststore": "/home/ec2-user/mongotruststore/rds-truststore.jks", + "truststorepassword": "${DocumentDBTrustStorePassword}" + } + + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'DocumentDBVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetTwo' + PublicSubnetThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetThree' + PrivateSubnetDocDBOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBOne' + PrivateSubnetDocDBTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBTwo' + PrivateSubnetDocDBThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBThree', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetDocDBThree' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + NATEIP1: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP1.AllocationId + SubnetId: !Ref 'PublicSubnetOne' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway1' + + NATEIP2: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP2.AllocationId + SubnetId: !Ref 'PublicSubnetTwo' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway2' + + NATEIP3: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway3: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP3.AllocationId + SubnetId: !Ref 'PublicSubnetThree' + Tags: + - Key: 'Name' + Value: 'DocumentDBNATGateway3' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + PublicSubnetThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetThree + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute1: + Type: AWS::EC2::Route + DependsOn: NATGateway1 + Properties: + RouteTableId: !Ref 'PrivateRouteTable1' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway1' + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute2: + Type: AWS::EC2::Route + DependsOn: NATGateway2 + Properties: + RouteTableId: !Ref 'PrivateRouteTable2' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway2' + + PrivateRouteTable3: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute3: + Type: AWS::EC2::Route + DependsOn: NATGateway3 + Properties: + RouteTableId: !Ref 'PrivateRouteTable3' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway3' + + PrivateSubnetDocDBOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnetDocDBOne + + PrivateSubnetDocDBTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnetDocDBTwo + + PrivateSubnetDocDBThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable3 + SubnetId: !Ref PrivateSubnetDocDBThree + + DocumentDBClientInstanceSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup + GroupName: !Sub "${AWS::StackName} Security group attached to the DocumentDB client" + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 10.0.0.0/16 + + DocumentDBSecurityGroup: + Type: AWS::EC2::SecurityGroup + DependsOn: [VPC,DocumentDBClientInstanceSecurityGroup] + Properties: + GroupDescription: DocumentDB Security Group + GroupName: !Sub "${AWS::StackName} Security group for the DocumentDB cluster" + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 27017 + ToPort: 27017 + SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 0 + ToPort: 65535 + CidrIp: 10.0.0.0/16 + + DocumentDBClientSelfIngressAllowRule: + Type: AWS::EC2::SecurityGroupIngress + DependsOn: DocumentDBClientInstanceSecurityGroup + Properties: + GroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + + DocumentDBClientEC2Instance: + DependsOn: DocumentDBCluster + Type: AWS::EC2::Instance + Properties: + InstanceType: m5.large + IamInstanceProfile: !Ref EC2InstanceProfile + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + SubnetId: !Ref PublicSubnetOne + SecurityGroupIds: [!GetAtt DocumentDBClientInstanceSecurityGroup.GroupId] + ImageId: !Ref LatestAmiId + Tags: + - Key: 'Name' + Value: 'DocumentDBClientInstance' + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: 50 + VolumeType: gp2 + DeleteOnTermination: true + UserData: + Fn::Base64: + !Sub + - | + #!/bin/bash + yum update -y + + # install Java + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum update -y + # yum install java-openjdk11-devel -y + + # install Java + JAVA_VERSION=${java_version} + echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + if [ "$JAVA_VERSION" == "java11" ]; then + sudo yum install java-11-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java17" ]; then + sudo yum install java-17-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java21" ]; then + sudo yum install java-21-amazon-corretto-devel -y + else + sudo yum install java-21-amazon-corretto-devel -y + fi + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of Java succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install nmap-ncat -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of nmap succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install git -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of git succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum erase awscli -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum erase of awscli succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install jq -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of jq succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y docker + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of docker succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + service docker start + usermod -a -G docker ec2-user + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y maven + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of maven succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + cd /home/ec2-user + su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user + su -c "pip3 install boto3 --user" -s /bin/sh ec2-user + su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user + + # install AWS CLI 2 - access with aws2 + cd /home/ec2-user + mkdir -p awscli + cd awscli + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + + # Install MongoDB shell + cd /home/ec2-user + wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-amazon2-x86_64-100.9.4.tgz + tar -zxvf mongodb-database-tools-amazon2-x86_64-100.9.4.tgz + sudo cp mongodb-database-tools-amazon2-x86_64-100.9.4/bin/* /usr/local/bin/ + + + # Install AWS SAM CLI + cd /home/ec2-user + mkdir -p awssam + cd awssam + wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + unzip aws-sam-cli-linux-x86_64.zip -d sam-installation + sudo ./sam-installation/install + + # Set environment variables + DOCDB_CLUSTER_ENDPOINT=${docdb_cluster_endpoint} + DOCDB_CLUSTER_RESOURCE=${docdb_cluster_resource} + DOCDB_CLUSTER_IDENTIFIER=${docdb_cluster_identifier} + DOCDB_DATABASE=${docdb_database} + DOCDB_COLLECTION=${docdb_collection} + DOCDB_SECRET_ARN=${docdb_secret_arn} + AWS_REGION=${aws_region} + DOCDB_SUBNET_ONE=${docdb_subnet_one} + DOCDB_SUBNET_TWO=${docdb_subnet_two} + DOCDB_SUBNET_THREE=${docdb_subnet_three} + DOCDB_SECURITY_GROUP=${docdb_security_group} + DOCDB_CLUSTER_ADMIN_USER=${docdb_cluster_admin_user} + DOCDB_CLUSTER_PASSWORD=${docdb_cluster_password} + DOCDB_TRUST_STORE_PASSWORD=${docdb_trust_store_password} + SECURITY_GROUP=${security_group_id} + + + echo "export DOCDB_CLUSTER_ENDPOINT=$DOCDB_CLUSTER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_RESOURCE=$DOCDB_CLUSTER_RESOURCE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_IDENTIFIER=$DOCDB_CLUSTER_IDENTIFIER" >> /home/ec2-user/.bash_profile + echo "export DOCDB_DATABASE=$DOCDB_DATABASE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_COLLECTION=$DOCDB_COLLECTION" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SECRET_ARN=$DOCDB_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_ONE=$DOCDB_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_TWO=$DOCDB_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SUBNET_THREE=$DOCDB_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export DOCDB_SECURITY_GROUP=$DOCDB_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_ADMIN_USER=$DOCDB_CLUSTER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export DOCDB_CLUSTER_PASSWORD=$DOCDB_CLUSTER_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export DOCDB_TRUST_STORE_PASSWORD=$DOCDB_TRUST_STORE_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + + + # Clone serverless patterns + cd /home/ec2-user + SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} + git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION + cd ./serverless-patterns + git sparse-checkout set --no-cone /documentdb-lambda-java-sam + git checkout + cd documentdb-lambda-java-sam + sudo chown -R ec2-user . + + #Install MongoShell + sudo cp ./mongodb-org-8.0.repo /etc/yum.repos.d + cd /home/ec2-user + mkdir mongoshell + cd mongoshell + sudo yum install -y mongodb-mongosh + + #Create Java Keystore to connect to DocumentDB + cd /home/ec2-user + mkdir mongotruststore + cd /home/ec2-user/mongotruststore + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/java_keystore_script.sh . + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/TRUSTSTORE_PASSWORD/$DOCDB_TRUST_STORE_PASSWORD/g" java_keystore_script.sh + chmod +x java_keystore_script.sh + sh ./java_keystore_script.sh + + #Create DocumentDB database and collection + cd /home/ec2-user/mongoshell + wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/docdb_db_collection.sh . + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/mongodbcolcreate.js . + cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/connect_to_mongo_shell.sh . + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" docdb_db_collection.sh + sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" docdb_db_collection.sh + sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" docdb_db_collection.sh + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" docdb_db_collection.sh + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" docdb_db_collection.sh + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" mongodbcolcreate.js + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" mongodbcolcreate.js + sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" connect_to_mongo_shell.sh + sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" connect_to_mongo_shell.sh + sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" connect_to_mongo_shell.sh + chmod +x docdb_db_collection.sh + chmod +x connect_to_mongo_shell.sh + sh ./docdb_db_collection.sh + + #Substitute SAM template variables + cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam + cd documentdb_streams_consumer_dynamo_sam + cp template_original.yaml template.yaml + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/DOCDB_CLUSTER_IDENTIFIER/$DOCDB_CLUSTER_IDENTIFIER/g" template.yaml + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" template.yaml + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" template.yaml + sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml + sed -i "s/DOCDB_SECRET_ARN/$DOCDB_SECRET_ARN/g" template.yaml + sed -i "s/DOCDB_SUBNET_ONE/$DOCDB_SUBNET_ONE/g" template.yaml + sed -i "s/DOCDB_SUBNET_TWO/$DOCDB_SUBNET_TWO/g" template.yaml + sed -i "s/DOCDB_SUBNET_THREE/$DOCDB_SUBNET_THREE/g" template.yaml + sed -i "s/DOCDB_SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + + #Adding DocumentDB variables to DocumentDB secret as CloudFormation cannot create a secret of type DocumentDB like you manually can + aws secretsmanager put-secret-value --secret-id AmazonDocumentDBCredentials --secret-string "{\"host\":\"$DOCDB_CLUSTER_ENDPOINT\",\"port\":\"27017\",\"username\":\"$DOCDB_CLUSTER_ADMIN_USER\",\"password\":\"$DOCDB_CLUSTER_PASSWORD\",\"engine\":\"mongo\",\"ssl\":\"true\",\"dbClusterIdentifier\":\"$DOCDB_CLUSTER_IDENTIFIER\"}" + + #Compiling Sender Program and Updating Command File with DocumentDB Database and Collection names + cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/documentdb_streams_message_sender_json + sudo chown -R ec2-user . + sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" commands.sh + sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" commands.sh + mvn clean install + + # Get IP CIDR range for EC2 Instance Connect + cd /home/ec2-user + mkdir -p ip_prefix + cd ip_prefix + git clone https://github.com/joetek/aws-ip-ranges-json.git + cd aws-ip-ranges-json + AWS_REGION=${aws_region} + EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') + echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile + SECURITY_GROUP=${security_group_id} + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP + + - docdb_cluster_endpoint: !GetAtt DocumentDBCluster.Endpoint + docdb_cluster_resource: !GetAtt DocumentDBCluster.ClusterResourceId + docdb_cluster_identifier: !Ref DocumentDBCluster + docdb_database: !Ref DocumentDBDatabaseName + docdb_collection: !Ref DocumentDBCollectionName + docdb_secret_arn: !Ref DocumentDBSecret + serverless_land_github_location: !Ref ServerlessLandGithubLocation + aws_region: !Ref 'AWS::Region' + java_version: !Ref JavaVersion + security_group_id : !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + docdb_subnet_one: !Ref PrivateSubnetDocDBOne + docdb_subnet_two: !Ref PrivateSubnetDocDBTwo + docdb_subnet_three: !Ref PrivateSubnetDocDBThree + docdb_security_group: !GetAtt DocumentDBSecurityGroup.GroupId + docdb_cluster_admin_user: !Ref DocumentDBClusterAdminUser + docdb_cluster_password: !Ref DocumentDBClusterPassword + docdb_trust_store_password: !Ref DocumentDBTrustStorePassword + + + EC2InstanceEndpoint: + Type: AWS::EC2::InstanceConnectEndpoint + Properties: + PreserveClientIp: true + SecurityGroupIds: + - !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + SubnetId: !Ref PublicSubnetOne + + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Action: 'sts:AssumeRole' + Path: "/" + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonDocDBFullAccess + - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore + - arn:aws:iam::aws:policy/AmazonS3FullAccess + - arn:aws:iam::aws:policy/IAMFullAccess + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 + Policies: + - PolicyName: DocumentDBAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "DocumentDBFullAccess", + "Effect": "Allow", + "Action": [ + "docdb:*", + "docdb-elastic:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecretsManagerAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${DocumentDBSecret}" + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${DocumentDBTrustStoreSecret}" + } + ] + }' + - PolicyName: CloudformationDeploy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecurityGroupsPolicy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupEgress", + "ec2:ModifySecurityGroupRules", + "ec2:UpdateSecurityGroupRuleDescriptionsIngress", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:ModifySecurityGroupRules" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" + ] + } + ] + }' + + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Join + - '-' + - - 'EC2DocumentDBProfile' + - !Ref 'AWS::StackName' + Roles: + - !Ref EC2Role + + + # DocumentDB Subnet Group + DocumentDBSubnetGroup: + Type: AWS::DocDB::DBSubnetGroup + Properties: + DBSubnetGroupDescription: Subnet group for DocumentDB cluster + SubnetIds: + - !Ref PrivateSubnetDocDBOne + - !Ref PrivateSubnetDocDBTwo + - !Ref PrivateSubnetDocDBThree + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-subnet-group" + + # DocumentDB Instance-Based Cluster + DocumentDBCluster: + Type: AWS::DocDB::DBCluster + Properties: + DBClusterIdentifier: !Sub "${AWS::StackName}-docdb-cluster" + MasterUsername: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:username}}" + MasterUserPassword: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:password}}" + EngineVersion: !Ref DocumentDBEngineVersion + DBSubnetGroupName: !Ref DocumentDBSubnetGroup + VpcSecurityGroupIds: + - !Ref DocumentDBSecurityGroup + BackupRetentionPeriod: 7 + PreferredBackupWindow: "07:00-09:00" + PreferredMaintenanceWindow: "sun:09:00-sun:11:00" + StorageEncrypted: true + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-cluster" + + DocumentDBInstance1: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-1" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-1" + + DocumentDBInstance2: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-2" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-2" + + DocumentDBInstance3: + Type: AWS::DocDB::DBInstance + Properties: + DBClusterIdentifier: !Ref DocumentDBCluster + DBInstanceClass: db.t3.medium + DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-3" + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-docdb-instance-31" + +Outputs: + VPCId: + Description: The ID of the VPC created + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PublicSubnetOne: + Description: The name of the public subnet created + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Sub "${AWS::StackName}-PublicSubnetOne" + PrivateSubnetDocDBOne: + Description: The ID of private subnet one created + Value: !Ref 'PrivateSubnetDocDBOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBOne" + PrivateSubnetDocDBTwo: + Description: The ID of private subnet two created + Value: !Ref 'PrivateSubnetDocDBTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBTwo" + PrivateSubnetDocDBThree: + Description: The ID of private subnet three created + Value: !Ref 'PrivateSubnetDocDBThree' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBThree" + VPCStackName: + Description: The name of the VPC Stack + Value: !Ref 'AWS::StackName' + Export: + Name: !Sub "${AWS::StackName}-VPCStackName" + DocumentDBClusterEndpoint: + Description: DocumentDB Instance-Based Cluster Endpoint + Value: !GetAtt DocumentDBCluster.Endpoint + Export: + Name: !Sub "${AWS::StackName}-DocumentDBClusterEndpoint" + DocumentDBSecretArn: + Description: ARN of the DocumentDB credentials secret + Value: !Ref DocumentDBSecret + Export: + Name: !Sub "${AWS::StackName}-DocumentDBSecretArn" + SecurityGroupId: + Description: ID of security group for DocumentDB clients + Value: !GetAtt DocumentDBSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" + EC2InstanceEndpointID: + Description: The ID of the EC2 Instance Endpoint + Value: !Ref EC2InstanceEndpoint + DocumentDBDatabaseName: + Description: The Database name to use for the Java Lambda Function + Value: !Ref DocumentDBDatabaseName + Export: + Name: !Sub "${AWS::StackName}-DocumentDBDatabaseName" + DocumentDBCollectionName: + Description: The Collection name to use for the Java Lambda Function + Value: !Ref DocumentDBCollectionName + Export: + Name: !Sub "${AWS::StackName}-DocumentDBCollectionName" diff --git a/rabbitmq-private-lambda-java-sam/README.md b/rabbitmq-private-lambda-java-sam/README.md new file mode 100755 index 000000000..09aa4d870 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/README.md @@ -0,0 +1,2 @@ +# javaRabbitMQLambdaDynamoDB +Java samples for RabbitMQ --> Lambda --> DynamoDB diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/.gitignore b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/.gitignore new file mode 100755 index 000000000..73a5e7b94 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/.gitignore @@ -0,0 +1,53 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +node_modules +npm-debug.log +package-lock.json +package +*out.yml +out.json +bucket-name.txt +target +build +.gradle +*.zip +bin +obj +Gemfile.lock +lib +__pycache__ +*.pyc +.classpath +.factorypath +.project +.settings/* +.aws +.sam +.aws-sam +samconfig.toml +__init__.py +.DS_Store +.project \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/README.md b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/README.md new file mode 100755 index 000000000..ad4cb4835 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/README.md @@ -0,0 +1,104 @@ +# rabbitmq-consumer-dynamo-sam + +This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. + +- rabbitmq_event_consumer_function/src/main/java - Code for the application's Lambda function. +- events - Invocation events that you can use to invoke the function. +- rabbitmq_event_consumer_function/src/test/java - Unit tests for the application code. +- template.yaml - A template that defines the application's AWS resources. + +The application uses several AWS resources, including a Lambda function, a RabbitMQ event source and a DynamoDB table to which the lambda function will write. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. + + +## Use the SAM CLI to build and test locally + +Build your application with the `sam build` command. + +```bash +sam build +``` + +The SAM CLI installs dependencies defined in `rabbitmq_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. + +Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. + +Run functions locally and invoke them with the `sam local invoke` command. + +```bash +sam local invoke --event events/event.json +``` + +## Deploy the sample application + +The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. + +To use the SAM CLI, you need the following tools. + +* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) +* Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) + +To build and deploy your application for the first time, run the following in your shell: + +```bash +sam build +sam deploy --guided +``` + +The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Parameter RabbitMQBrokerName**: The name of the RabbitMQ Broker +* **Parameter RabbitMQBrokerUniqueString**: The unique string of the RabbitMQ Broker +* **Parameter RabbitMQQueue**: The name of the RabbitMQ Queue +* **Parameter SecretsManagerSecretForMQName**: The name of the Secrets Manager secret that has the RabbitMQ broker Username and Password +* **Parameter SecretsManagerSecretForMQUniqueString**: The unique string of the Secrets Manager secret that has the RabbitMQ broker Username and Password +* **Parameter Subnet1**: The name of the first subnet where the RabbitMQ broker has been configured +* **Parameter Subnet2**: The name of the second subnet where the RabbitMQ broker has been configured +* **Parameter SecurityGroup**: The name of the security group where the RabbitMQ broker has been configured +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails +* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. +* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally +* **SAM configuration environment [default]**: Environment for storing deployment information locally + +You should get a message "Successfully created/updated stack - in " if all goes well + + +## Test the sample application + +Once the lambda function is deployed, send some RabbitMQ messages on the queue that the lambda function is listening on. + +Use the project ../rabbitmq_message_sender_json. + +Look at the Readme of that project to determine how to build that project and run the command that will send RabbitMQ messages with a Json payload to the lambda function built using this project. The lambda function will receive the RabbitMQ messages with a JSON payload and input fields from the RabbitMQ message into a DynamoDB table. + +The value field of each RabbitMQ message that will be sent out will be a Json element of the format + +"person": { + "firstname": "Myra", + "lastname": "Munns", + "company": "Anker Law Office", + "street": "461 Prospect Pl #316", + "city": "Euless", + "county": "Tarrant", + "state": "TX", + "zip": "76040", + "homePhone": "817-914-7518", + "cellPhone": "817-451-3518", + "email": "mmunns@cox.net", + "website": "http://www.ankerlawoffice.com" +} + +Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) + +Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. + +The lambda code parses the RabbitMQ messages and outputs the fields in the RabbitMQ messages to Cloudwatch logs + +A single lambda function receives a batch of messages. + +The code in this example prints out the fields in the SQS message and logs them in Cloudwatch logs. + +Apart from outputting to Cloudwatch logs, the lambda function also inputs fields from the RabbitMQ message (both message metadata fields as well as payload fields from the JSON payload) into a DynamoDB table created by the SAM template. You can log into the AWS console and look at the DynamoDB table and run a scan to see data getting input from the RabbitMQ message into the DynamoDB table diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/events/event.json b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/events/event.json new file mode 100755 index 000000000..4ec1efb29 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/events/event.json @@ -0,0 +1,608 @@ +{ + "eventSource": "aws:rmq", + "eventSourceArn": "arn:aws:mq:us-west-2:664251831272:broker:ib-rabbitmq-broker:b-22450561-3f76-4004-813d-392346f054fe", + "rmqMessagesByQueue": { + "LambdaRabbitMQQueue::/": [ + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 1, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-1", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:1", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 321 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 2, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-2", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:2", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 297 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJBcnQiLCJsYXN0bmFtZSI6IlZlbmVyZSIsImNvbXBhbnkiOiJcIkNoZW1lbCwgSmFtZXMgTCBDcGFcIiIsInN0cmVldCI6IjggVyBDZXJyaXRvcyBBdmUgIzU0IiwiY2l0eSI6IkJyaWRnZXBvcnQiLCJjb3VudHkiOiJHbG91Y2VzdGVyIiwic3RhdGUiOiJOSiIsInppcCI6IjgwMTQiLCJob21lUGhvbmUiOiI4NTYtNjM2LTg3NDkiLCJjZWxsUGhvbmUiOiI4NTYtMjY0LTQxMzAiLCJlbWFpbCI6ImFydEB2ZW5lcmUub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuY2hlbWVsamFtZXNsY3BhLmNvbSJ9" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 3, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-3", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:3", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 302 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0=" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 4, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-4", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:4", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 295 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJEb25ldHRlIiwibGFzdG5hbWUiOiJGb2xsZXIiLCJjb21wYW55IjoiUHJpbnRpbmcgRGltZW5zaW9ucyIsInN0cmVldCI6IjM0IENlbnRlciBTdCIsImNpdHkiOiJIYW1pbHRvbiIsImNvdW50eSI6IkJ1dGxlciIsInN0YXRlIjoiT0giLCJ6aXAiOiI0NTAxMSIsImhvbWVQaG9uZSI6IjUxMy01NzAtMTg5MyIsImNlbGxQaG9uZSI6IjUxMy01NDktNDU2MSIsImVtYWlsIjoiZG9uZXR0ZS5mb2xsZXJAY294Lm5ldCIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnByaW50aW5nZGltZW5zaW9ucy5jb20ifQ==" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 5, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-5", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:5", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 292 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJTaW1vbmEiLCJsYXN0bmFtZSI6Ik1vcmFzY2EiLCJjb21wYW55IjoiXCJDaGFwbWFuLCBSb3NzIEUgRXNxXCIiLCJzdHJlZXQiOiIzIE1jYXVsZXkgRHIiLCJjaXR5IjoiQXNobGFuZCIsImNvdW50eSI6IkFzaGxhbmQiLCJzdGF0ZSI6Ik9IIiwiemlwIjoiNDQ4MDUiLCJob21lUGhvbmUiOiI0MTktNTAzLTI0ODQiLCJjZWxsUGhvbmUiOiI0MTktODAwLTY3NTkiLCJlbWFpbCI6InNpbW9uYUBtb3Jhc2NhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYXBtYW5yb3NzZWVzcS5jb20ifQ==" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 6, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-6", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:6", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 289 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJNaXRzdWUiLCJsYXN0bmFtZSI6IlRvbGxuZXIiLCJjb21wYW55IjoiTW9ybG9uZyBBc3NvY2lhdGVzIiwic3RyZWV0IjoiNyBFYWRzIFN0IiwiY2l0eSI6IkNoaWNhZ28iLCJjb3VudHkiOiJDb29rIiwic3RhdGUiOiJJTCIsInppcCI6IjYwNjMyIiwiaG9tZVBob25lIjoiNzczLTU3My02OTE0IiwiY2VsbFBob25lIjoiNzczLTkyNC04NTY1IiwiZW1haWwiOiJtaXRzdWVfdG9sbG5lckB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tb3Jsb25nYXNzb2NpYXRlcy5jb20ifQ==" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 7, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-7", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:7", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 293 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJMZW90YSIsImxhc3RuYW1lIjoiRGlsbGlhcmQiLCJjb21wYW55IjoiQ29tbWVyY2lhbCBQcmVzcyIsInN0cmVldCI6IjcgVyBKYWNrc29uIEJsdmQiLCJjaXR5IjoiU2FuIEpvc2UiLCJjb3VudHkiOiJTYW50YSBDbGFyYSIsInN0YXRlIjoiQ0EiLCJ6aXAiOiI5NTExMSIsImhvbWVQaG9uZSI6IjQwOC03NTItMzUwMCIsImNlbGxQaG9uZSI6IjQwOC04MTMtMTEwNSIsImVtYWlsIjoibGVvdGFAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5jb21tZXJjaWFscHJlc3MuY29tIn0=" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 8, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-8", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:8", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 309 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJTYWdlIiwibGFzdG5hbWUiOiJXaWVzZXIiLCJjb21wYW55IjoiVHJ1aGxhciBBbmQgVHJ1aGxhciBBdHR5cyIsInN0cmVldCI6IjUgQm9zdG9uIEF2ZSAjODgiLCJjaXR5IjoiU2lvdXggRmFsbHMiLCJjb3VudHkiOiJNaW5uZWhhaGEiLCJzdGF0ZSI6IlNEIiwiemlwIjoiNTcxMDUiLCJob21lUGhvbmUiOiI2MDUtNDE0LTIxNDciLCJjZWxsUGhvbmUiOiI2MDUtNzk0LTQ4OTUiLCJlbWFpbCI6InNhZ2Vfd2llc2VyQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy50cnVobGFyYW5kdHJ1aGxhcmF0dHlzLmNvbSJ9" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 9, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-9", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:9", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 312 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJLcmlzIiwibGFzdG5hbWUiOiJNYXJyaWVyIiwiY29tcGFueSI6IlwiS2luZywgQ2hyaXN0b3BoZXIgQSBFc3FcIiIsInN0cmVldCI6IjIyOCBSdW5hbXVjayBQbCAjMjgwOCIsImNpdHkiOiJCYWx0aW1vcmUiLCJjb3VudHkiOiJCYWx0aW1vcmUgQ2l0eSIsInN0YXRlIjoiTUQiLCJ6aXAiOiIyMTIyNCIsImhvbWVQaG9uZSI6IjQxMC02NTUtODcyMyIsImNlbGxQaG9uZSI6IjQxMC04MDQtNDY5NCIsImVtYWlsIjoia3Jpc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5raW5nY2hyaXN0b3BoZXJhZXNxLmNvbSJ9" + }, + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": "UTF-8", + "headers": { + "MessageNumberInBatch": 10, + "MessageBatchIdentifier": { + "bytes": [ + 84, + 101, + 115, + 116, + 77, + 101, + 115, + 115, + 97, + 103, + 101, + 48, + 51, + 45, + 48, + 55, + 45, + 48, + 50, + 45, + 50, + 48, + 50, + 51, + 45, + 48, + 49, + 45, + 48, + 55, + 45, + 50, + 48 + ] + } + }, + "deliveryMode": 2, + "priority": 1, + "correlationId": "TestMessage03-07-02-2023-01-07-20-10", + "replyTo": null, + "expiration": 60000, + "messageId": "TestMessage03-07-02-2023-01-07-20:10", + "timestamp": "Jul 2, 2023, 1:30:34 AM", + "type": "JsonRabbitMQProducer", + "userId": "admin", + "appId": "rabbitmq.producer.JsonRabbitMQProducer", + "clusterId": "b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com", + "bodySize": 300 + }, + "redelivered": false, + "data": "eyJmaXJzdG5hbWUiOiJNaW5uYSIsImxhc3RuYW1lIjoiQW1pZ29uIiwiY29tcGFueSI6IlwiRG9ybCwgSmFtZXMgSiBFc3FcIiIsInN0cmVldCI6IjIzNzEgSmVycm9sZCBBdmUiLCJjaXR5IjoiS3VscHN2aWxsZSIsImNvdW50eSI6Ik1vbnRnb21lcnkiLCJzdGF0ZSI6IlBBIiwiemlwIjoiMTk0NDMiLCJob21lUGhvbmUiOiIyMTUtODc0LTEyMjkiLCJjZWxsUGhvbmUiOiIyMTUtNDIyLTg2OTQiLCJlbWFpbCI6Im1pbm5hX2FtaWdvbkB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5kb3JsamFtZXNqZXNxLmNvbSJ9" + } + ] + } +} \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.gitignore b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.gitignore new file mode 100755 index 000000000..b83d22266 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 000000000..d4313d4b2 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 000000000..46235dc07 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/pom.xml b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/pom.xml new file mode 100755 index 000000000..37c5f71f5 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/pom.xml @@ -0,0 +1,85 @@ + + 4.0.0 + com.amazonaws.services.lambda.samples.events.rabbitmq + RabbitMQConsumer + 1.0 + jar + A sample Lambda RabbitMQ consumer + + 11 + 11 + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.11.0 + + + + com.amazonaws + aws-java-sdk-dynamodb + 1.12.445 + + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + org.mockito + mockito-core + 3.7.7 + test + + + org.mockito + mockito-junit-jupiter + 3.8.0 + test + + + + + com.fasterxml.jackson.core + jackson-core + 2.15.1 + + + com.rabbitmq + amqp-client + 5.9.0 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + package + + shade + + + + + + + diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdater.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdater.java new file mode 100755 index 000000000..2eefd0fb5 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdater.java @@ -0,0 +1,112 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; +import com.amazonaws.services.dynamodbv2.document.DynamoDB; +import com.amazonaws.services.dynamodbv2.document.Item; +import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.dynamodbv2.document.Table; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent.BasicProperties; + +public class DynamoDBUpdater { + + String dynamoDBTableName; + AmazonDynamoDB client; + DynamoDB dynamoDB; + Table dynamoTable; + + public DynamoDBUpdater(String dynamoDBTableName) { + super(); + if (null == dynamoDBTableName) { + this.dynamoDBTableName = "ACTIVEMQ_LAMBDA_DYNAMO_TABLE"; + } else { + this.dynamoDBTableName = dynamoDBTableName; + } + String AWS_SAM_LOCAL = System.getenv("AWS_SAM_LOCAL"); + if (null == AWS_SAM_LOCAL) { + this.client = AmazonDynamoDBClientBuilder.standard().build(); + } else { + this.client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(new EndpointConfiguration("http://127.0.0.1:8000", "")).build(); + this.dynamoDBTableName = "ACTIVEMQ_LAMBDA_DYNAMO_TABLE"; + } + this.dynamoDB = new DynamoDB(client); + this.dynamoTable = dynamoDB.getTable(this.dynamoDBTableName); + } + + public PutItemOutcome insertIntoDynamoDB(RabbitMQEvent.RabbitMessage thisMessage, Person thisPerson, LambdaLogger logger, long receiveTime, String queueName, String eventSource, String eventSourceARN) { + BasicProperties thisMessageProperties = thisMessage.getBasicProperties(); + logger.log("Now inserting a row in DynamoDB for messageID = " + thisMessageProperties.getMessageId()); + Item item = new Item(); + item.withPrimaryKey("MessageID", thisMessageProperties.getMessageId()); + item.withString("EventSource", eventSource); + item.withString("EventSourceARN", eventSourceARN); + item.withString("Queue", queueName); + item.withString("Firstname", thisPerson.getFirstname()); + item.withString("Lastname", thisPerson.getLastname()); + item.withString("Company", thisPerson.getCompany()); + item.withString("Street", thisPerson.getStreet()); + item.withString("City", thisPerson.getCity()); + item.withString("County", thisPerson.getCounty()); + item.withString("State", thisPerson.getState()); + item.withString("Zip", thisPerson.getZip()); + item.withString("Cellphone", thisPerson.getCellPhone()); + item.withString("Homephone", thisPerson.getHomePhone()); + item.withString("Email", thisPerson.getEmail()); + item.withString("Website", thisPerson.getWebsite()); + item.withString("CorrelationID", thisMessageProperties.getCorrelationId()); + item.withString("MessageType", thisMessageProperties.getMessageId()); + if (null == thisMessageProperties.getReplyTo()) { + item.withNull("ReplyTo"); + } else { + item.withString("ReplyTo", thisMessageProperties.getReplyTo()); + } + if (null == thisMessageProperties.getType()) { + item.withNull("Type"); + } else { + item.withString("Type", thisMessageProperties.getType()); + } + item.withBoolean("WhetherRedelivered", thisMessage.getRedelivered()); + item.withString("AppID", thisMessageProperties.getAppId()); + item.withInt("BodySize", thisMessageProperties.getBodySize()); + item.withString("ClusterId", thisMessageProperties.getClusterId()); + item.withString("ContentEncoding", thisMessageProperties.getContentEncoding()); + item.withString("ContentType", thisMessageProperties.getContentType()); + item.withInt("DeliveryMode", thisMessageProperties.getDeliveryMode()); + item.withInt("Expiration", thisMessageProperties.getExpiration()); + item.withInt("Priority", thisMessageProperties.getPriority()); + if (null != thisMessageProperties.getReplyTo()) { + item.withString("ReplyTo", thisMessageProperties.getReplyTo()); + } else { + item.withNull("ReplyTo"); + } + item.withString("Timestamp", thisMessageProperties.getTimestamp()); + item.withString("Type", thisMessageProperties.getType()); + item.withString("UserId", thisMessageProperties.getUserId()); + Map thisMessageHeaders = thisMessageProperties.getHeaders(); + thisMessageHeaders.forEach((headerName, headerValue) -> { + if (headerValue.getClass().getName().equalsIgnoreCase("java.util.LinkedHashMap")) { + LinkedHashMap headerValueLinkedHashMap = (LinkedHashMap)headerValue; + ArrayList headerValueArrayList = (ArrayList)headerValueLinkedHashMap.get("bytes"); + byte[] headerValueByteArray = new byte[headerValueArrayList.size()]; + int i=0; + for (Integer thisInteger: headerValueArrayList) { + headerValueByteArray[i] = thisInteger.byteValue(); + i++; + } + String headerValueString = new String(headerValueByteArray); + item.withString(headerName, headerValueString); + } else { + item.with(headerName, headerValue); + } + }); + logger.log("Now done inserting a row in DynamoDB for messageID = " + thisMessageProperties.getMessageId()); + return dynamoTable.putItem(item); + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQ.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQ.java new file mode 100755 index 000000000..d886dd9fd --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQ.java @@ -0,0 +1,102 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent.BasicProperties; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class HandlerRabbitMQ implements RequestHandler{ + String dynamoDBTableName = System.getenv("DYNAMO_DB_TABLE"); + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater(dynamoDBTableName); + boolean addToDynamoDB; + ObjectMapper objectMapper = new ObjectMapper(); + @Override + public String handleRequest(RabbitMQEvent event, Context context) + { + addToDynamoDB = true; + LambdaLogger logger = context.getLogger(); + try { + logger.log("Begin Event *************"); + logger.log(objectMapper.writeValueAsString(event)); + logger.log("End Event ***************"); + logger.log("EventSource = " + event.getEventSource()); + logger.log("EventSourceARN = " + event.getEventSourceArn()); + logger.log("Now iterating through Map of all queues"); + Map> mapOfMessages = event.getRmqMessagesByQueue(); + mapOfMessages.forEach((k, v) -> { + String currentQueueName = k.substring(0, k.indexOf("::")); + logger.log("Current Queue Name = " + currentQueueName); + logger.log("Now iterating through each message in this queue - " + currentQueueName); + for (RabbitMQEvent.RabbitMessage thisMessage: v) { + logger.log("Now logging a new message"); + String encodedData = thisMessage.getData(); + logger.log("EncodedData = " + encodedData); + String decodedData = new String(Base64.getDecoder().decode(encodedData)); + logger.log("DecodedData = " + decodedData); + Person thisPerson = new Person(); + try { + thisPerson = objectMapper.readValue(decodedData, Person.class); + } catch (JsonProcessingException e) { + logger.log(e.getMessage()); + } + logger.log("This person = " + thisPerson.toString()); + logger.log("Whether Redelivered = " + thisMessage.getRedelivered()); + BasicProperties thisMessageProperties = thisMessage.getBasicProperties(); + logger.log("AppID = " + thisMessageProperties.getAppId()); + logger.log("BodySize = " + thisMessageProperties.getBodySize()); + logger.log("ClusterId = " + thisMessageProperties.getClusterId()); + logger.log("ContentEncoding = " + thisMessageProperties.getContentEncoding()); + logger.log("ContentType = " + thisMessageProperties.getContentType()); + logger.log("CorrelationId = " + thisMessageProperties.getCorrelationId()); + logger.log("DeliveryMode = " + thisMessageProperties.getDeliveryMode()); + logger.log("Expiration = " + thisMessageProperties.getExpiration()); + logger.log("MessageId = " + thisMessageProperties.getMessageId()); + logger.log("Priority = " + thisMessageProperties.getPriority()); + logger.log("ReplyTo = " + thisMessageProperties.getReplyTo()); + logger.log("Timestamp = " + thisMessageProperties.getTimestamp()); + logger.log("Type = " + thisMessageProperties.getType()); + logger.log("UserId = " + thisMessageProperties.getUserId()); + logger.log("Now iterating through the headers in this message"); + Map thisMessageHeaders = thisMessageProperties.getHeaders(); + thisMessageHeaders.forEach((headerName, headerValue) -> { + if (headerValue.getClass().getName().equalsIgnoreCase("java.util.LinkedHashMap")) { + LinkedHashMap headerValueLinkedHashMap = (LinkedHashMap)headerValue; + ArrayList headerValueArrayList = (ArrayList)headerValueLinkedHashMap.get("bytes"); + byte[] headerValueByteArray = new byte[headerValueArrayList.size()]; + int i=0; + for (Integer thisInteger: headerValueArrayList) { + headerValueByteArray[i] = thisInteger.byteValue(); + i++; + } + String headerValueString = new String(headerValueByteArray); + logger.log("Header Name = " + headerName + " and Header Value = " + headerValueString); + } else { + logger.log("Header Name = " + headerName + " and Header Value = " + headerValue.toString()); + } + }); + logger.log("Now done iterating through the headers in this message"); + logger.log("Now done logging a new message"); + String AWS_SAM_LOCAL = System.getenv("AWS_SAM_LOCAL"); + if ((null == AWS_SAM_LOCAL) && (addToDynamoDB)) { + ddbUpdater.insertIntoDynamoDB(thisMessage, thisPerson, logger, System.currentTimeMillis(), currentQueueName, event.getEventSource(), event.getEventSourceArn()); + } + } + logger.log("Now done iterating through each message in this queue"); + }); + logger.log("Done iterating through Map of all queues"); + return "200"; + } catch (Exception e) { + logger.log("An exception occurred - " + e.getMessage()); + return "500"; + } + + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/Person.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/Person.java new file mode 100755 index 000000000..a94203922 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/main/java/com/amazonaws/services/lambda/samples/events/rabbitmq/Person.java @@ -0,0 +1,137 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import java.util.Objects; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Person { + + String firstname; + String lastname; + String company; + String street; + String city; + String county; + String state; + String zip; + String homePhone; + String cellPhone; + String email; + String website; + public Person() { + super(); + } + public String getFirstname() { + return firstname; + } + public void setFirstname(String firstname) { + this.firstname = firstname; + } + public String getLastname() { + return lastname; + } + public void setLastname(String lastname) { + this.lastname = lastname; + } + public String getCompany() { + return company; + } + public void setCompany(String company) { + this.company = company; + } + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getCounty() { + return county; + } + public void setCounty(String county) { + this.county = county; + } + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + public String getZip() { + return zip; + } + public void setZip(String zip) { + this.zip = zip; + } + public String getHomePhone() { + return homePhone; + } + public void setHomePhone(String homePhone) { + this.homePhone = homePhone; + } + public String getCellPhone() { + return cellPhone; + } + public void setCellPhone(String cellPhone) { + this.cellPhone = cellPhone; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getWebsite() { + return website; + } + public void setWebsite(String website) { + this.website = website; + } + @Override + public String toString() { + return "Person [firstname=" + firstname + ", lastname=" + lastname + ", company=" + company + ", street=" + + street + ", city=" + city + ", county=" + county + ", state=" + state + ", zip=" + zip + + ", homePhone=" + homePhone + ", cellPhone=" + cellPhone + ", email=" + email + ", website=" + website + + "]"; + } + + public String toJson() { + ObjectMapper om = new ObjectMapper(); + String returnValue = ""; + try { + returnValue = om.writeValueAsString(this); + } catch (JsonProcessingException e) { + returnValue = this.toString(); + } + return returnValue; + } + @Override + public int hashCode() { + return Objects.hash(cellPhone, city, company, county, email, firstname, homePhone, lastname, state, street, + website, zip); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Person other = (Person) obj; + return Objects.equals(cellPhone, other.cellPhone) && Objects.equals(city, other.city) + && Objects.equals(company, other.company) && Objects.equals(county, other.county) + && Objects.equals(email, other.email) && Objects.equals(firstname, other.firstname) + && Objects.equals(homePhone, other.homePhone) && Objects.equals(lastname, other.lastname) + && Objects.equals(state, other.state) && Objects.equals(street, other.street) + && Objects.equals(website, other.website) && Objects.equals(zip, other.zip); + } + +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdaterTest.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdaterTest.java new file mode 100755 index 000000000..6ad67ad5f --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/DynamoDBUpdaterTest.java @@ -0,0 +1,689 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Base64; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.document.DynamoDB; +import com.amazonaws.services.dynamodbv2.document.Item; +import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.dynamodbv2.document.Table; +import com.amazonaws.services.lambda.runtime.LambdaLogger; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.mockito.ArgumentMatchers; + +class DynamoDBUpdaterTest { + + private static final String mqEventJson = "{\n" + + " \"eventSource\": \"aws:rmq\",\n" + + " \"eventSourceArn\": \"arn:aws:mq:us-west-2:664251831272:broker:ib-rabbitmq-broker:b-22450561-3f76-4004-813d-392346f054fe\",\n" + + " \"rmqMessagesByQueue\": {\n" + + " \"LambdaRabbitMQQueue::/\": [\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 1,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-1\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:1\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 321\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 2,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-2\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:2\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 297\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJBcnQiLCJsYXN0bmFtZSI6IlZlbmVyZSIsImNvbXBhbnkiOiJcIkNoZW1lbCwgSmFtZXMgTCBDcGFcIiIsInN0cmVldCI6IjggVyBDZXJyaXRvcyBBdmUgIzU0IiwiY2l0eSI6IkJyaWRnZXBvcnQiLCJjb3VudHkiOiJHbG91Y2VzdGVyIiwic3RhdGUiOiJOSiIsInppcCI6IjgwMTQiLCJob21lUGhvbmUiOiI4NTYtNjM2LTg3NDkiLCJjZWxsUGhvbmUiOiI4NTYtMjY0LTQxMzAiLCJlbWFpbCI6ImFydEB2ZW5lcmUub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuY2hlbWVsamFtZXNsY3BhLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 3,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-3\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:3\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 302\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0=\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 4,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-4\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:4\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 295\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJEb25ldHRlIiwibGFzdG5hbWUiOiJGb2xsZXIiLCJjb21wYW55IjoiUHJpbnRpbmcgRGltZW5zaW9ucyIsInN0cmVldCI6IjM0IENlbnRlciBTdCIsImNpdHkiOiJIYW1pbHRvbiIsImNvdW50eSI6IkJ1dGxlciIsInN0YXRlIjoiT0giLCJ6aXAiOiI0NTAxMSIsImhvbWVQaG9uZSI6IjUxMy01NzAtMTg5MyIsImNlbGxQaG9uZSI6IjUxMy01NDktNDU2MSIsImVtYWlsIjoiZG9uZXR0ZS5mb2xsZXJAY294Lm5ldCIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnByaW50aW5nZGltZW5zaW9ucy5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 5,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-5\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:5\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 292\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJTaW1vbmEiLCJsYXN0bmFtZSI6Ik1vcmFzY2EiLCJjb21wYW55IjoiXCJDaGFwbWFuLCBSb3NzIEUgRXNxXCIiLCJzdHJlZXQiOiIzIE1jYXVsZXkgRHIiLCJjaXR5IjoiQXNobGFuZCIsImNvdW50eSI6IkFzaGxhbmQiLCJzdGF0ZSI6Ik9IIiwiemlwIjoiNDQ4MDUiLCJob21lUGhvbmUiOiI0MTktNTAzLTI0ODQiLCJjZWxsUGhvbmUiOiI0MTktODAwLTY3NTkiLCJlbWFpbCI6InNpbW9uYUBtb3Jhc2NhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYXBtYW5yb3NzZWVzcS5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 6,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-6\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:6\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 289\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNaXRzdWUiLCJsYXN0bmFtZSI6IlRvbGxuZXIiLCJjb21wYW55IjoiTW9ybG9uZyBBc3NvY2lhdGVzIiwic3RyZWV0IjoiNyBFYWRzIFN0IiwiY2l0eSI6IkNoaWNhZ28iLCJjb3VudHkiOiJDb29rIiwic3RhdGUiOiJJTCIsInppcCI6IjYwNjMyIiwiaG9tZVBob25lIjoiNzczLTU3My02OTE0IiwiY2VsbFBob25lIjoiNzczLTkyNC04NTY1IiwiZW1haWwiOiJtaXRzdWVfdG9sbG5lckB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tb3Jsb25nYXNzb2NpYXRlcy5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 7,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-7\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:7\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 293\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMZW90YSIsImxhc3RuYW1lIjoiRGlsbGlhcmQiLCJjb21wYW55IjoiQ29tbWVyY2lhbCBQcmVzcyIsInN0cmVldCI6IjcgVyBKYWNrc29uIEJsdmQiLCJjaXR5IjoiU2FuIEpvc2UiLCJjb3VudHkiOiJTYW50YSBDbGFyYSIsInN0YXRlIjoiQ0EiLCJ6aXAiOiI5NTExMSIsImhvbWVQaG9uZSI6IjQwOC03NTItMzUwMCIsImNlbGxQaG9uZSI6IjQwOC04MTMtMTEwNSIsImVtYWlsIjoibGVvdGFAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5jb21tZXJjaWFscHJlc3MuY29tIn0=\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 8,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-8\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:8\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 309\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJTYWdlIiwibGFzdG5hbWUiOiJXaWVzZXIiLCJjb21wYW55IjoiVHJ1aGxhciBBbmQgVHJ1aGxhciBBdHR5cyIsInN0cmVldCI6IjUgQm9zdG9uIEF2ZSAjODgiLCJjaXR5IjoiU2lvdXggRmFsbHMiLCJjb3VudHkiOiJNaW5uZWhhaGEiLCJzdGF0ZSI6IlNEIiwiemlwIjoiNTcxMDUiLCJob21lUGhvbmUiOiI2MDUtNDE0LTIxNDciLCJjZWxsUGhvbmUiOiI2MDUtNzk0LTQ4OTUiLCJlbWFpbCI6InNhZ2Vfd2llc2VyQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy50cnVobGFyYW5kdHJ1aGxhcmF0dHlzLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 9,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-9\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:9\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 312\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJLcmlzIiwibGFzdG5hbWUiOiJNYXJyaWVyIiwiY29tcGFueSI6IlwiS2luZywgQ2hyaXN0b3BoZXIgQSBFc3FcIiIsInN0cmVldCI6IjIyOCBSdW5hbXVjayBQbCAjMjgwOCIsImNpdHkiOiJCYWx0aW1vcmUiLCJjb3VudHkiOiJCYWx0aW1vcmUgQ2l0eSIsInN0YXRlIjoiTUQiLCJ6aXAiOiIyMTIyNCIsImhvbWVQaG9uZSI6IjQxMC02NTUtODcyMyIsImNlbGxQaG9uZSI6IjQxMC04MDQtNDY5NCIsImVtYWlsIjoia3Jpc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5raW5nY2hyaXN0b3BoZXJhZXNxLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 10,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-10\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:10\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 300\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNaW5uYSIsImxhc3RuYW1lIjoiQW1pZ29uIiwiY29tcGFueSI6IlwiRG9ybCwgSmFtZXMgSiBFc3FcIiIsInN0cmVldCI6IjIzNzEgSmVycm9sZCBBdmUiLCJjaXR5IjoiS3VscHN2aWxsZSIsImNvdW50eSI6Ik1vbnRnb21lcnkiLCJzdGF0ZSI6IlBBIiwiemlwIjoiMTk0NDMiLCJob21lUGhvbmUiOiIyMTUtODc0LTEyMjkiLCJjZWxsUGhvbmUiOiIyMTUtNDIyLTg2OTQiLCJlbWFpbCI6Im1pbm5hX2FtaWdvbkB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5kb3JsamFtZXNqZXNxLmNvbSJ9\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + @Test + void testDynamoDBUpdater() { + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater("DBTable"); + assertNotNull(ddbUpdater); + assertEquals(ddbUpdater.dynamoDBTableName, "DBTable"); + assertNotNull(ddbUpdater.client); + assertNotNull(ddbUpdater.dynamoDB); + assertNotNull(ddbUpdater.dynamoTable); + } + + @Test + void testInsertIntoDynamoDB() { + + ObjectMapper om = new ObjectMapper(); + RabbitMQEvent event = null; + try { + event = om.readValue(mqEventJson, RabbitMQEvent.class); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + String eventSource = event.getEventSource(); + String eventSourceArn = event.getEventSourceArn(); + Map> mapOfMessages = event.getRmqMessagesByQueue(); + mapOfMessages.forEach((k, v) -> { + String currentQueueName = k.substring(0, k.indexOf("::/")); + for (RabbitMQEvent.RabbitMessage thisMessage: v) { + String encodedData = thisMessage.getData(); + String decodedData = new String(Base64.getDecoder().decode(encodedData)); + Person thisPerson = new Person(); + try { + thisPerson = om.readValue(decodedData, Person.class); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + Table dynamoDbTable = mock(Table.class); + AmazonDynamoDB client = mock(AmazonDynamoDB.class); + DynamoDB dynamoDB = mock(DynamoDB.class); + PutItemOutcome putoutcome = mock(PutItemOutcome.class); + LambdaLogger logger = mock(LambdaLogger.class); + DynamoDBUpdater ddbUpdater = new DynamoDBUpdater("DBTable"); + ddbUpdater.client = client; + ddbUpdater.dynamoDB = dynamoDB; + ddbUpdater.dynamoTable = dynamoDbTable; + when(ddbUpdater.dynamoTable.putItem(ArgumentMatchers.any(Item.class))).thenReturn(putoutcome); + PutItemOutcome putOutcome = ddbUpdater.insertIntoDynamoDB(thisMessage, thisPerson, logger, System.currentTimeMillis(), currentQueueName, eventSource, eventSourceArn); + assertNotNull(putOutcome); + } + + }); + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQTest.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQTest.java new file mode 100755 index 000000000..28cd4f90a --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/HandlerRabbitMQTest.java @@ -0,0 +1,655 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +//import com.amazonaws.services.dynamodbv2.document.PutItemOutcome; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +class HandlerRabbitMQTest { + + private static final String mqEventJson = "{\n" + + " \"eventSource\": \"aws:rmq\",\n" + + " \"eventSourceArn\": \"arn:aws:mq:us-west-2:664251831272:broker:ib-rabbitmq-broker:b-22450561-3f76-4004-813d-392346f054fe\",\n" + + " \"rmqMessagesByQueue\": {\n" + + " \"LambdaRabbitMQQueue::/\": [\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 1,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-1\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:1\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 321\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 2,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-2\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:2\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 297\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJBcnQiLCJsYXN0bmFtZSI6IlZlbmVyZSIsImNvbXBhbnkiOiJcIkNoZW1lbCwgSmFtZXMgTCBDcGFcIiIsInN0cmVldCI6IjggVyBDZXJyaXRvcyBBdmUgIzU0IiwiY2l0eSI6IkJyaWRnZXBvcnQiLCJjb3VudHkiOiJHbG91Y2VzdGVyIiwic3RhdGUiOiJOSiIsInppcCI6IjgwMTQiLCJob21lUGhvbmUiOiI4NTYtNjM2LTg3NDkiLCJjZWxsUGhvbmUiOiI4NTYtMjY0LTQxMzAiLCJlbWFpbCI6ImFydEB2ZW5lcmUub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuY2hlbWVsamFtZXNsY3BhLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 3,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-3\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:3\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 302\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0=\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 4,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-4\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:4\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 295\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJEb25ldHRlIiwibGFzdG5hbWUiOiJGb2xsZXIiLCJjb21wYW55IjoiUHJpbnRpbmcgRGltZW5zaW9ucyIsInN0cmVldCI6IjM0IENlbnRlciBTdCIsImNpdHkiOiJIYW1pbHRvbiIsImNvdW50eSI6IkJ1dGxlciIsInN0YXRlIjoiT0giLCJ6aXAiOiI0NTAxMSIsImhvbWVQaG9uZSI6IjUxMy01NzAtMTg5MyIsImNlbGxQaG9uZSI6IjUxMy01NDktNDU2MSIsImVtYWlsIjoiZG9uZXR0ZS5mb2xsZXJAY294Lm5ldCIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnByaW50aW5nZGltZW5zaW9ucy5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 5,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-5\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:5\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 292\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJTaW1vbmEiLCJsYXN0bmFtZSI6Ik1vcmFzY2EiLCJjb21wYW55IjoiXCJDaGFwbWFuLCBSb3NzIEUgRXNxXCIiLCJzdHJlZXQiOiIzIE1jYXVsZXkgRHIiLCJjaXR5IjoiQXNobGFuZCIsImNvdW50eSI6IkFzaGxhbmQiLCJzdGF0ZSI6Ik9IIiwiemlwIjoiNDQ4MDUiLCJob21lUGhvbmUiOiI0MTktNTAzLTI0ODQiLCJjZWxsUGhvbmUiOiI0MTktODAwLTY3NTkiLCJlbWFpbCI6InNpbW9uYUBtb3Jhc2NhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYXBtYW5yb3NzZWVzcS5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 6,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-6\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:6\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 289\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNaXRzdWUiLCJsYXN0bmFtZSI6IlRvbGxuZXIiLCJjb21wYW55IjoiTW9ybG9uZyBBc3NvY2lhdGVzIiwic3RyZWV0IjoiNyBFYWRzIFN0IiwiY2l0eSI6IkNoaWNhZ28iLCJjb3VudHkiOiJDb29rIiwic3RhdGUiOiJJTCIsInppcCI6IjYwNjMyIiwiaG9tZVBob25lIjoiNzczLTU3My02OTE0IiwiY2VsbFBob25lIjoiNzczLTkyNC04NTY1IiwiZW1haWwiOiJtaXRzdWVfdG9sbG5lckB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tb3Jsb25nYXNzb2NpYXRlcy5jb20ifQ==\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 7,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-7\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:7\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 293\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJMZW90YSIsImxhc3RuYW1lIjoiRGlsbGlhcmQiLCJjb21wYW55IjoiQ29tbWVyY2lhbCBQcmVzcyIsInN0cmVldCI6IjcgVyBKYWNrc29uIEJsdmQiLCJjaXR5IjoiU2FuIEpvc2UiLCJjb3VudHkiOiJTYW50YSBDbGFyYSIsInN0YXRlIjoiQ0EiLCJ6aXAiOiI5NTExMSIsImhvbWVQaG9uZSI6IjQwOC03NTItMzUwMCIsImNlbGxQaG9uZSI6IjQwOC04MTMtMTEwNSIsImVtYWlsIjoibGVvdGFAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5jb21tZXJjaWFscHJlc3MuY29tIn0=\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 8,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-8\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:8\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 309\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJTYWdlIiwibGFzdG5hbWUiOiJXaWVzZXIiLCJjb21wYW55IjoiVHJ1aGxhciBBbmQgVHJ1aGxhciBBdHR5cyIsInN0cmVldCI6IjUgQm9zdG9uIEF2ZSAjODgiLCJjaXR5IjoiU2lvdXggRmFsbHMiLCJjb3VudHkiOiJNaW5uZWhhaGEiLCJzdGF0ZSI6IlNEIiwiemlwIjoiNTcxMDUiLCJob21lUGhvbmUiOiI2MDUtNDE0LTIxNDciLCJjZWxsUGhvbmUiOiI2MDUtNzk0LTQ4OTUiLCJlbWFpbCI6InNhZ2Vfd2llc2VyQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy50cnVobGFyYW5kdHJ1aGxhcmF0dHlzLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 9,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-9\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:9\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 312\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJLcmlzIiwibGFzdG5hbWUiOiJNYXJyaWVyIiwiY29tcGFueSI6IlwiS2luZywgQ2hyaXN0b3BoZXIgQSBFc3FcIiIsInN0cmVldCI6IjIyOCBSdW5hbXVjayBQbCAjMjgwOCIsImNpdHkiOiJCYWx0aW1vcmUiLCJjb3VudHkiOiJCYWx0aW1vcmUgQ2l0eSIsInN0YXRlIjoiTUQiLCJ6aXAiOiIyMTIyNCIsImhvbWVQaG9uZSI6IjQxMC02NTUtODcyMyIsImNlbGxQaG9uZSI6IjQxMC04MDQtNDY5NCIsImVtYWlsIjoia3Jpc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5raW5nY2hyaXN0b3BoZXJhZXNxLmNvbSJ9\"\n" + + " },\n" + + " {\n" + + " \"basicProperties\": {\n" + + " \"contentType\": \"text/plain\",\n" + + " \"contentEncoding\": \"UTF-8\",\n" + + " \"headers\": {\n" + + " \"MessageNumberInBatch\": 10,\n" + + " \"MessageBatchIdentifier\": {\n" + + " \"bytes\": [\n" + + " 84,\n" + + " 101,\n" + + " 115,\n" + + " 116,\n" + + " 77,\n" + + " 101,\n" + + " 115,\n" + + " 115,\n" + + " 97,\n" + + " 103,\n" + + " 101,\n" + + " 48,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 48,\n" + + " 50,\n" + + " 45,\n" + + " 50,\n" + + " 48,\n" + + " 50,\n" + + " 51,\n" + + " 45,\n" + + " 48,\n" + + " 49,\n" + + " 45,\n" + + " 48,\n" + + " 55,\n" + + " 45,\n" + + " 50,\n" + + " 48\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"deliveryMode\": 2,\n" + + " \"priority\": 1,\n" + + " \"correlationId\": \"TestMessage03-07-02-2023-01-07-20-10\",\n" + + " \"replyTo\": null,\n" + + " \"expiration\": 60000,\n" + + " \"messageId\": \"TestMessage03-07-02-2023-01-07-20:10\",\n" + + " \"timestamp\": \"Jul 2, 2023, 1:30:34 AM\",\n" + + " \"type\": \"JsonRabbitMQProducer\",\n" + + " \"userId\": \"admin\",\n" + + " \"appId\": \"rabbitmq.producer.JsonRabbitMQProducer\",\n" + + " \"clusterId\": \"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com\",\n" + + " \"bodySize\": 300\n" + + " },\n" + + " \"redelivered\": false,\n" + + " \"data\": \"eyJmaXJzdG5hbWUiOiJNaW5uYSIsImxhc3RuYW1lIjoiQW1pZ29uIiwiY29tcGFueSI6IlwiRG9ybCwgSmFtZXMgSiBFc3FcIiIsInN0cmVldCI6IjIzNzEgSmVycm9sZCBBdmUiLCJjaXR5IjoiS3VscHN2aWxsZSIsImNvdW50eSI6Ik1vbnRnb21lcnkiLCJzdGF0ZSI6IlBBIiwiemlwIjoiMTk0NDMiLCJob21lUGhvbmUiOiIyMTUtODc0LTEyMjkiLCJjZWxsUGhvbmUiOiIyMTUtNDIyLTg2OTQiLCJlbWFpbCI6Im1pbm5hX2FtaWdvbkB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5kb3JsamFtZXNqZXNxLmNvbSJ9\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + @Mock + DynamoDBUpdater ddbUpdater; + + @Test + @ExtendWith(MockitoExtension.class) + void invokeTest() { + + ObjectMapper om = new ObjectMapper(); + //SQSEvent event = gson.fromJson(sqsEventJson, SQSEvent.class); + RabbitMQEvent event = null; + try { + event = om.readValue(mqEventJson, RabbitMQEvent.class); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Context context = new TestContext(); + //PutItemOutcome putItemOutcome = mock(PutItemOutcome.class); + DynamoDBUpdater dbUpdater = mock(DynamoDBUpdater.class); + HandlerRabbitMQ handler = new HandlerRabbitMQ(); + handler.ddbUpdater = dbUpdater; + String result = handler.handleRequest(event, context); + assertEquals(result, "200"); + } + +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestContext.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestContext.java new file mode 100755 index 000000000..71e1c0142 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestContext.java @@ -0,0 +1,45 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.CognitoIdentity; +import com.amazonaws.services.lambda.runtime.ClientContext; +import com.amazonaws.services.lambda.runtime.LambdaLogger; + +public class TestContext implements Context{ + + public TestContext() {} + public String getAwsRequestId(){ + return new String("495b12a8-xmpl-4eca-8168-160484189f99"); + } + public String getLogGroupName(){ + return new String("/aws/lambda/my-function"); + } + public String getLogStreamName(){ + return new String("2020/02/26/[$LATEST]704f8dxmpla04097b9134246b8438f1a"); + } + public String getFunctionName(){ + return new String("my-function"); + } + public String getFunctionVersion(){ + return new String("$LATEST"); + } + public String getInvokedFunctionArn(){ + return new String("arn:aws:lambda:us-east-2:123456789012:function:my-function"); + } + public CognitoIdentity getIdentity(){ + return null; + } + public ClientContext getClientContext(){ + return null; + } + public int getRemainingTimeInMillis(){ + return 300000; + } + public int getMemoryLimitInMB(){ + return 512; + } + public LambdaLogger getLogger(){ + return new TestLogger(); + } + +} \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestLogger.java b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestLogger.java new file mode 100755 index 000000000..d4ebd0af1 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/rabbitmq_event_consumer_function/src/test/java/com/amazonaws/services/lambda/samples/events/rabbitmq/TestLogger.java @@ -0,0 +1,14 @@ +package com.amazonaws.services.lambda.samples.events.rabbitmq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.amazonaws.services.lambda.runtime.LambdaLogger; + +public class TestLogger implements LambdaLogger { + private static final Logger logger = LoggerFactory.getLogger(TestLogger.class); + public void log(String message){ + logger.info(message); + } + public void log(byte[] message){ + logger.info(new String(message)); + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml new file mode 100755 index 000000000..aaf29d21d --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml @@ -0,0 +1,128 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + rabbitmq_event_consumer_function + + Sample SAM Template for rabbitmq-consumer-with-sam + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 15 + +Resources: + LambdaRabbitMQConsumerJavaFunction: + Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Properties: + FunctionName: java-rabbitmq-consumer-dynamodb-sam + CodeUri: rabbitmq_event_consumer_function + Handler: com.amazonaws.services.lambda.samples.events.rabbitmq.HandlerRabbitMQ::handleRequest + Runtime: java21 + Architectures: + - x86_64 + MemorySize: 512 + Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object + Variables: + DYNAMO_DB_TABLE: !Ref RabbitMQDynamoDBTable + JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/ + VpcConfig: + SecurityGroupIds: + - !Ref SecurityGroup + SubnetIds: + - !Ref Subnet1 + - !Ref Subnet2 + - !Ref Subnet3 + Events: + MQEvent: + Type: MQ + Properties: + BatchSize: 10 + MaximumBatchingWindowInSeconds: 5 + Broker: + !Join ['', ["arn:", "aws:", "mq:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "broker:", !Ref RabbitMQBrokerName, ":", !Ref RabbitMQBrokerUniqueString]] + Queues: + - !Ref RabbitMQQueue + SourceAccessConfigurations: + - Type: BASIC_AUTH + URI: + !Join ['', ["arn:", "aws:", "secretsmanager:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "secret:", !Ref SecretsManagerSecretForMQName, "-", !Ref SecretsManagerSecretForMQUniqueString]] + - Type: VIRTUAL_HOST + URI: !Ref RabbitMQVirtualHost + + Policies: + - Statement: + - Sid: RabbitMQPermissionsPolicy + Effect: Allow + Action: + - mq:DescribeBroker + - secretsmanager:GetSecretValue + - ec2:CreateNetworkInterface + - ec2:DeleteNetworkInterface + - ec2:DescribeNetworkInterfaces + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: '*' + - Statement: + - Sid: DynamoDBPermissionsPolicy + Effect: Allow + Action: + - dynamodb:GetItem + - dynamodb:DeleteItem + - dynamodb:PutItem + - dynamodb:Scan + - dynamodb:Query + - dynamodb:UpdateItem + - dynamodb:BatchWriteItem + - dynamodb:BatchGetItem + - dynamodb:DescribeTable + - dynamodb:ConditionCheckItem + Resource: + - !Join ['', ["arn:", "aws:", "dynamodb:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "table/", !Ref RabbitMQDynamoDBTable]] + - !Join ['', ["arn:", "aws:", "dynamodb:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "table/", !Ref RabbitMQDynamoDBTable, "/index/*"]] + + RabbitMQDynamoDBTable: + Type: AWS::Serverless::SimpleTable + Properties: + TableName: RabbitMQDynamoDBTableJava + PrimaryKey: + Name: MessageID + Type: String +Parameters: + RabbitMQBrokerName: + Type: String + Description: Enter the name of the RabbitMQBroker that is part of the ARN + RabbitMQBrokerUniqueString: + Type: String + Description: Enter the unique string of the RabbitMQBroker after the broker name in the ARN + RabbitMQVirtualHost: + Type: String + Description: Enter the name of the RabbitMQ virtualhost from which the lambda function will consume messages + RabbitMQQueue: + Type: String + Description: Enter the name of the RabbitMQ queue from which the lambda function will consume messages + SecretsManagerSecretForMQName: + Type: String + Description: Enter the name of the secret that has username/password for Rabbit MQ + SecretsManagerSecretForMQUniqueString: + Type: String + Description: Enter the unique string of the secret that has username/password for Rabbit MQ + Subnet1: + Type: String + Description: The first of the three private subnets in the RabbitMQ broker's VPC + Subnet2: + Type: String + Description: The second of the three private subnets in the RabbitMQ broker's VPC + Subnet3: + Type: String + Description: The third of the three private subnets in the RabbitMQ broker's VPC + SecurityGroup: + Type: String + Description: The security group associated with this function (use same RabbitMQ) +Outputs: + LambdaRabbitMQConsumerJavaFunction: + Description: "Queue Consumer Lambda Function ARN" + Value: !GetAtt LambdaRabbitMQConsumerJavaFunction.Arn diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/.gitignore b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/.gitignore new file mode 100755 index 000000000..73a5e7b94 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/.gitignore @@ -0,0 +1,53 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +node_modules +npm-debug.log +package-lock.json +package +*out.yml +out.json +bucket-name.txt +target +build +.gradle +*.zip +bin +obj +Gemfile.lock +lib +__pycache__ +*.pyc +.classpath +.factorypath +.project +.settings/* +.aws +.sam +.aws-sam +samconfig.toml +__init__.py +.DS_Store +.project \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/Commands.txt b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/Commands.txt new file mode 100755 index 000000000..05f0899bf --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/Commands.txt @@ -0,0 +1,10 @@ +java -classpath /rabbitmq_message_sender_json/target/json-rabbitmq-producer-0.0.1-SNAPSHOT.jar rabbitmq.producer.JsonRabbitMQProducer + +Example: + +java -classpath /home/ec2-user/JavaExamples/rabbitmq_message_sender_json/target/json-rabbitmq-producer-0.0.1-SNAPSHOT.jar rabbitmq.producer.JsonRabbitMQProducer b-70f77a26-a520-4c7d-bdfe-05z1b885q677aaa.mq.us-west-2.on.aws lambdavhost lambdafanoutexchange lambdaqueue TestMessage021 100 + + +Make sure to put the host name without amqps:// and without port at the end (just the hostname of the RabbitMQ server) + +Also make sure the security group of the RabbitMQ server allows inbound traffic on port 5671 from the security group of the Cloud9 (or EC2 machine) from where you are running this command \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/pom.xml b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/pom.xml new file mode 100755 index 000000000..97cbc12a3 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/pom.xml @@ -0,0 +1,131 @@ + + 4.0.0 + com.amazonaws.services.lambda.samples.events.rabbitmq + json-rabbitmq-producer + 0.0.1-SNAPSHOT + + UTF-8 + 11 + 11 + 2.20.68 + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.11.0 + + + com.google.code.gson + gson + 2.8.9 + + + org.apache.logging.log4j + log4j-api + 2.21.0 + + + org.apache.logging.log4j + log4j-core + 2.21.0 + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + + software.amazon.awssdk + bom + ${aws.java.sdk.version} + pom + import + + + + software.amazon.awssdk + regions + 2.20.68 + + + software.amazon.awssdk + secretsmanager + 2.20.68 + + + + + software.amazon.awssdk + utils + 2.20.68 + + + com.fasterxml.jackson.core + jackson-core + 2.15.1 + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + 2.15.1 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.15.2 + + + com.rabbitmq + amqp-client + 5.25.0 + + + + + + maven-surefire-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.2 + + false + + + + package + + shade + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/JsonRabbitMQProducer.java b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/JsonRabbitMQProducer.java new file mode 100755 index 000000000..83c63a7f4 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/JsonRabbitMQProducer.java @@ -0,0 +1,182 @@ +package rabbitmq.producer; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.AMQP; +import com.rabbitmq.client.BuiltinExchangeType; +import com.rabbitmq.client.Channel; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class JsonRabbitMQProducer { + + Properties prop; + + public static void main(String[] args) { + + String rabbitMQEndpoint = args[0]; + String rabbitMQUsername = SecretsManagerDecoder.getUsernameAndPassword().getUsername(); + String rabbitMQPassword = SecretsManagerDecoder.getUsernameAndPassword().getPassword(); + String rabbitMQVirtualHost = args[1]; + String rabbitMQExchange = args[2]; + String rabbitMQQueue = args[3]; + String seederKeyString = args[4]; + int numberOfMessages = Integer.parseInt(args[5]); + String rabbitMQMessageKey = seederKeyString + "-" + JsonRabbitMQProducer.getTodayDate(); + try { + + JsonRabbitMQProducer.rabbitMQQueueSender(rabbitMQEndpoint, rabbitMQUsername, rabbitMQPassword, rabbitMQVirtualHost, rabbitMQExchange, rabbitMQQueue, rabbitMQMessageKey, numberOfMessages); + System.exit(0); + } catch (Exception e) { + System.out.println("Exception occurred"); + e.printStackTrace(); + System.exit(-1); + } + } + + public static void rabbitMQQueueSender(String rabbitMQEndpoint, String rabbitMQUsername, String rabbitMQPassword, String rabbitMQVirtualHost, String rabbitMQExchange, String rabbitMQQueue, String seederKeyString, int numberOfMessages) throws Exception { + List people = JsonRabbitMQProducer.readDataFile(); + int numberOfMessagesToSend=0; + if (people.size() > numberOfMessages) { + numberOfMessagesToSend = numberOfMessages; + } else { + numberOfMessagesToSend = people.size(); + } + + ConnectionFactory factory = new ConnectionFactory(); + + factory.setUsername(rabbitMQUsername); + factory.setPassword(rabbitMQPassword); + + //Replace the URL with your information + factory.setHost(rabbitMQEndpoint); + factory.setPort(5671); + factory.setVirtualHost(rabbitMQVirtualHost); + + // Allows client to establish a connection over TLS + factory.useSslProtocol(); + + // Create a connection + Connection conn = factory.newConnection(); + + // Create a channel + Channel channel = conn.createChannel(); + channel.exchangeDeclare(rabbitMQExchange, BuiltinExchangeType.FANOUT, true); + channel.queueDeclare(rabbitMQQueue, true, false, false, null); + channel.queueBind(rabbitMQQueue, rabbitMQExchange, rabbitMQExchange.concat("-").concat(rabbitMQQueue)); + try { + for (int i = 1; i <= numberOfMessagesToSend; i++) { + Person thisPerson = JsonRabbitMQProducer.getPersonFromLine(people.get(i)); + String thisPersonJson = thisPerson.toJson(); + byte[] messageBodyBytes = thisPersonJson.getBytes(); + MapheaderMap = new HashMap(); + headerMap.put("MessageBatchIdentifier", seederKeyString); + headerMap.put("MessageNumberInBatch", Integer.valueOf(i)); + AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder() + .appId("rabbitmq.producer.JsonRabbitMQProducer") + .clusterId(rabbitMQEndpoint) + .contentEncoding("UTF-8") + .contentType("text/plain") + .correlationId(seederKeyString.concat("-").concat(Integer.toString(i))) + .deliveryMode(2) + .expiration("60000") + .headers(headerMap) + .messageId(seederKeyString.concat(":").concat(Integer.toString(i))) + .priority(1) + .timestamp(new Date(System.currentTimeMillis())) + .type("JsonRabbitMQProducer") + .userId(rabbitMQUsername) + .build(); + System.out.println("Now sending out one message - Number " + i); + channel.basicPublish(rabbitMQExchange, + rabbitMQExchange.concat("-").concat(rabbitMQQueue), + basicProperties, + messageBodyBytes); + + + + System.out.println("Sent out one message - Number " + i + " at time = " + System.currentTimeMillis()); + } + } catch (Exception e) { + System.out.println("An exception occurred - " + e.getMessage()); + e.printStackTrace(); + } + + } + + public static Properties readPropertiesFile(String fileName) throws FileNotFoundException, IOException { + FileInputStream fis = null; + Properties prop = null; + try { + fis = new FileInputStream(fileName); + prop = new Properties(); + prop.load(fis); + } catch (FileNotFoundException fnfe) { + fnfe.printStackTrace(); + throw new FileNotFoundException("Not a valid property file path"); + } catch (IOException ioe) { + ioe.printStackTrace(); + throw new IOException("Problem reading property file. Check permissions"); + } finally { + fis.close(); + } + return prop; + } + + public static List readDataFile() { + List personList = new ArrayList(); + InputStream is = JsonRabbitMQProducer.class.getClassLoader().getResourceAsStream("us-500.csv"); + BufferedReader bf = new BufferedReader(new InputStreamReader(is)); + String thisLine = null; + try { + thisLine = bf.readLine(); + while (null != thisLine) { + personList.add(thisLine); + thisLine = bf.readLine(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return personList; + } + + public static Person getPersonFromLine(String line) { + + //String[] fields = line.split(","); + String[] fields = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1); + Person thisPerson = new Person(); + thisPerson.setFirstname(fields[0]); + thisPerson.setLastname(fields[1]); + thisPerson.setCompany(fields[2]); + thisPerson.setStreet(fields[3]); + thisPerson.setCity(fields[4]); + thisPerson.setCounty(fields[5]); + thisPerson.setState(fields[6]); + thisPerson.setZip(fields[7]); + thisPerson.setHomePhone(fields[8]); + thisPerson.setCellPhone(fields[9]); + thisPerson.setEmail(fields[10]); + thisPerson.setWebsite(fields[11]); + return thisPerson; + } + + public static String getTodayDate() { + + LocalDateTime ldt = LocalDateTime.now(); + String formattedDateStr = DateTimeFormatter.ofPattern("MM-dd-YYYY-HH-MM-SS").format(ldt); + return formattedDateStr; + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/Person.java b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/Person.java new file mode 100755 index 000000000..77ce7e6d1 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/Person.java @@ -0,0 +1,107 @@ +package rabbitmq.producer; + +import com.google.gson.Gson; + +public class Person { + + String firstname; + String lastname; + String company; + String street; + String city; + String county; + String state; + String zip; + String homePhone; + String cellPhone; + String email; + String website; + public Person() { + super(); + } + public String getFirstname() { + return firstname; + } + public void setFirstname(String firstname) { + this.firstname = firstname; + } + public String getLastname() { + return lastname; + } + public void setLastname(String lastname) { + this.lastname = lastname; + } + public String getCompany() { + return company; + } + public void setCompany(String company) { + this.company = company; + } + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getCounty() { + return county; + } + public void setCounty(String county) { + this.county = county; + } + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + public String getZip() { + return zip; + } + public void setZip(String zip) { + this.zip = zip; + } + public String getHomePhone() { + return homePhone; + } + public void setHomePhone(String homePhone) { + this.homePhone = homePhone; + } + public String getCellPhone() { + return cellPhone; + } + public void setCellPhone(String cellPhone) { + this.cellPhone = cellPhone; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getWebsite() { + return website; + } + public void setWebsite(String website) { + this.website = website; + } + @Override + public String toString() { + return "Person [firstname=" + firstname + ", lastname=" + lastname + ", company=" + company + ", street=" + + street + ", city=" + city + ", county=" + county + ", state=" + state + ", zip=" + zip + + ", homePhone=" + homePhone + ", cellPhone=" + cellPhone + ", email=" + email + ", website=" + website + + "]"; + } + + public String toJson() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/SecretsManagerDecoder.java b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/SecretsManagerDecoder.java new file mode 100755 index 000000000..def8d7e09 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/SecretsManagerDecoder.java @@ -0,0 +1,47 @@ +package rabbitmq.producer; + +import com.google.gson.Gson; + +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; +import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; +import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse; + +public class SecretsManagerDecoder { + + public static String getSecret() { + + String secretName = "AmazonRabbitMQCredentials"; + + DefaultAwsRegionProviderChain defaultAwsRegionProviderChain = new DefaultAwsRegionProviderChain(); + Region region = defaultAwsRegionProviderChain.getRegion(); + System.out.println("region = " + region.toString()); + + SecretsManagerClient client = SecretsManagerClient.builder() + .region(region) + .build(); + + GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder() + .secretId(secretName) + .build(); + + GetSecretValueResponse getSecretValueResponse = null; + + try { + getSecretValueResponse = client.getSecretValue(getSecretValueRequest); + } catch (Exception e) { + e.printStackTrace(); + } + if (null != getSecretValueResponse) { + return getSecretValueResponse.secretString(); + } else { + return "Sorry mate! No secret found"; + } + } + + public static User getUsernameAndPassword() { + Gson gson = new Gson(); + return gson.fromJson(SecretsManagerDecoder.getSecret(), User.class); + } +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/User.java b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/User.java new file mode 100755 index 000000000..653e7ab2a --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/java/rabbitmq/producer/User.java @@ -0,0 +1,67 @@ +package rabbitmq.producer; + +import java.util.Objects; + +public class User { + String username; + String password; + /** + * + */ + public User() { + super(); + } + /** + * @param username + * @param password + */ + public User(String username, String password) { + super(); + this.username = username; + this.password = password; + } + /** + * @return the username + */ + public String getUsername() { + return username; + } + /** + * @param username the username to set + */ + public void setUsername(String username) { + this.username = username; + } + /** + * @return the password + */ + public String getPassword() { + return password; + } + /** + * @param password the password to set + */ + public void setPassword(String password) { + this.password = password; + } + @Override + public int hashCode() { + return Objects.hash(password, username); + } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof User)) { + return false; + } + User other = (User) obj; + return Objects.equals(password, other.password) && Objects.equals(username, other.username); + } + @Override + public String toString() { + return "User [username=" + username + ", password=" + password + "]"; + } + +} diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/resources/us-500.csv b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/resources/us-500.csv new file mode 100755 index 000000000..20c58066e --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/src/main/resources/us-500.csv @@ -0,0 +1,500 @@ +James,Butt,"Benton, John B Jr",6649 N Blue Gum St,New Orleans,Orleans,LA,70116,504-621-8927,504-845-1427,jbutt@gmail.com,http://www.bentonjohnbjr.com +Josephine,Darakjy,"Chanay, Jeffrey A Esq",4 B Blue Ridge Blvd,Brighton,Livingston,MI,48116,810-292-9388,810-374-9840,josephine_darakjy@darakjy.org,http://www.chanayjeffreyaesq.com +Art,Venere,"Chemel, James L Cpa",8 W Cerritos Ave #54,Bridgeport,Gloucester,NJ,8014,856-636-8749,856-264-4130,art@venere.org,http://www.chemeljameslcpa.com +Lenna,Paprocki,Feltz Printing Service,639 Main St,Anchorage,Anchorage,AK,99501,907-385-4412,907-921-2010,lpaprocki@hotmail.com,http://www.feltzprintingservice.com +Donette,Foller,Printing Dimensions,34 Center St,Hamilton,Butler,OH,45011,513-570-1893,513-549-4561,donette.foller@cox.net,http://www.printingdimensions.com +Simona,Morasca,"Chapman, Ross E Esq",3 Mcauley Dr,Ashland,Ashland,OH,44805,419-503-2484,419-800-6759,simona@morasca.com,http://www.chapmanrosseesq.com +Mitsue,Tollner,Morlong Associates,7 Eads St,Chicago,Cook,IL,60632,773-573-6914,773-924-8565,mitsue_tollner@yahoo.com,http://www.morlongassociates.com +Leota,Dilliard,Commercial Press,7 W Jackson Blvd,San Jose,Santa Clara,CA,95111,408-752-3500,408-813-1105,leota@hotmail.com,http://www.commercialpress.com +Sage,Wieser,Truhlar And Truhlar Attys,5 Boston Ave #88,Sioux Falls,Minnehaha,SD,57105,605-414-2147,605-794-4895,sage_wieser@cox.net,http://www.truhlarandtruhlarattys.com +Kris,Marrier,"King, Christopher A Esq",228 Runamuck Pl #2808,Baltimore,Baltimore City,MD,21224,410-655-8723,410-804-4694,kris@gmail.com,http://www.kingchristopheraesq.com +Minna,Amigon,"Dorl, James J Esq",2371 Jerrold Ave,Kulpsville,Montgomery,PA,19443,215-874-1229,215-422-8694,minna_amigon@yahoo.com,http://www.dorljamesjesq.com +Abel,Maclead,Rangoni Of Florence,37275 St Rt 17m M,Middle Island,Suffolk,NY,11953,631-335-3414,631-677-3675,amaclead@gmail.com,http://www.rangoniofflorence.com +Kiley,Caldarera,Feiner Bros,25 E 75th St #69,Los Angeles,Los Angeles,CA,90034,310-498-5651,310-254-3084,kiley.caldarera@aol.com,http://www.feinerbros.com +Graciela,Ruta,Buckley Miller & Wright,98 Connecticut Ave Nw,Chagrin Falls,Geauga,OH,44023,440-780-8425,440-579-7763,gruta@cox.net,http://www.buckleymillerwright.com +Cammy,Albares,"Rousseaux, Michael Esq",56 E Morehead St,Laredo,Webb,TX,78045,956-537-6195,956-841-7216,calbares@gmail.com,http://www.rousseauxmichaelesq.com +Mattie,Poquette,Century Communications,73 State Road 434 E,Phoenix,Maricopa,AZ,85013,602-277-4385,602-953-6360,mattie@aol.com,http://www.centurycommunications.com +Meaghan,Garufi,"Bolton, Wilbur Esq",69734 E Carrillo St,Mc Minnville,Warren,TN,37110,931-313-9635,931-235-7959,meaghan@hotmail.com,http://www.boltonwilburesq.com +Gladys,Rim,T M Byxbee Company Pc,322 New Horizon Blvd,Milwaukee,Milwaukee,WI,53207,414-661-9598,414-377-2880,gladys.rim@rim.org,http://www.tmbyxbeecompanypc.com +Yuki,Whobrey,Farmers Insurance Group,1 State Route 27,Taylor,Wayne,MI,48180,313-288-7937,313-341-4470,yuki_whobrey@aol.com,http://www.farmersinsurancegroup.com +Fletcher,Flosi,Post Box Services Plus,394 Manchester Blvd,Rockford,Winnebago,IL,61109,815-828-2147,815-426-5657,fletcher.flosi@yahoo.com,http://www.postboxservicesplus.com +Bette,Nicka,Sport En Art,6 S 33rd St,Aston,Delaware,PA,19014,610-545-3615,610-492-4643,bette_nicka@cox.net,http://www.sportenart.com +Veronika,Inouye,C 4 Network Inc,6 Greenleaf Ave,San Jose,Santa Clara,CA,95111,408-540-1785,408-813-4592,vinouye@aol.com,http://www.cnetworkinc.com +Willard,Kolmetz,"Ingalls, Donald R Esq",618 W Yakima Ave,Irving,Dallas,TX,75062,972-303-9197,972-896-4882,willard@hotmail.com,http://www.ingallsdonaldresq.com +Maryann,Royster,"Franklin, Peter L Esq",74 S Westgate St,Albany,Albany,NY,12204,518-966-7987,518-448-8982,mroyster@royster.com,http://www.franklinpeterlesq.com +Alisha,Slusarski,Wtlz Power 107 Fm,3273 State St,Middlesex,Middlesex,NJ,8846,732-658-3154,732-635-3453,alisha@slusarski.com,http://www.wtlzpowerfm.com +Allene,Iturbide,"Ledecky, David Esq",1 Central Ave,Stevens Point,Portage,WI,54481,715-662-6764,715-530-9863,allene_iturbide@cox.net,http://www.ledeckydavidesq.com +Chanel,Caudy,Professional Image Inc,86 Nw 66th St #8673,Shawnee,Johnson,KS,66218,913-388-2079,913-899-1103,chanel.caudy@caudy.org,http://www.professionalimageinc.com +Ezekiel,Chui,"Sider, Donald C Esq",2 Cedar Ave #84,Easton,Talbot,MD,21601,410-669-1642,410-235-8738,ezekiel@chui.com,http://www.siderdonaldcesq.com +Willow,Kusko,U Pull It,90991 Thorburn Ave,New York,New York,NY,10011,212-582-4976,212-934-5167,wkusko@yahoo.com,http://www.upullit.com +Bernardo,Figeroa,"Clark, Richard Cpa",386 9th Ave N,Conroe,Montgomery,TX,77301,936-336-3951,936-597-3614,bfigeroa@aol.com,http://www.clarkrichardcpa.com +Ammie,Corrio,"Moskowitz, Barry S",74874 Atlantic Ave,Columbus,Franklin,OH,43215,614-801-9788,614-648-3265,ammie@corrio.com,http://www.moskowitzbarrys.com +Francine,Vocelka,Cascade Realty Advisors Inc,366 South Dr,Las Cruces,Dona Ana,NM,88011,505-977-3911,505-335-5293,francine_vocelka@vocelka.com,http://www.cascaderealtyadvisorsinc.com +Ernie,Stenseth,Knwz Newsradio,45 E Liberty St,Ridgefield Park,Bergen,NJ,7660,201-709-6245,201-387-9093,ernie_stenseth@aol.com,http://www.knwznewsradio.com +Albina,Glick,"Giampetro, Anthony D",4 Ralph Ct,Dunellen,Middlesex,NJ,8812,732-924-7882,732-782-6701,albina@glick.com,http://www.giampetroanthonyd.com +Alishia,Sergi,Milford Enterprises Inc,2742 Distribution Way,New York,New York,NY,10025,212-860-1579,212-753-2740,asergi@gmail.com,http://www.milfordenterprisesinc.com +Solange,Shinko,"Mosocco, Ronald A",426 Wolf St,Metairie,Jefferson,LA,70002,504-979-9175,504-265-8174,solange@shinko.com,http://www.mosoccoronalda.com +Jose,Stockham,Tri State Refueler Co,128 Bransten Rd,New York,New York,NY,10011,212-675-8570,212-569-4233,jose@yahoo.com,http://www.tristaterefuelerco.com +Rozella,Ostrosky,Parkway Company,17 Morena Blvd,Camarillo,Ventura,CA,93012,805-832-6163,805-609-1531,rozella.ostrosky@ostrosky.com,http://www.parkwaycompany.com +Valentine,Gillian,Fbs Business Finance,775 W 17th St,San Antonio,Bexar,TX,78204,210-812-9597,210-300-6244,valentine_gillian@gmail.com,http://www.fbsbusinessfinance.com +Kati,Rulapaugh,Eder Assocs Consltng Engrs Pc,6980 Dorsett Rd,Abilene,Dickinson,KS,67410,785-463-7829,785-219-7724,kati.rulapaugh@hotmail.com,http://www.ederassocsconsltngengrspc.com +Youlanda,Schemmer,Tri M Tool Inc,2881 Lewis Rd,Prineville,Crook,OR,97754,541-548-8197,541-993-2611,youlanda@aol.com,http://www.trimtoolinc.com +Dyan,Oldroyd,International Eyelets Inc,7219 Woodfield Rd,Overland Park,Johnson,KS,66204,913-413-4604,913-645-8918,doldroyd@aol.com,http://www.internationaleyeletsinc.com +Roxane,Campain,Rapid Trading Intl,1048 Main St,Fairbanks,Fairbanks North Star,AK,99708,907-231-4722,907-335-6568,roxane@hotmail.com,http://www.rapidtradingintl.com +Lavera,Perin,Abc Enterprises Inc,678 3rd Ave,Miami,Miami-Dade,FL,33196,305-606-7291,305-995-2078,lperin@perin.org,http://www.abcenterprisesinc.com +Erick,Ferencz,Cindy Turner Associates,20 S Babcock St,Fairbanks,Fairbanks North Star,AK,99712,907-741-1044,907-227-6777,erick.ferencz@aol.com,http://www.cindyturnerassociates.com +Fatima,Saylors,"Stanton, James D Esq",2 Lighthouse Ave,Hopkins,Hennepin,MN,55343,952-768-2416,952-479-2375,fsaylors@saylors.org,http://www.stantonjamesdesq.com +Jina,Briddick,Grace Pastries Inc,38938 Park Blvd,Boston,Suffolk,MA,2128,617-399-5124,617-997-5771,jina_briddick@briddick.com,http://www.gracepastriesinc.com +Kanisha,Waycott,"Schroer, Gene E Esq",5 Tomahawk Dr,Los Angeles,Los Angeles,CA,90006,323-453-2780,323-315-7314,kanisha_waycott@yahoo.com,http://www.schroergeneeesq.com +Emerson,Bowley,Knights Inn,762 S Main St,Madison,Dane,WI,53711,608-336-7444,608-658-7940,emerson.bowley@bowley.org,http://www.knightsinn.com +Blair,Malet,Bollinger Mach Shp & Shipyard,209 Decker Dr,Philadelphia,Philadelphia,PA,19132,215-907-9111,215-794-4519,bmalet@yahoo.com,http://www.bollingermachshpshipyard.com +Brock,Bolognia,Orinda News,4486 W O St #1,New York,New York,NY,10003,212-402-9216,212-617-5063,bbolognia@yahoo.com,http://www.orindanews.com +Lorrie,Nestle,Ballard Spahr Andrews,39 S 7th St,Tullahoma,Coffee,TN,37388,931-875-6644,931-303-6041,lnestle@hotmail.com,http://www.ballardspahrandrews.com +Sabra,Uyetake,Lowy Limousine Service,98839 Hawthorne Blvd #6101,Columbia,Richland,SC,29201,803-925-5213,803-681-3678,sabra@uyetake.org,http://www.lowylimousineservice.com +Marjory,Mastella,Vicon Corporation,71 San Mateo Ave,Wayne,Delaware,PA,19087,610-814-5533,610-379-7125,mmastella@mastella.com,http://www.viconcorporation.com +Karl,Klonowski,"Rossi, Michael M",76 Brooks St #9,Flemington,Hunterdon,NJ,8822,908-877-6135,908-470-4661,karl_klonowski@yahoo.com,http://www.rossimichaelm.com +Tonette,Wenner,Northwest Publishing,4545 Courthouse Rd,Westbury,Nassau,NY,11590,516-968-6051,516-333-4861,twenner@aol.com,http://www.northwestpublishing.com +Amber,Monarrez,Branford Wire & Mfg Co,14288 Foster Ave #4121,Jenkintown,Montgomery,PA,19046,215-934-8655,215-329-6386,amber_monarrez@monarrez.org,http://www.branfordwiremfgco.com +Shenika,Seewald,East Coast Marketing,4 Otis St,Van Nuys,Los Angeles,CA,91405,818-423-4007,818-749-8650,shenika@gmail.com,http://www.eastcoastmarketing.com +Delmy,Ahle,Wye Technologies Inc,65895 S 16th St,Providence,Providence,RI,2909,401-458-2547,401-559-8961,delmy.ahle@hotmail.com,http://www.wyetechnologiesinc.com +Deeanna,Juhas,"Healy, George W Iv",14302 Pennsylvania Ave,Huntingdon Valley,Montgomery,PA,19006,215-211-9589,215-417-9563,deeanna_juhas@gmail.com,http://www.healygeorgewiv.com +Blondell,Pugh,Alpenlite Inc,201 Hawk Ct,Providence,Providence,RI,2904,401-960-8259,401-300-8122,bpugh@aol.com,http://www.alpenliteinc.com +Jamal,Vanausdal,"Hubbard, Bruce Esq",53075 Sw 152nd Ter #615,Monroe Township,Middlesex,NJ,8831,732-234-1546,732-904-2931,jamal@vanausdal.org,http://www.hubbardbruceesq.com +Cecily,Hollack,Arthur A Oliver & Son Inc,59 N Groesbeck Hwy,Austin,Travis,TX,78731,512-486-3817,512-861-3814,cecily@hollack.org,http://www.arthuraoliversoninc.com +Carmelina,Lindall,George Jessop Carter Jewelers,2664 Lewis Rd,Littleton,Douglas,CO,80126,303-724-7371,303-874-5160,carmelina_lindall@lindall.com,http://www.georgejessopcarterjewelers.com +Maurine,Yglesias,"Schultz, Thomas C Md",59 Shady Ln #53,Milwaukee,Milwaukee,WI,53214,414-748-1374,414-573-7719,maurine_yglesias@yglesias.com,http://www.schultzthomascmd.com +Tawna,Buvens,H H H Enterprises Inc,3305 Nabell Ave #679,New York,New York,NY,10009,212-674-9610,212-462-9157,tawna@gmail.com,http://www.hhhenterprisesinc.com +Penney,Weight,Hawaiian King Hotel,18 Fountain St,Anchorage,Anchorage,AK,99515,907-797-9628,907-873-2882,penney_weight@aol.com,http://www.hawaiiankinghotel.com +Elly,Morocco,Killion Industries,7 W 32nd St,Erie,Erie,PA,16502,814-393-5571,814-420-3553,elly_morocco@gmail.com,http://www.killionindustries.com +Ilene,Eroman,"Robinson, William J Esq",2853 S Central Expy,Glen Burnie,Anne Arundel,MD,21061,410-914-9018,410-937-4543,ilene.eroman@hotmail.com,http://www.robinsonwilliamjesq.com +Vallie,Mondella,Private Properties,74 W College St,Boise,Ada,ID,83707,208-862-5339,208-737-8439,vmondella@mondella.com,http://www.privateproperties.com +Kallie,Blackwood,Rowley Schlimgen Inc,701 S Harrison Rd,San Francisco,San Francisco,CA,94104,415-315-2761,415-604-7609,kallie.blackwood@gmail.com,http://www.rowleyschlimgeninc.com +Johnetta,Abdallah,Forging Specialties,1088 Pinehurst St,Chapel Hill,Orange,NC,27514,919-225-9345,919-715-3791,johnetta_abdallah@aol.com,http://www.forgingspecialties.com +Bobbye,Rhym,"Smits, Patricia Garity",30 W 80th St #1995,San Carlos,San Mateo,CA,94070,650-528-5783,650-811-9032,brhym@rhym.com,http://www.smitspatriciagarity.com +Micaela,Rhymes,H Lee Leonard Attorney At Law,20932 Hedley St,Concord,Contra Costa,CA,94520,925-647-3298,925-522-7798,micaela_rhymes@gmail.com,http://www.hleeleonardattorneyatlaw.com +Tamar,Hoogland,A K Construction Co,2737 Pistorio Rd #9230,London,Madison,OH,43140,740-343-8575,740-526-5410,tamar@hotmail.com,http://www.akconstructionco.com +Moon,Parlato,"Ambelang, Jessica M Md",74989 Brandon St,Wellsville,Allegany,NY,14895,585-866-8313,585-498-4278,moon@yahoo.com,http://www.ambelangjessicammd.com +Laurel,Reitler,Q A Service,6 Kains Ave,Baltimore,Baltimore City,MD,21215,410-520-4832,410-957-6903,laurel_reitler@reitler.com,http://www.qaservice.com +Delisa,Crupi,Wood & Whitacre Contractors,47565 W Grand Ave,Newark,Essex,NJ,7105,973-354-2040,973-847-9611,delisa.crupi@crupi.com,http://www.woodwhitacrecontractors.com +Viva,Toelkes,Mark Iv Press Ltd,4284 Dorigo Ln,Chicago,Cook,IL,60647,773-446-5569,773-352-3437,viva.toelkes@gmail.com,http://www.markivpressltd.com +Elza,Lipke,Museum Of Science & Industry,6794 Lake Dr E,Newark,Essex,NJ,7104,973-927-3447,973-796-3667,elza@yahoo.com,http://www.museumofscienceindustry.com +Devorah,Chickering,Garrison Ind,31 Douglas Blvd #950,Clovis,Curry,NM,88101,505-975-8559,505-950-1763,devorah@hotmail.com,http://www.garrisonind.com +Timothy,Mulqueen,Saronix Nymph Products,44 W 4th St,Staten Island,Richmond,NY,10309,718-332-6527,718-654-7063,timothy_mulqueen@mulqueen.org,http://www.saronixnymphproducts.com +Arlette,Honeywell,Smc Inc,11279 Loytan St,Jacksonville,Duval,FL,32254,904-775-4480,904-514-9918,ahoneywell@honeywell.com,http://www.smcinc.com +Dominque,Dickerson,E A I Electronic Assocs Inc,69 Marquette Ave,Hayward,Alameda,CA,94545,510-993-3758,510-901-7640,dominque.dickerson@dickerson.org,http://www.eaielectronicassocsinc.com +Lettie,Isenhower,"Conte, Christopher A Esq",70 W Main St,Beachwood,Cuyahoga,OH,44122,216-657-7668,216-733-8494,lettie_isenhower@yahoo.com,http://www.contechristopheraesq.com +Myra,Munns,Anker Law Office,461 Prospect Pl #316,Euless,Tarrant,TX,76040,817-914-7518,817-451-3518,mmunns@cox.net,http://www.ankerlawoffice.com +Stephaine,Barfield,Beutelschies & Company,47154 Whipple Ave Nw,Gardena,Los Angeles,CA,90247,310-774-7643,310-968-1219,stephaine@barfield.com,http://www.beutelschiescompany.com +Lai,Gato,"Fligg, Kenneth I Jr",37 Alabama Ave,Evanston,Cook,IL,60201,847-728-7286,847-957-4614,lai.gato@gato.org,http://www.fliggkennethijr.com +Stephen,Emigh,"Sharp, J Daniel Esq",3777 E Richmond St #900,Akron,Summit,OH,44302,330-537-5358,330-700-2312,stephen_emigh@hotmail.com,http://www.sharpjdanielesq.com +Tyra,Shields,"Assink, Anne H Esq",3 Fort Worth Ave,Philadelphia,Philadelphia,PA,19106,215-255-1641,215-228-8264,tshields@gmail.com,http://www.assinkannehesq.com +Tammara,Wardrip,Jewel My Shop Inc,4800 Black Horse Pike,Burlingame,San Mateo,CA,94010,650-803-1936,650-216-5075,twardrip@cox.net,http://www.jewelmyshopinc.com +Cory,Gibes,Chinese Translation Resources,83649 W Belmont Ave,San Gabriel,Los Angeles,CA,91776,626-572-1096,626-696-2777,cory.gibes@gmail.com,http://www.chinesetranslationresources.com +Danica,Bruschke,"Stevens, Charles T",840 15th Ave,Waco,McLennan,TX,76708,254-782-8569,254-205-1422,danica_bruschke@gmail.com,http://www.stevenscharlest.com +Wilda,Giguere,"Mclaughlin, Luther W Cpa",1747 Calle Amanecer #2,Anchorage,Anchorage,AK,99501,907-870-5536,907-914-9482,wilda@cox.net,http://www.mclaughlinlutherwcpa.com +Elvera,Benimadho,Tree Musketeers,99385 Charity St #840,San Jose,Santa Clara,CA,95110,408-703-8505,408-440-8447,elvera.benimadho@cox.net,http://www.treemusketeers.com +Carma,Vanheusen,Springfield Div Oh Edison Co,68556 Central Hwy,San Leandro,Alameda,CA,94577,510-503-7169,510-452-4835,carma@cox.net,http://www.springfielddivohedisonco.com +Malinda,Hochard,Logan Memorial Hospital,55 Riverside Ave,Indianapolis,Marion,IN,46202,317-722-5066,317-472-2412,malinda.hochard@yahoo.com,http://www.loganmemorialhospital.com +Natalie,Fern,"Kelly, Charles G Esq",7140 University Ave,Rock Springs,Sweetwater,WY,82901,307-704-8713,307-279-3793,natalie.fern@hotmail.com,http://www.kellycharlesgesq.com +Lisha,Centini,Industrial Paper Shredders Inc,64 5th Ave #1153,Mc Lean,Fairfax,VA,22102,703-235-3937,703-475-7568,lisha@centini.org,http://www.industrialpapershreddersinc.com +Arlene,Klusman,Beck Horizon Builders,3 Secor Rd,New Orleans,Orleans,LA,70112,504-710-5840,504-946-1807,arlene_klusman@gmail.com,http://www.beckhorizonbuilders.com +Alease,Buemi,Porto Cayo At Hawks Cay,4 Webbs Chapel Rd,Boulder,Boulder,CO,80303,303-301-4946,303-521-9860,alease@buemi.com,http://www.portocayoathawkscay.com +Louisa,Cronauer,Pacific Grove Museum Ntrl Hist,524 Louisiana Ave Nw,San Leandro,Alameda,CA,94577,510-828-7047,510-472-7758,louisa@cronauer.com,http://www.pacificgrovemuseumntrlhist.com +Angella,Cetta,Bender & Hatley Pc,185 Blackstone Bldge,Honolulu,Honolulu,HI,96817,808-892-7943,808-475-2310,angella.cetta@hotmail.com,http://www.benderhatleypc.com +Cyndy,Goldammer,Di Cristina J & Son,170 Wyoming Ave,Burnsville,Dakota,MN,55337,952-334-9408,952-938-9457,cgoldammer@cox.net,http://www.dicristinajson.com +Rosio,Cork,Green Goddess,4 10th St W,High Point,Guilford,NC,27263,336-243-5659,336-497-4407,rosio.cork@gmail.com,http://www.greengoddess.com +Celeste,Korando,American Arts & Graphics,7 W Pinhook Rd,Lynbrook,Nassau,NY,11563,516-509-2347,516-365-7266,ckorando@hotmail.com,http://www.americanartsgraphics.com +Twana,Felger,Opryland Hotel,1 Commerce Way,Portland,Washington,OR,97224,503-939-3153,503-909-7167,twana.felger@felger.org,http://www.oprylandhotel.com +Estrella,Samu,Marking Devices Pubg Co,64 Lakeview Ave,Beloit,Rock,WI,53511,608-976-7199,608-942-8836,estrella@aol.com,http://www.markingdevicespubgco.com +Donte,Kines,W Tc Industries Inc,3 Aspen St,Worcester,Worcester,MA,1602,508-429-8576,508-843-1426,dkines@hotmail.com,http://www.wtcindustriesinc.com +Tiffiny,Steffensmeier,Whitehall Robbins Labs Divsn,32860 Sierra Rd,Miami,Miami-Dade,FL,33133,305-385-9695,305-304-6573,tiffiny_steffensmeier@cox.net,http://www.whitehallrobbinslabsdivsn.com +Edna,Miceli,Sampler,555 Main St,Erie,Erie,PA,16502,814-460-2655,814-299-2877,emiceli@miceli.org,http://www.sampler.com +Sue,Kownacki,Juno Chefs Incorporated,2 Se 3rd Ave,Mesquite,Dallas,TX,75149,972-666-3413,972-742-4000,sue@aol.com,http://www.junochefsincorporated.com +Jesusa,Shin,"Carroccio, A Thomas Esq",2239 Shawnee Mission Pky,Tullahoma,Coffee,TN,37388,931-273-8709,931-739-1551,jshin@shin.com,http://www.carroccioathomasesq.com +Rolland,Francescon,"Stanley, Richard L Esq",2726 Charcot Ave,Paterson,Passaic,NJ,7501,973-649-2922,973-284-4048,rolland@cox.net,http://www.stanleyrichardlesq.com +Pamella,Schmierer,K Cs Cstm Mouldings Windows,5161 Dorsett Rd,Homestead,Miami-Dade,FL,33030,305-420-8970,305-575-8481,pamella.schmierer@schmierer.org,http://www.kcscstmmouldingswindows.com +Glory,Kulzer,Comfort Inn,55892 Jacksonville Rd,Owings Mills,Baltimore,MD,21117,410-224-9462,410-916-8015,gkulzer@kulzer.org,http://www.comfortinn.com +Shawna,Palaspas,"Windsor, James L Esq",5 N Cleveland Massillon Rd,Thousand Oaks,Ventura,CA,91362,805-275-3566,805-638-6617,shawna_palaspas@palaspas.org,http://www.windsorjameslesq.com +Brandon,Callaro,Jackson Shields Yeiser,7 Benton Dr,Honolulu,Honolulu,HI,96819,808-215-6832,808-240-5168,brandon_callaro@hotmail.com,http://www.jacksonshieldsyeiser.com +Scarlet,Cartan,"Box, J Calvin Esq",9390 S Howell Ave,Albany,Dougherty,GA,31701,229-735-3378,229-365-9658,scarlet.cartan@yahoo.com,http://www.boxjcalvinesq.com +Oretha,Menter,Custom Engineering Inc,8 County Center Dr #647,Boston,Suffolk,MA,2210,617-418-5043,617-697-6024,oretha_menter@yahoo.com,http://www.customengineeringinc.com +Ty,Smith,Bresler Eitel Framg Gllry Ltd,4646 Kaahumanu St,Hackensack,Bergen,NJ,7601,201-672-1553,201-995-3149,tsmith@aol.com,http://www.breslereitelframggllryltd.com +Xuan,Rochin,"Carol, Drake Sparks Esq",2 Monroe St,San Mateo,San Mateo,CA,94403,650-933-5072,650-247-2625,xuan@gmail.com,http://www.caroldrakesparksesq.com +Lindsey,Dilello,Biltmore Investors Bank,52777 Leaders Heights Rd,Ontario,San Bernardino,CA,91761,909-639-9887,909-589-1693,lindsey.dilello@hotmail.com,http://www.biltmoreinvestorsbank.com +Devora,Perez,Desco Equipment Corp,72868 Blackington Ave,Oakland,Alameda,CA,94606,510-955-3016,510-755-9274,devora_perez@perez.org,http://www.descoequipmentcorp.com +Herman,Demesa,Merlin Electric Co,9 Norristown Rd,Troy,Rensselaer,NY,12180,518-497-2940,518-931-7852,hdemesa@cox.net,http://www.merlinelectricco.com +Rory,Papasergi,Bailey Cntl Co Div Babcock,83 County Road 437 #8581,Clarks Summit,Lackawanna,PA,18411,570-867-7489,570-469-8401,rpapasergi@cox.net,http://www.baileycntlcodivbabcock.com +Talia,Riopelle,Ford Brothers Wholesale Inc,1 N Harlem Ave #9,Orange,Essex,NJ,7050,973-245-2133,973-818-9788,talia_riopelle@aol.com,http://www.fordbrotherswholesaleinc.com +Van,Shire,Cambridge Inn,90131 J St,Pittstown,Hunterdon,NJ,8867,908-409-2890,908-448-1209,van.shire@shire.com,http://www.cambridgeinn.com +Lucina,Lary,"Matricciani, Albert J Jr",8597 W National Ave,Cocoa,Brevard,FL,32922,321-749-4981,321-632-4668,lucina_lary@cox.net,http://www.matriccianialbertjjr.com +Bok,Isaacs,Nelson Hawaiian Ltd,6 Gilson St,Bronx,Bronx,NY,10468,718-809-3762,718-478-8568,bok.isaacs@aol.com,http://www.nelsonhawaiianltd.com +Rolande,Spickerman,Neland Travel Agency,65 W Maple Ave,Pearl City,Honolulu,HI,96782,808-315-3077,808-526-5863,rolande.spickerman@spickerman.com,http://www.nelandtravelagency.com +Howard,Paulas,"Asendorf, J Alan Esq",866 34th Ave,Denver,Denver,CO,80231,303-623-4241,303-692-3118,hpaulas@gmail.com,http://www.asendorfjalanesq.com +Kimbery,Madarang,"Silberman, Arthur L Esq",798 Lund Farm Way,Rockaway,Morris,NJ,7866,973-310-1634,973-225-6259,kimbery_madarang@cox.net,http://www.silbermanarthurlesq.com +Thurman,Manno,Honey Bee Breeding Genetics &,9387 Charcot Ave,Absecon,Atlantic,NJ,8201,609-524-3586,609-234-8376,thurman.manno@yahoo.com,http://www.honeybeebreedinggenetics.com +Becky,Mirafuentes,Wells Kravitz Schnitzer,30553 Washington Rd,Plainfield,Union,NJ,7062,908-877-8409,908-426-8272,becky.mirafuentes@mirafuentes.com,http://www.wellskravitzschnitzer.com +Beatriz,Corrington,Prohab Rehabilitation Servs,481 W Lemon St,Middleboro,Plymouth,MA,2346,508-584-4279,508-315-3867,beatriz@yahoo.com,http://www.prohabrehabilitationservs.com +Marti,Maybury,"Eldridge, Kristin K Esq",4 Warehouse Point Rd #7,Chicago,Cook,IL,60638,773-775-4522,773-539-1058,marti.maybury@yahoo.com,http://www.eldridgekristinkesq.com +Nieves,Gotter,"Vlahos, John J Esq",4940 Pulaski Park Dr,Portland,Multnomah,OR,97202,503-527-5274,503-455-3094,nieves_gotter@gmail.com,http://www.vlahosjohnjesq.com +Leatha,Hagele,Ninas Indian Grs & Videos,627 Walford Ave,Dallas,Dallas,TX,75227,214-339-1809,214-225-5850,lhagele@cox.net,http://www.ninasindiangrsvideos.com +Valentin,Klimek,"Schmid, Gayanne K Esq",137 Pioneer Way,Chicago,Cook,IL,60604,312-303-5453,312-512-2338,vklimek@klimek.org,http://www.schmidgayannekesq.com +Melissa,Wiklund,Moapa Valley Federal Credit Un,61 13 Stoneridge #835,Findlay,Hancock,OH,45840,419-939-3613,419-254-4591,melissa@cox.net,http://www.moapavalleyfederalcreditun.com +Sheridan,Zane,Kentucky Tennessee Clay Co,2409 Alabama Rd,Riverside,Riverside,CA,92501,951-645-3605,951-248-6822,sheridan.zane@zane.com,http://www.kentuckytennesseeclayco.com +Bulah,Padilla,Admiral Party Rentals & Sales,8927 Vandever Ave,Waco,McLennan,TX,76707,254-463-4368,254-816-8417,bulah_padilla@hotmail.com,http://www.admiralpartyrentalssales.com +Audra,Kohnert,"Nelson, Karolyn King Esq",134 Lewis Rd,Nashville,Davidson,TN,37211,615-406-7854,615-448-9249,audra@kohnert.com,http://www.nelsonkarolynkingesq.com +Daren,Weirather,Panasystems,9 N College Ave #3,Milwaukee,Milwaukee,WI,53216,414-959-2540,414-838-3151,dweirather@aol.com,http://www.panasystems.com +Fernanda,Jillson,"Shank, Edward L Esq",60480 Old Us Highway 51,Preston,Caroline,MD,21655,410-387-5260,410-724-6472,fjillson@aol.com,http://www.shankedwardlesq.com +Gearldine,Gellinger,Megibow & Edwards,4 Bloomfield Ave,Irving,Dallas,TX,75061,972-934-6914,972-821-7118,gearldine_gellinger@gellinger.com,http://www.megibowedwards.com +Chau,Kitzman,"Benoff, Edward Esq",429 Tiger Ln,Beverly Hills,Los Angeles,CA,90212,310-560-8022,310-969-7230,chau@gmail.com,http://www.benoffedwardesq.com +Theola,Frey,Woodbridge Free Public Library,54169 N Main St,Massapequa,Nassau,NY,11758,516-948-5768,516-357-3362,theola_frey@frey.com,http://www.woodbridgefreepubliclibrary.com +Cheryl,Haroldson,New York Life John Thune,92 Main St,Atlantic City,Atlantic,NJ,8401,609-518-7697,609-263-9243,cheryl@haroldson.org,http://www.newyorklifejohnthune.com +Laticia,Merced,Alinabal Inc,72 Mannix Dr,Cincinnati,Hamilton,OH,45203,513-508-7371,513-418-1566,lmerced@gmail.com,http://www.alinabalinc.com +Carissa,Batman,"Poletto, Kim David Esq",12270 Caton Center Dr,Eugene,Lane,OR,97401,541-326-4074,541-801-5717,carissa.batman@yahoo.com,http://www.polettokimdavidesq.com +Lezlie,Craghead,"Chang, Carolyn Esq",749 W 18th St #45,Smithfield,Johnston,NC,27577,919-533-3762,919-885-2453,lezlie.craghead@craghead.org,http://www.changcarolynesq.com +Ozell,Shealy,Silver Bros Inc,8 Industry Ln,New York,New York,NY,10002,212-332-8435,212-880-8865,oshealy@hotmail.com,http://www.silverbrosinc.com +Arminda,Parvis,Newtec Inc,1 Huntwood Ave,Phoenix,Maricopa,AZ,85017,602-906-9419,602-277-3025,arminda@parvis.com,http://www.newtecinc.com +Reita,Leto,Creative Business Systems,55262 N French Rd,Indianapolis,Marion,IN,46240,317-234-1135,317-787-5514,reita.leto@gmail.com,http://www.creativebusinesssystems.com +Yolando,Luczki,Dal Tile Corporation,422 E 21st St,Syracuse,Onondaga,NY,13214,315-304-4759,315-640-6357,yolando@cox.net,http://www.daltilecorporation.com +Lizette,Stem,Edward S Katz,501 N 19th Ave,Cherry Hill,Camden,NJ,8002,856-487-5412,856-702-3676,lizette.stem@aol.com,http://www.edwardskatz.com +Gregoria,Pawlowicz,Oh My Goodknits Inc,455 N Main Ave,Garden City,Nassau,NY,11530,516-212-1915,516-376-4230,gpawlowicz@yahoo.com,http://www.ohmygoodknitsinc.com +Carin,Deleo,"Redeker, Debbie",1844 Southern Blvd,Little Rock,Pulaski,AR,72202,501-308-1040,501-409-6072,cdeleo@deleo.com,http://www.redekerdebbie.com +Chantell,Maynerich,Desert Sands Motel,2023 Greg St,Saint Paul,Ramsey,MN,55101,651-591-2583,651-776-9688,chantell@yahoo.com,http://www.desertsandsmotel.com +Dierdre,Yum,Cummins Southern Plains Inc,63381 Jenks Ave,Philadelphia,Philadelphia,PA,19134,215-325-3042,215-346-4666,dyum@yahoo.com,http://www.cumminssouthernplainsinc.com +Larae,Gudroe,Lehigh Furn Divsn Lehigh,6651 Municipal Rd,Houma,Terrebonne,LA,70360,985-890-7262,985-261-5783,larae_gudroe@gmail.com,http://www.lehighfurndivsnlehigh.com +Latrice,Tolfree,United Van Lines Agent,81 Norris Ave #525,Ronkonkoma,Suffolk,NY,11779,631-957-7624,631-998-2102,latrice.tolfree@hotmail.com,http://www.unitedvanlinesagent.com +Kerry,Theodorov,Capitol Reporters,6916 W Main St,Sacramento,Sacramento,CA,95827,916-591-3277,916-770-7448,kerry.theodorov@gmail.com,http://www.capitolreporters.com +Dorthy,Hidvegi,Kwik Kopy Printing,9635 S Main St,Boise,Ada,ID,83704,208-649-2373,208-690-3315,dhidvegi@yahoo.com,http://www.kwikkopyprinting.com +Fannie,Lungren,Centro Inc,17 Us Highway 111,Round Rock,Williamson,TX,78664,512-587-5746,512-528-9933,fannie.lungren@yahoo.com,http://www.centroinc.com +Evangelina,Radde,"Campbell, Jan Esq",992 Civic Center Dr,Philadelphia,Philadelphia,PA,19123,215-964-3284,215-417-5612,evangelina@aol.com,http://www.campbelljanesq.com +Novella,Degroot,"Evans, C Kelly Esq",303 N Radcliffe St,Hilo,Hawaii,HI,96720,808-477-4775,808-746-1865,novella_degroot@degroot.org,http://www.evansckellyesq.com +Clay,Hoa,Scat Enterprises,73 Saint Ann St #86,Reno,Washoe,NV,89502,775-501-8109,775-848-9135,choa@hoa.org,http://www.scatenterprises.com +Jennifer,Fallick,"Nagle, Daniel J Esq",44 58th St,Wheeling,Cook,IL,60090,847-979-9545,847-800-3054,jfallick@yahoo.com,http://www.nagledanieljesq.com +Irma,Wolfgramm,Serendiquity Bed & Breakfast,9745 W Main St,Randolph,Morris,NJ,7869,973-545-7355,973-868-8660,irma.wolfgramm@hotmail.com,http://www.serendiquitybedbreakfast.com +Eun,Coody,Ray Carolyne Realty,84 Bloomfield Ave,Spartanburg,Spartanburg,SC,29301,864-256-3620,864-594-4578,eun@yahoo.com,http://www.raycarolynerealty.com +Sylvia,Cousey,"Berg, Charles E",287 Youngstown Warren Rd,Hampstead,Carroll,MD,21074,410-209-9545,410-863-8263,sylvia_cousey@cousey.org,http://www.bergcharlese.com +Nana,Wrinkles,"Ray, Milbern D",6 Van Buren St,Mount Vernon,Westchester,NY,10553,914-855-2115,914-796-3775,nana@aol.com,http://www.raymilbernd.com +Layla,Springe,Chadds Ford Winery,229 N Forty Driv,New York,New York,NY,10011,212-260-3151,212-253-7448,layla.springe@cox.net,http://www.chaddsfordwinery.com +Joesph,Degonia,A R Packaging,2887 Knowlton St #5435,Berkeley,Alameda,CA,94710,510-677-9785,510-942-5916,joesph_degonia@degonia.org,http://www.arpackaging.com +Annabelle,Boord,Corn Popper,523 Marquette Ave,Concord,Middlesex,MA,1742,978-697-6263,978-289-7717,annabelle.boord@cox.net,http://www.cornpopper.com +Stephaine,Vinning,Birite Foodservice Distr,3717 Hamann Industrial Pky,San Francisco,San Francisco,CA,94104,415-767-6596,415-712-9530,stephaine@cox.net,http://www.biritefoodservicedistr.com +Nelida,Sawchuk,Anchorage Museum Of Hist & Art,3 State Route 35 S,Paramus,Bergen,NJ,7652,201-971-1638,201-247-8925,nelida@gmail.com,http://www.anchoragemuseumofhistart.com +Marguerita,Hiatt,"Haber, George D Md",82 N Highway 67,Oakley,Contra Costa,CA,94561,925-634-7158,925-541-8521,marguerita.hiatt@gmail.com,http://www.habergeorgedmd.com +Carmela,Cookey,Royal Pontiac Olds Inc,9 Murfreesboro Rd,Chicago,Cook,IL,60623,773-494-4195,773-297-9391,ccookey@cookey.org,http://www.royalpontiacoldsinc.com +Junita,Brideau,Leonards Antiques Inc,6 S Broadway St,Cedar Grove,Essex,NJ,7009,973-943-3423,973-582-5469,jbrideau@aol.com,http://www.leonardsantiquesinc.com +Claribel,Varriano,Meca,6 Harry L Dr #6327,Perrysburg,Wood,OH,43551,419-544-4900,419-573-2033,claribel_varriano@cox.net,http://www.meca.com +Benton,Skursky,Nercon Engineering & Mfg Inc,47939 Porter Ave,Gardena,Los Angeles,CA,90248,310-579-2907,310-694-8466,benton.skursky@aol.com,http://www.nerconengineeringmfginc.com +Hillary,Skulski,Replica I,9 Wales Rd Ne #914,Homosassa,Citrus,FL,34448,352-242-2570,352-990-5946,hillary.skulski@aol.com,http://www.replicai.com +Merilyn,Bayless,20 20 Printing Inc,195 13n N,Santa Clara,Santa Clara,CA,95054,408-758-5015,408-346-2180,merilyn_bayless@cox.net,http://www.printinginc.com +Teri,Ennaco,Publishers Group West,99 Tank Farm Rd,Hazleton,Luzerne,PA,18201,570-889-5187,570-355-1665,tennaco@gmail.com,http://www.publishersgroupwest.com +Merlyn,Lawler,"Nischwitz, Jeffrey L Esq",4671 Alemany Blvd,Jersey City,Hudson,NJ,7304,201-588-7810,201-858-9960,merlyn_lawler@hotmail.com,http://www.nischwitzjeffreylesq.com +Georgene,Montezuma,Payne Blades & Wellborn Pa,98 University Dr,San Ramon,Contra Costa,CA,94583,925-615-5185,925-943-3449,gmontezuma@cox.net,http://www.paynebladeswellbornpa.com +Jettie,Mconnell,Coldwell Bnkr Wright Real Est,50 E Wacker Dr,Bridgewater,Somerset,NJ,8807,908-802-3564,908-602-5258,jmconnell@hotmail.com,http://www.coldwellbnkrwrightrealest.com +Lemuel,Latzke,Computer Repair Service,70 Euclid Ave #722,Bohemia,Suffolk,NY,11716,631-748-6479,631-291-4976,lemuel.latzke@gmail.com,http://www.computerrepairservice.com +Melodie,Knipp,Fleetwood Building Block Inc,326 E Main St #6496,Thousand Oaks,Ventura,CA,91362,805-690-1682,805-810-8964,mknipp@gmail.com,http://www.fleetwoodbuildingblockinc.com +Candida,Corbley,Colts Neck Medical Assocs Inc,406 Main St,Somerville,Somerset,NJ,8876,908-275-8357,908-943-6103,candida_corbley@hotmail.com,http://www.coltsneckmedicalassocsinc.com +Karan,Karpin,New England Taxidermy,3 Elmwood Dr,Beaverton,Washington,OR,97005,503-940-8327,503-707-5812,karan_karpin@gmail.com,http://www.newenglandtaxidermy.com +Andra,Scheyer,"Ludcke, George O Esq",9 Church St,Salem,Marion,OR,97302,503-516-2189,503-950-3068,andra@gmail.com,http://www.ludckegeorgeoesq.com +Felicidad,Poullion,"Mccorkle, Tom S Esq",9939 N 14th St,Riverton,Burlington,NJ,8077,856-305-9731,856-828-6021,fpoullion@poullion.com,http://www.mccorkletomsesq.com +Belen,Strassner,Eagle Software Inc,5384 Southwyck Blvd,Douglasville,Douglas,GA,30135,770-507-8791,770-802-4003,belen_strassner@aol.com,http://www.eaglesoftwareinc.com +Gracia,Melnyk,Juvenile & Adult Super,97 Airport Loop Dr,Jacksonville,Duval,FL,32216,904-235-3633,904-627-4341,gracia@melnyk.com,http://www.juvenileadultsuper.com +Jolanda,Hanafan,"Perez, Joseph J Esq",37855 Nolan Rd,Bangor,Penobscot,ME,4401,207-458-9196,207-233-6185,jhanafan@gmail.com,http://www.perezjosephjesq.com +Barrett,Toyama,Case Foundation Co,4252 N Washington Ave #9,Kennedale,Tarrant,TX,76060,817-765-5781,817-577-6151,barrett.toyama@toyama.org,http://www.casefoundationco.com +Helga,Fredicks,Eis Environmental Engrs Inc,42754 S Ash Ave,Buffalo,Erie,NY,14228,716-752-4114,716-854-9845,helga_fredicks@yahoo.com,http://www.eisenvironmentalengrsinc.com +Ashlyn,Pinilla,Art Crafters,703 Beville Rd,Opa Locka,Miami-Dade,FL,33054,305-670-9628,305-857-5489,apinilla@cox.net,http://www.artcrafters.com +Fausto,Agramonte,Marriott Hotels Resorts Suites,5 Harrison Rd,New York,New York,NY,10038,212-313-1783,212-778-3063,fausto_agramonte@yahoo.com,http://www.marriotthotelsresortssuites.com +Ronny,Caiafa,Remaco Inc,73 Southern Blvd,Philadelphia,Philadelphia,PA,19103,215-605-7570,215-511-3531,ronny.caiafa@caiafa.org,http://www.remacoinc.com +Marge,Limmel,"Bjork, Robert D Jr",189 Village Park Rd,Crestview,Okaloosa,FL,32536,850-430-1663,850-330-8079,marge@gmail.com,http://www.bjorkrobertdjr.com +Norah,Waymire,"Carmichael, Jeffery L Esq",6 Middlegate Rd #106,San Francisco,San Francisco,CA,94107,415-306-7897,415-874-2984,norah.waymire@gmail.com,http://www.carmichaeljefferylesq.com +Aliza,Baltimore,"Andrews, J Robert Esq",1128 Delaware St,San Jose,Santa Clara,CA,95132,408-504-3552,408-425-1994,aliza@aol.com,http://www.andrewsjrobertesq.com +Mozell,Pelkowski,Winship & Byrne,577 Parade St,South San Francisco,San Mateo,CA,94080,650-947-1215,650-960-1069,mpelkowski@pelkowski.org,http://www.winshipbyrne.com +Viola,Bitsuie,Burton & Davis,70 Mechanic St,Northridge,Los Angeles,CA,91325,818-864-4875,818-481-5787,viola@gmail.com,http://www.burtondavis.com +Franklyn,Emard,Olympic Graphic Arts,4379 Highway 116,Philadelphia,Philadelphia,PA,19103,215-558-8189,215-483-3003,femard@emard.com,http://www.olympicgraphicarts.com +Willodean,Konopacki,Magnuson,55 Hawthorne Blvd,Lafayette,Lafayette,LA,70506,337-253-8384,337-774-7564,willodean_konopacki@konopacki.org,http://www.magnuson.com +Beckie,Silvestrini,A All American Travel Inc,7116 Western Ave,Dearborn,Wayne,MI,48126,313-533-4884,313-390-7855,beckie.silvestrini@silvestrini.com,http://www.aallamericantravelinc.com +Rebecka,Gesick,Polykote Inc,2026 N Plankinton Ave #3,Austin,Travis,TX,78754,512-213-8574,512-693-8345,rgesick@gesick.org,http://www.polykoteinc.com +Frederica,Blunk,Jets Cybernetics,99586 Main St,Dallas,Dallas,TX,75207,214-428-2285,214-529-1949,frederica_blunk@gmail.com,http://www.jetscybernetics.com +Glen,Bartolet,Metlab Testing Services,8739 Hudson St,Vashon,King,WA,98070,206-697-5796,206-389-1482,glen_bartolet@hotmail.com,http://www.metlabtestingservices.com +Freeman,Gochal,"Kellermann, William T Esq",383 Gunderman Rd #197,Coatesville,Chester,PA,19320,610-476-3501,610-752-2683,freeman_gochal@aol.com,http://www.kellermannwilliamtesq.com +Vincent,Meinerding,"Arturi, Peter D Esq",4441 Point Term Mkt,Philadelphia,Philadelphia,PA,19143,215-372-1718,215-829-4221,vincent.meinerding@hotmail.com,http://www.arturipeterdesq.com +Rima,Bevelacqua,Mcauley Mfg Co,2972 Lafayette Ave,Gardena,Los Angeles,CA,90248,310-858-5079,310-499-4200,rima@cox.net,http://www.mcauleymfgco.com +Glendora,Sarbacher,Defur Voran Hanley Radcliff,2140 Diamond Blvd,Rohnert Park,Sonoma,CA,94928,707-653-8214,707-881-3154,gsarbacher@gmail.com,http://www.defurvoranhanleyradcliff.com +Avery,Steier,Dill Dill Carr & Stonbraker Pc,93 Redmond Rd #492,Orlando,Orange,FL,32803,407-808-9439,407-945-8566,avery@cox.net,http://www.dilldillcarrstonbrakerpc.com +Cristy,Lother,Kleensteel,3989 Portage Tr,Escondido,San Diego,CA,92025,760-971-4322,760-465-4762,cristy@lother.com,http://www.kleensteel.com +Nicolette,Brossart,Goulds Pumps Inc Slurry Pump,1 Midway Rd,Westborough,Worcester,MA,1581,508-837-9230,508-504-6388,nicolette_brossart@brossart.com,http://www.gouldspumpsincslurrypump.com +Tracey,Modzelewski,Kansas City Insurance Report,77132 Coon Rapids Blvd Nw,Conroe,Montgomery,TX,77301,936-264-9294,936-988-8171,tracey@hotmail.com,http://www.kansascityinsurancereport.com +Virgina,Tegarden,Berhanu International Foods,755 Harbor Way,Milwaukee,Milwaukee,WI,53226,414-214-8697,414-411-5744,virgina_tegarden@tegarden.com,http://www.berhanuinternationalfoods.com +Tiera,Frankel,Roland Ashcroft,87 Sierra Rd,El Monte,Los Angeles,CA,91731,626-636-4117,626-638-4241,tfrankel@aol.com,http://www.rolandashcroft.com +Alaine,Bergesen,Hispanic Magazine,7667 S Hulen St #42,Yonkers,Westchester,NY,10701,914-300-9193,914-654-1426,alaine_bergesen@cox.net,http://www.hispanicmagazine.com +Earleen,Mai,Little Sheet Metal Co,75684 S Withlapopka Dr #32,Dallas,Dallas,TX,75227,214-289-1973,214-785-6750,earleen_mai@cox.net,http://www.littlesheetmetalco.com +Leonida,Gobern,"Holmes, Armstead J Esq",5 Elmwood Park Blvd,Biloxi,Harrison,MS,39530,228-235-5615,228-432-4635,leonida@gobern.org,http://www.holmesarmsteadjesq.com +Ressie,Auffrey,"Faw, James C Cpa",23 Palo Alto Sq,Miami,Miami-Dade,FL,33134,305-604-8981,305-287-4743,ressie.auffrey@yahoo.com,http://www.fawjamesccpa.com +Justine,Mugnolo,Evans Rule Company,38062 E Main St,New York,New York,NY,10048,212-304-9225,212-311-6377,jmugnolo@yahoo.com,http://www.evansrulecompany.com +Eladia,Saulter,Tyee Productions Inc,3958 S Dupont Hwy #7,Ramsey,Bergen,NJ,7446,201-474-4924,201-365-8698,eladia@saulter.com,http://www.tyeeproductionsinc.com +Chaya,Malvin,Dunnells & Duvall,560 Civic Center Dr,Ann Arbor,Washtenaw,MI,48103,734-928-5182,734-408-8174,chaya@malvin.com,http://www.dunnellsduvall.com +Gwenn,Suffield,Deltam Systems Inc,3270 Dequindre Rd,Deer Park,Suffolk,NY,11729,631-258-6558,631-295-9879,gwenn_suffield@suffield.org,http://www.deltamsystemsinc.com +Salena,Karpel,Hammill Mfg Co,1 Garfield Ave #7,Canton,Stark,OH,44707,330-791-8557,330-618-2579,skarpel@cox.net,http://www.hammillmfgco.com +Yoko,Fishburne,Sams Corner Store,9122 Carpenter Ave,New Haven,New Haven,CT,6511,203-506-4706,203-840-8634,yoko@fishburne.com,http://www.samscornerstore.com +Taryn,Moyd,"Siskin, Mark J Esq",48 Lenox St,Fairfax,Fairfax City,VA,22030,703-322-4041,703-938-7939,taryn.moyd@hotmail.com,http://www.siskinmarkjesq.com +Katina,Polidori,Cape & Associates Real Estate,5 Little River Tpke,Wilmington,Middlesex,MA,1887,978-626-2978,978-679-7429,katina_polidori@aol.com,http://www.capeassociatesrealestate.com +Rickie,Plumer,Merrill Lynch,3 N Groesbeck Hwy,Toledo,Lucas,OH,43613,419-693-1334,419-313-5571,rickie.plumer@aol.com,http://www.merrilllynch.com +Alex,Loader,"Sublett, Scott Esq",37 N Elm St #916,Tacoma,Pierce,WA,98409,253-660-7821,253-875-9222,alex@loader.com,http://www.sublettscottesq.com +Lashon,Vizarro,Sentry Signs,433 Westminster Blvd #590,Roseville,Placer,CA,95661,916-741-7884,916-289-4526,lashon@aol.com,http://www.sentrysigns.com +Lauran,Burnard,Professionals Unlimited,66697 Park Pl #3224,Riverton,Fremont,WY,82501,307-342-7795,307-453-7589,lburnard@burnard.com,http://www.professionalsunlimited.com +Ceola,Setter,Southern Steel Shelving Co,96263 Greenwood Pl,Warren,Knox,ME,4864,207-627-7565,207-297-5029,ceola.setter@setter.org,http://www.southernsteelshelvingco.com +My,Rantanen,"Bosco, Paul J",8 Mcarthur Ln,Richboro,Bucks,PA,18954,215-491-5633,215-647-2158,my@hotmail.com,http://www.boscopaulj.com +Lorrine,Worlds,"Longo, Nicholas J Esq",8 Fair Lawn Ave,Tampa,Hillsborough,FL,33614,813-769-2939,813-863-6467,lorrine.worlds@worlds.com,http://www.longonicholasjesq.com +Peggie,Sturiale,Henry County Middle School,9 N 14th St,El Cajon,San Diego,CA,92020,619-608-1763,619-695-8086,peggie@cox.net,http://www.henrycountymiddleschool.com +Marvel,Raymo,Edison Supply & Equipment Co,9 Vanowen St,College Station,Brazos,TX,77840,979-718-8968,979-809-5770,mraymo@yahoo.com,http://www.edisonsupplyequipmentco.com +Daron,Dinos,"Wolf, Warren R Esq",18 Waterloo Geneva Rd,Highland Park,Lake,IL,60035,847-233-3075,847-265-6609,daron_dinos@cox.net,http://www.wolfwarrenresq.com +An,Fritz,Linguistic Systems Inc,506 S Hacienda Dr,Atlantic City,Atlantic,NJ,8401,609-228-5265,609-854-7156,an_fritz@hotmail.com,http://www.linguisticsystemsinc.com +Portia,Stimmel,Peace Christian Center,3732 Sherman Ave,Bridgewater,Somerset,NJ,8807,908-722-7128,908-670-4712,portia.stimmel@aol.com,http://www.peacechristiancenter.com +Rhea,Aredondo,Double B Foods Inc,25657 Live Oak St,Brooklyn,Kings,NY,11226,718-560-9537,718-280-4183,rhea_aredondo@cox.net,http://www.doublebfoodsinc.com +Benedict,Sama,Alexander & Alexander Inc,4923 Carey Ave,Saint Louis,Saint Louis City,MO,63104,314-787-1588,314-858-4832,bsama@cox.net,http://www.alexanderalexanderinc.com +Alyce,Arias,Fairbanks Scales,3196 S Rider Trl,Stockton,San Joaquin,CA,95207,209-317-1801,209-242-7022,alyce@arias.org,http://www.fairbanksscales.com +Heike,Berganza,Cali Sportswear Cutting Dept,3 Railway Ave #75,Little Falls,Passaic,NJ,7424,973-936-5095,973-822-8827,heike@gmail.com,http://www.calisportswearcuttingdept.com +Carey,Dopico,"Garofani, John Esq",87393 E Highland Rd,Indianapolis,Marion,IN,46220,317-578-2453,317-441-5848,carey_dopico@dopico.org,http://www.garofanijohnesq.com +Dottie,Hellickson,Thompson Fabricating Co,67 E Chestnut Hill Rd,Seattle,King,WA,98133,206-540-6076,206-295-5631,dottie@hellickson.org,http://www.thompsonfabricatingco.com +Deandrea,Hughey,Century 21 Krall Real Estate,33 Lewis Rd #46,Burlington,Alamance,NC,27215,336-822-7652,336-467-3095,deandrea@yahoo.com,http://www.centurykrallrealestate.com +Kimberlie,Duenas,Mid Contntl Rlty & Prop Mgmt,8100 Jacksonville Rd #7,Hays,Ellis,KS,67601,785-629-8542,785-616-1685,kimberlie_duenas@yahoo.com,http://www.midcontntlrltypropmgmt.com +Martina,Staback,Ace Signs Inc,7 W Wabansia Ave #227,Orlando,Orange,FL,32822,407-471-6908,407-429-2145,martina_staback@staback.com,http://www.acesignsinc.com +Skye,Fillingim,Rodeway Inn,25 Minters Chapel Rd #9,Minneapolis,Hennepin,MN,55401,612-508-2655,612-664-6304,skye_fillingim@yahoo.com,http://www.rodewayinn.com +Jade,Farrar,Bonnet & Daughter,6882 Torresdale Ave,Columbia,Richland,SC,29201,803-352-5387,803-975-3405,jade.farrar@yahoo.com,http://www.bonnetdaughter.com +Charlene,Hamilton,Oshins & Gibbons,985 E 6th Ave,Santa Rosa,Sonoma,CA,95407,707-300-1771,707-821-8037,charlene.hamilton@hotmail.com,http://www.oshinsgibbons.com +Geoffrey,Acey,Price Business Services,7 West Ave #1,Palatine,Cook,IL,60067,847-222-1734,847-556-2909,geoffrey@gmail.com,http://www.pricebusinessservices.com +Stevie,Westerbeck,"Wise, Dennis W Md",26659 N 13th St,Costa Mesa,Orange,CA,92626,949-867-4077,949-903-3898,stevie.westerbeck@yahoo.com,http://www.wisedenniswmd.com +Pamella,Fortino,Super 8 Motel,669 Packerland Dr #1438,Denver,Denver,CO,80212,303-404-2210,303-794-1341,pamella@fortino.com,http://www.supermotel.com +Harrison,Haufler,John Wagner Associates,759 Eldora St,New Haven,New Haven,CT,6515,203-801-6193,203-801-8497,hhaufler@hotmail.com,http://www.johnwagnerassociates.com +Johnna,Engelberg,Thrifty Oil Co,5 S Colorado Blvd #449,Bothell,Snohomish,WA,98021,425-986-7573,425-700-3751,jengelberg@engelberg.org,http://www.thriftyoilco.com +Buddy,Cloney,Larkfield Photo,944 Gaither Dr,Strongsville,Cuyahoga,OH,44136,440-989-5826,440-327-2093,buddy.cloney@yahoo.com,http://www.larkfieldphoto.com +Dalene,Riden,Silverman Planetarium,66552 Malone Rd,Plaistow,Rockingham,NH,3865,603-315-6839,603-745-7497,dalene.riden@aol.com,http://www.silvermanplanetarium.com +Jerry,Zurcher,J & F Lumber,77 Massillon Rd #822,Satellite Beach,Brevard,FL,32937,321-518-5938,321-597-2159,jzurcher@zurcher.org,http://www.jflumber.com +Haydee,Denooyer,Cleaning Station Inc,25346 New Rd,New York,New York,NY,10016,212-792-8658,212-782-3493,hdenooyer@denooyer.org,http://www.cleaningstationinc.com +Joseph,Cryer,Ames Stationers,60 Fillmore Ave,Huntington Beach,Orange,CA,92647,714-584-2237,714-698-2170,joseph_cryer@cox.net,http://www.amesstationers.com +Deonna,Kippley,Midas Muffler Shops,57 Haven Ave #90,Southfield,Oakland,MI,48075,248-913-4677,248-793-4966,deonna_kippley@hotmail.com,http://www.midasmufflershops.com +Raymon,Calvaresi,Seaboard Securities Inc,6538 E Pomona St #60,Indianapolis,Marion,IN,46222,317-825-4724,317-342-1532,raymon.calvaresi@gmail.com,http://www.seaboardsecuritiesinc.com +Alecia,Bubash,"Petersen, James E Esq",6535 Joyce St,Wichita Falls,Wichita,TX,76301,940-276-7922,940-302-3036,alecia@aol.com,http://www.petersenjameseesq.com +Ma,Layous,Development Authority,78112 Morris Ave,North Haven,New Haven,CT,6473,203-721-3388,203-564-1543,mlayous@hotmail.com,http://www.developmentauthority.com +Detra,Coyier,Schott Fiber Optics Inc,96950 Hidden Ln,Aberdeen,Harford,MD,21001,410-739-9277,410-259-2118,detra@aol.com,http://www.schottfiberopticsinc.com +Terrilyn,Rodeigues,Stuart J Agins,3718 S Main St,New Orleans,Orleans,LA,70130,504-463-4384,504-635-8518,terrilyn.rodeigues@cox.net,http://www.stuartjagins.com +Salome,Lacovara,Mitsumi Electronics Corp,9677 Commerce Dr,Richmond,Richmond City,VA,23219,804-550-5097,804-858-1011,slacovara@gmail.com,http://www.mitsumielectronicscorp.com +Garry,Keetch,Italian Express Franchise Corp,5 Green Pond Rd #4,Southampton,Bucks,PA,18966,215-979-8776,215-846-9046,garry_keetch@hotmail.com,http://www.italianexpressfranchisecorp.com +Matthew,Neither,American Council On Sci & Hlth,636 Commerce Dr #42,Shakopee,Scott,MN,55379,952-651-7597,952-906-4597,mneither@yahoo.com,http://www.americancouncilonscihlth.com +Theodora,Restrepo,"Kleri, Patricia S Esq",42744 Hamann Industrial Pky #82,Miami,Miami-Dade,FL,33136,305-936-8226,305-573-1085,theodora.restrepo@restrepo.com,http://www.kleripatriciasesq.com +Noah,Kalafatis,Twiggs Abrams Blanchard,1950 5th Ave,Milwaukee,Milwaukee,WI,53209,414-263-5287,414-660-9766,noah.kalafatis@aol.com,http://www.twiggsabramsblanchard.com +Carmen,Sweigard,Maui Research & Technology Pk,61304 N French Rd,Somerset,Somerset,NJ,8873,732-941-2621,732-445-6940,csweigard@sweigard.com,http://www.mauiresearchtechnologypk.com +Lavonda,Hengel,Bradley Nameplate Corp,87 Imperial Ct #79,Fargo,Cass,ND,58102,701-898-2154,701-421-7080,lavonda@cox.net,http://www.bradleynameplatecorp.com +Junita,Stoltzman,Geonex Martel Inc,94 W Dodge Rd,Carson City,Carson City,NV,89701,775-638-9963,775-578-1214,junita@aol.com,http://www.geonexmartelinc.com +Herminia,Nicolozakes,Sea Island Div Of Fstr Ind Inc,4 58th St #3519,Scottsdale,Maricopa,AZ,85254,602-954-5141,602-304-6433,herminia@nicolozakes.org,http://www.seaislanddivoffstrindinc.com +Casie,Good,"Papay, Debbie J Esq",5221 Bear Valley Rd,Nashville,Davidson,TN,37211,615-390-2251,615-825-4297,casie.good@aol.com,http://www.papaydebbiejesq.com +Reena,Maisto,Lane Promotions,9648 S Main,Salisbury,Wicomico,MD,21801,410-351-1863,410-951-2667,reena@hotmail.com,http://www.lanepromotions.com +Mirta,Mallett,Stephen Kennerly Archts Inc Pc,7 S San Marcos Rd,New York,New York,NY,10004,212-870-1286,212-745-6948,mirta_mallett@gmail.com,http://www.stephenkennerlyarchtsincpc.com +Cathrine,Pontoriero,Business Systems Of Wis Inc,812 S Haven St,Amarillo,Randall,TX,79109,806-703-1435,806-558-5848,cathrine.pontoriero@pontoriero.com,http://www.businesssystemsofwisinc.com +Filiberto,Tawil,"Flash, Elena Salerno Esq",3882 W Congress St #799,Los Angeles,Los Angeles,CA,90016,323-765-2528,323-842-8226,ftawil@hotmail.com,http://www.flashelenasalernoesq.com +Raul,Upthegrove,"Neeley, Gregory W Esq",4 E Colonial Dr,La Mesa,San Diego,CA,91942,619-509-5282,619-666-4765,rupthegrove@yahoo.com,http://www.neeleygregorywesq.com +Sarah,Candlish,Alabama Educational Tv Comm,45 2nd Ave #9759,Atlanta,Fulton,GA,30328,770-732-1194,770-531-2842,sarah.candlish@gmail.com,http://www.alabamaeducationaltvcomm.com +Lucy,Treston,Franz Inc,57254 Brickell Ave #372,Worcester,Worcester,MA,1602,508-769-5250,508-502-5634,lucy@cox.net,http://www.franzinc.com +Judy,Aquas,Plantation Restaurant,8977 Connecticut Ave Nw #3,Niles,Berrien,MI,49120,269-756-7222,269-431-9464,jaquas@aquas.com,http://www.plantationrestaurant.com +Yvonne,Tjepkema,Radio Communications Co,9 Waydell St,Fairfield,Essex,NJ,7004,973-714-1721,973-976-8627,yvonne.tjepkema@hotmail.com,http://www.radiocommunicationsco.com +Kayleigh,Lace,Dentalaw Divsn Hlth Care,43 Huey P Long Ave,Lafayette,Lafayette,LA,70508,337-740-9323,337-751-2326,kayleigh.lace@yahoo.com,http://www.dentalawdivsnhlthcare.com +Felix,Hirpara,American Speedy Printing Ctrs,7563 Cornwall Rd #4462,Denver,Lancaster,PA,17517,717-491-5643,717-583-1497,felix_hirpara@cox.net,http://www.americanspeedyprintingctrs.com +Tresa,Sweely,"Grayson, Grant S Esq",22 Bridle Ln,Valley Park,Saint Louis,MO,63088,314-359-9566,314-231-3514,tresa_sweely@hotmail.com,http://www.graysongrantsesq.com +Kristeen,Turinetti,Jeanerette Middle School,70099 E North Ave,Arlington,Tarrant,TX,76013,817-213-8851,817-947-9480,kristeen@gmail.com,http://www.jeanerettemiddleschool.com +Jenelle,Regusters,"Haavisto, Brian F Esq",3211 E Northeast Loop,Tampa,Hillsborough,FL,33619,813-932-8715,813-357-7296,jregusters@regusters.com,http://www.haavistobrianfesq.com +Renea,Monterrubio,Wmmt Radio Station,26 Montgomery St,Atlanta,Fulton,GA,30328,770-679-4752,770-930-9967,renea@hotmail.com,http://www.wmmtradiostation.com +Olive,Matuszak,Colony Paints Sales Ofc & Plnt,13252 Lighthouse Ave,Cathedral City,Riverside,CA,92234,760-938-6069,760-745-2649,olive@aol.com,http://www.colonypaintssalesofcplnt.com +Ligia,Reiber,Floral Expressions,206 Main St #2804,Lansing,Ingham,MI,48933,517-906-1108,517-747-7664,lreiber@cox.net,http://www.floralexpressions.com +Christiane,Eschberger,Casco Services Inc,96541 W Central Blvd,Phoenix,Maricopa,AZ,85034,602-390-4944,602-330-6894,christiane.eschberger@yahoo.com,http://www.cascoservicesinc.com +Goldie,Schirpke,"Reuter, Arthur C Jr",34 Saint George Ave #2,Bangor,Penobscot,ME,4401,207-295-7569,207-748-3722,goldie.schirpke@yahoo.com,http://www.reuterarthurcjr.com +Loreta,Timenez,"Kaminski, Katherine Andritsaki",47857 Coney Island Ave,Clinton,Prince Georges,MD,20735,301-696-6420,301-392-6698,loreta.timenez@hotmail.com,http://www.kaminskikatherineandritsaki.com +Fabiola,Hauenstein,Sidewinder Products Corp,8573 Lincoln Blvd,York,York,PA,17404,717-809-3119,717-344-2804,fabiola.hauenstein@hauenstein.org,http://www.sidewinderproductscorp.com +Amie,Perigo,General Foam Corporation,596 Santa Maria Ave #7913,Mesquite,Dallas,TX,75150,972-419-7946,972-898-1033,amie.perigo@yahoo.com,http://www.generalfoamcorporation.com +Raina,Brachle,Ikg Borden Divsn Harsco Corp,3829 Ventura Blvd,Butte,Silver Bow,MT,59701,406-318-1515,406-374-7752,raina.brachle@brachle.org,http://www.ikgbordendivsnharscocorp.com +Erinn,Canlas,Anchor Computer Inc,13 S Hacienda Dr,Livingston,Essex,NJ,7039,973-767-3008,973-563-9502,erinn.canlas@canlas.com,http://www.anchorcomputerinc.com +Cherry,Lietz,Sebring & Co,40 9th Ave Sw #91,Waterford,Oakland,MI,48329,248-980-6904,248-697-7722,cherry@lietz.com,http://www.sebringco.com +Kattie,Vonasek,H A C Farm Lines Co Optv Assoc,2845 Boulder Crescent St,Cleveland,Cuyahoga,OH,44103,216-923-3715,216-270-9653,kattie@vonasek.org,http://www.hacfarmlinescooptvassoc.com +Lilli,Scriven,"Hunter, John J Esq",33 State St,Abilene,Taylor,TX,79601,325-631-1560,325-667-7868,lilli@aol.com,http://www.hunterjohnjesq.com +Whitley,Tomasulo,Freehold Fence Co,2 S 15th St,Fort Worth,Tarrant,TX,76107,817-526-4408,817-819-7799,whitley.tomasulo@aol.com,http://www.freeholdfenceco.com +Barbra,Adkin,Binswanger,4 Kohler Memorial Dr,Brooklyn,Kings,NY,11230,718-201-3751,718-732-9475,badkin@hotmail.com,http://www.binswanger.com +Hermila,Thyberg,Chilton Malting Co,1 Rancho Del Mar Shopping C,Providence,Providence,RI,2903,401-893-4882,401-885-7681,hermila_thyberg@hotmail.com,http://www.chiltonmaltingco.com +Jesusita,Flister,"Schoen, Edward J Jr",3943 N Highland Ave,Lancaster,Lancaster,PA,17601,717-885-9118,717-686-7564,jesusita.flister@hotmail.com,http://www.schoenedwardjjr.com +Caitlin,Julia,"Helderman, Seymour Cpa",5 Williams St,Johnston,Providence,RI,2919,401-948-4982,401-552-9059,caitlin.julia@julia.org,http://www.heldermanseymourcpa.com +Roosevelt,Hoffis,"Denbrook, Myron",60 Old Dover Rd,Hialeah,Miami-Dade,FL,33014,305-622-4739,305-302-1135,roosevelt.hoffis@aol.com,http://www.denbrookmyron.com +Helaine,Halter,"Lippitt, Mike",8 Sheridan Rd,Jersey City,Hudson,NJ,7304,201-832-4168,201-412-3040,hhalter@yahoo.com,http://www.lippittmike.com +Lorean,Martabano,"Hiram, Hogg P Esq",85092 Southern Blvd,San Antonio,Bexar,TX,78204,210-856-4979,210-634-2447,lorean.martabano@hotmail.com,http://www.hiramhoggpesq.com +France,Buzick,In Travel Agency,64 Newman Springs Rd E,Brooklyn,Kings,NY,11219,718-478-8504,718-853-3740,france.buzick@yahoo.com,http://www.intravelagency.com +Justine,Ferrario,Newhart Foods Inc,48 Stratford Ave,Pomona,Los Angeles,CA,91768,909-993-3242,909-631-5703,jferrario@hotmail.com,http://www.newhartfoodsinc.com +Adelina,Nabours,Courtyard By Marriott,80 Pittsford Victor Rd #9,Cleveland,Cuyahoga,OH,44103,216-230-4892,216-937-5320,adelina_nabours@gmail.com,http://www.courtyardbymarriott.com +Derick,Dhamer,"Studer, Eugene A Esq",87163 N Main Ave,New York,New York,NY,10013,212-304-4515,212-225-9676,ddhamer@cox.net,http://www.studereugeneaesq.com +Jerry,Dallen,Seashore Supply Co Waretown,393 Lafayette Ave,Richmond,Richmond City,VA,23219,804-762-9576,804-808-9574,jerry.dallen@yahoo.com,http://www.seashoresupplycowaretown.com +Leota,Ragel,Mayar Silk Inc,99 5th Ave #33,Trion,Chattooga,GA,30753,706-221-4243,706-616-5131,leota.ragel@gmail.com,http://www.mayarsilkinc.com +Jutta,Amyot,National Medical Excess Corp,49 N Mays St,Broussard,Lafayette,LA,70518,337-515-1438,337-991-8070,jamyot@hotmail.com,http://www.nationalmedicalexcesscorp.com +Aja,Gehrett,Stero Company,993 Washington Ave,Nutley,Essex,NJ,7110,973-544-2677,973-986-4456,aja_gehrett@hotmail.com,http://www.sterocompany.com +Kirk,Herritt,"Hasting, H Duane Esq",88 15th Ave Ne,Vestal,Broome,NY,13850,607-407-3716,607-350-7690,kirk.herritt@aol.com,http://www.hastinghduaneesq.com +Leonora,Mauson,Insty Prints,3381 E 40th Ave,Passaic,Passaic,NJ,7055,973-412-2995,973-355-2120,leonora@yahoo.com,http://www.instyprints.com +Winfred,Brucato,Glenridge Manor Mobile Home Pk,201 Ridgewood Rd,Moscow,Latah,ID,83843,208-252-4552,208-793-4108,winfred_brucato@hotmail.com,http://www.glenridgemanormobilehomepk.com +Tarra,Nachor,Circuit Solution Inc,39 Moccasin Dr,San Francisco,San Francisco,CA,94104,415-411-1775,415-284-2730,tarra.nachor@cox.net,http://www.circuitsolutioninc.com +Corinne,Loder,Local Office,4 Carroll St,North Attleboro,Bristol,MA,2760,508-942-4186,508-618-7826,corinne@loder.org,http://www.localoffice.com +Dulce,Labreche,Lee Kilkelly Paulson & Kabaker,9581 E Arapahoe Rd,Rochester,Oakland,MI,48307,248-357-8718,248-811-5696,dulce_labreche@yahoo.com,http://www.leekilkellypaulsonkabaker.com +Kate,Keneipp,"Davis, Maxon R Esq",33 N Michigan Ave,Green Bay,Brown,WI,54301,920-353-6377,920-355-1610,kate_keneipp@yahoo.com,http://www.davismaxonresq.com +Kaitlyn,Ogg,"Garrison, Paul E Esq",2 S Biscayne Blvd,Baltimore,Baltimore City,MD,21230,410-665-4903,410-773-3862,kaitlyn.ogg@gmail.com,http://www.garrisonpauleesq.com +Sherita,Saras,Black History Resource Center,8 Us Highway 22,Colorado Springs,El Paso,CO,80937,719-669-1664,719-547-9543,sherita.saras@cox.net,http://www.blackhistoryresourcecenter.com +Lashawnda,Stuer,"Rodriguez, J Christopher Esq",7422 Martin Ave #8,Toledo,Lucas,OH,43607,419-588-8719,419-399-1744,lstuer@cox.net,http://www.rodriguezjchristopheresq.com +Ernest,Syrop,Grant Family Health Center,94 Chase Rd,Hyattsville,Prince Georges,MD,20785,301-998-9644,301-257-4883,ernest@cox.net,http://www.grantfamilyhealthcenter.com +Nobuko,Halsey,Goeman Wood Products Inc,8139 I Hwy 10 #92,New Bedford,Bristol,MA,2745,508-855-9887,508-897-7916,nobuko.halsey@yahoo.com,http://www.goemanwoodproductsinc.com +Lavonna,Wolny,"Linhares, Kenneth A Esq",5 Cabot Rd,Mc Lean,Fairfax,VA,22102,703-483-1970,703-892-2914,lavonna.wolny@hotmail.com,http://www.linhareskennethaesq.com +Lashaunda,Lizama,Earnhardt Printing,3387 Ryan Dr,Hanover,Anne Arundel,MD,21076,410-678-2473,410-912-6032,llizama@cox.net,http://www.earnhardtprinting.com +Mariann,Bilden,H P G Industrys Inc,3125 Packer Ave #9851,Austin,Travis,TX,78753,512-223-4791,512-742-1149,mariann.bilden@aol.com,http://www.hpgindustrysinc.com +Helene,Rodenberger,Bailey Transportation Prod Inc,347 Chestnut St,Peoria,Maricopa,AZ,85381,623-461-8551,623-426-4907,helene@aol.com,http://www.baileytransportationprodinc.com +Roselle,Estell,Mcglynn Bliss Pc,8116 Mount Vernon Ave,Bucyrus,Crawford,OH,44820,419-571-5920,419-488-6648,roselle.estell@hotmail.com,http://www.mcglynnblisspc.com +Samira,Heintzman,Mutual Fish Co,8772 Old County Rd #5410,Kent,King,WA,98032,206-311-4137,206-923-6042,sheintzman@hotmail.com,http://www.mutualfishco.com +Margart,Meisel,"Yeates, Arthur L Aia",868 State St #38,Cincinnati,Hamilton,OH,45251,513-617-2362,513-747-9603,margart_meisel@yahoo.com,http://www.yeatesarthurlaia.com +Kristofer,Bennick,"Logan, Ronald J Esq",772 W River Dr,Bloomington,Monroe,IN,47404,812-368-1511,812-442-8544,kristofer.bennick@yahoo.com,http://www.loganronaldjesq.com +Weldon,Acuff,Advantage Martgage Company,73 W Barstow Ave,Arlington Heights,Cook,IL,60004,847-353-2156,847-613-5866,wacuff@gmail.com,http://www.advantagemartgagecompany.com +Shalon,Shadrick,Germer And Gertz Llp,61047 Mayfield Ave,Brooklyn,Kings,NY,11223,718-232-2337,718-394-4974,shalon@cox.net,http://www.germerandgertzllp.com +Denise,Patak,Spence Law Offices,2139 Santa Rosa Ave,Orlando,Orange,FL,32801,407-446-4358,407-808-3254,denise@patak.org,http://www.spencelawoffices.com +Louvenia,Beech,John Ortiz Nts Therapy Center,598 43rd St,Beverly Hills,Los Angeles,CA,90210,310-820-2117,310-652-2379,louvenia.beech@beech.com,http://www.johnortizntstherapycenter.com +Audry,Yaw,Mike Uchrin Htg & Air Cond Inc,70295 Pioneer Ct,Brandon,Hillsborough,FL,33511,813-797-4816,813-744-7100,audry.yaw@yaw.org,http://www.mikeuchrinhtgaircondinc.com +Kristel,Ehmann,"Mccoy, Joy Reynolds Esq",92899 Kalakaua Ave,El Paso,El Paso,TX,79925,915-452-1290,915-300-6100,kristel.ehmann@aol.com,http://www.mccoyjoyreynoldsesq.com +Vincenza,Zepp,Kbor 1600 Am,395 S 6th St #2,El Cajon,San Diego,CA,92020,619-603-5125,619-935-6661,vzepp@gmail.com,http://www.kboram.com +Elouise,Gwalthney,Quality Inn Northwest,9506 Edgemore Ave,Bladensburg,Prince Georges,MD,20710,301-841-5012,301-591-3034,egwalthney@yahoo.com,http://www.qualityinnnorthwest.com +Venita,Maillard,Wallace Church Assoc Inc,72119 S Walker Ave #63,Anaheim,Orange,CA,92801,714-523-6653,714-663-9740,venita_maillard@gmail.com,http://www.wallacechurchassocinc.com +Kasandra,Semidey,Can Tron,369 Latham St #500,Saint Louis,Saint Louis City,MO,63102,314-732-9131,314-697-3652,kasandra_semidey@semidey.com,http://www.cantron.com +Xochitl,Discipio,Ravaal Enterprises Inc,3158 Runamuck Pl,Round Rock,Williamson,TX,78664,512-233-1831,512-942-3411,xdiscipio@gmail.com,http://www.ravaalenterprisesinc.com +Maile,Linahan,Thompson Steel Company Inc,9 Plainsboro Rd #598,Greensboro,Guilford,NC,27409,336-670-2640,336-364-6037,mlinahan@yahoo.com,http://www.thompsonsteelcompanyinc.com +Krissy,Rauser,"Anderson, Mark A Esq",8728 S Broad St,Coram,Suffolk,NY,11727,631-443-4710,631-288-2866,krauser@cox.net,http://www.andersonmarkaesq.com +Pete,Dubaldi,Womack & Galich,2215 Prosperity Dr,Lyndhurst,Bergen,NJ,7071,201-825-2514,201-749-8866,pdubaldi@hotmail.com,http://www.womackgalich.com +Linn,Paa,Valerie & Company,1 S Pine St,Memphis,Shelby,TN,38112,901-412-4381,901-573-9024,linn_paa@paa.com,http://www.valeriecompany.com +Paris,Wide,Gehring Pumps Inc,187 Market St,Atlanta,Fulton,GA,30342,404-505-4445,404-607-8435,paris@hotmail.com,http://www.gehringpumpsinc.com +Wynell,Dorshorst,"Haehnel, Craig W Esq",94290 S Buchanan St,Pacifica,San Mateo,CA,94044,650-473-1262,650-749-9879,wynell_dorshorst@dorshorst.org,http://www.haehnelcraigwesq.com +Quentin,Birkner,Spoor Behrins Campbell & Young,7061 N 2nd St,Burnsville,Dakota,MN,55337,952-702-7993,952-314-5871,qbirkner@aol.com,http://www.spoorbehrinscampbellyoung.com +Regenia,Kannady,Ken Jeter Store Equipment Inc,10759 Main St,Scottsdale,Maricopa,AZ,85260,480-726-1280,480-205-5121,regenia.kannady@cox.net,http://www.kenjeterstoreequipmentinc.com +Sheron,Louissant,"Potter, Brenda J Cpa",97 E 3rd St #9,Long Island City,Queens,NY,11101,718-976-8610,718-613-9994,sheron@aol.com,http://www.potterbrendajcpa.com +Izetta,Funnell,Baird Kurtz & Dobson,82 Winsor St #54,Atlanta,Dekalb,GA,30340,770-844-3447,770-584-4119,izetta.funnell@hotmail.com,http://www.bairdkurtzdobson.com +Rodolfo,Butzen,"Minor, Cynthia A Esq",41 Steel Ct,Northfield,Rice,MN,55057,507-210-3510,507-590-5237,rodolfo@hotmail.com,http://www.minorcynthiaaesq.com +Zona,Colla,"Solove, Robert A Esq",49440 Dearborn St,Norwalk,Fairfield,CT,6854,203-461-1949,203-938-2557,zona@hotmail.com,http://www.soloverobertaesq.com +Serina,Zagen,Mark Ii Imports Inc,7 S Beverly Dr,Fort Wayne,Allen,IN,46802,260-273-3725,260-382-4869,szagen@aol.com,http://www.markiiimportsinc.com +Paz,Sahagun,White Sign Div Ctrl Equip Co,919 Wall Blvd,Meridian,Lauderdale,MS,39307,601-927-8287,601-249-4511,paz_sahagun@cox.net,http://www.whitesigndivctrlequipco.com +Markus,Lukasik,M & M Store Fixtures Co Inc,89 20th St E #779,Sterling Heights,Macomb,MI,48310,586-970-7380,586-247-1614,markus@yahoo.com,http://www.mmstorefixturescoinc.com +Jaclyn,Bachman,Judah Caster & Wheel Co,721 Interstate 45 S,Colorado Springs,El Paso,CO,80919,719-853-3600,719-223-2074,jaclyn@aol.com,http://www.judahcasterwheelco.com +Cyril,Daufeldt,Galaxy International Inc,3 Lawton St,New York,New York,NY,10013,212-745-8484,212-422-5427,cyril_daufeldt@daufeldt.com,http://www.galaxyinternationalinc.com +Gayla,Schnitzler,Sigma Corp Of America,38 Pleasant Hill Rd,Hayward,Alameda,CA,94545,510-686-3407,510-441-4055,gschnitzler@gmail.com,http://www.sigmacorpofamerica.com +Erick,Nievas,"Soward, Anne Esq",45 E Acacia Ct,Chicago,Cook,IL,60624,773-704-9903,773-359-6109,erick_nievas@aol.com,http://www.sowardanneesq.com +Jennie,Drymon,"Osborne, Michelle M Esq",63728 Poway Rd #1,Scranton,Lackawanna,PA,18509,570-218-4831,570-868-8688,jennie@cox.net,http://www.osbornemichellemesq.com +Mitsue,Scipione,Students In Free Entrprs Natl,77 222 Dr,Oroville,Butte,CA,95965,530-986-9272,530-399-3254,mscipione@scipione.com,http://www.studentsinfreeentrprsnatl.com +Ciara,Ventura,"Johnson, Robert M Esq",53 W Carey St,Port Jervis,Orange,NY,12771,845-823-8877,845-694-7919,cventura@yahoo.com,http://www.johnsonrobertmesq.com +Galen,Cantres,Del Charro Apartments,617 Nw 36th Ave,Brook Park,Cuyahoga,OH,44142,216-600-6111,216-871-6876,galen@yahoo.com,http://www.delcharroapartments.com +Truman,Feichtner,Legal Search Inc,539 Coldwater Canyon Ave,Bloomfield,Essex,NJ,7003,973-852-2736,973-473-5108,tfeichtner@yahoo.com,http://www.legalsearchinc.com +Gail,Kitty,Service Supply Co Inc,735 Crawford Dr,Anchorage,Anchorage,AK,99501,907-435-9166,907-770-3542,gail@kitty.com,http://www.servicesupplycoinc.com +Dalene,Schoeneck,"Sameshima, Douglas J Esq",910 Rahway Ave,Philadelphia,Philadelphia,PA,19102,215-268-1275,215-380-8820,dalene@schoeneck.org,http://www.sameshimadouglasjesq.com +Gertude,Witten,"Thompson, John Randolph Jr",7 Tarrytown Rd,Cincinnati,Hamilton,OH,45217,513-977-7043,513-863-9471,gertude.witten@gmail.com,http://www.thompsonjohnrandolphjr.com +Lizbeth,Kohl,E T Balancing Co Inc,35433 Blake St #588,Gardena,Los Angeles,CA,90248,310-699-1222,310-955-5788,lizbeth@yahoo.com,http://www.etbalancingcoinc.com +Glenn,Berray,"Griswold, John E Esq",29 Cherry St #7073,Des Moines,Polk,IA,50315,515-370-7348,515-372-1738,gberray@gmail.com,http://www.griswoldjohneesq.com +Lashandra,Klang,Acqua Group,810 N La Brea Ave,King of Prussia,Montgomery,PA,19406,610-809-1818,610-378-7332,lashandra@yahoo.com,http://www.acquagroup.com +Lenna,Newville,"Brooks, Morris J Jr",987 Main St,Raleigh,Wake,NC,27601,919-623-2524,919-254-5987,lnewville@newville.com,http://www.brooksmorrisjjr.com +Laurel,Pagliuca,Printing Images Corp,36 Enterprise St Se,Richland,Benton,WA,99352,509-695-5199,509-595-6485,laurel@yahoo.com,http://www.printingimagescorp.com +Mireya,Frerking,Roberts Supply Co Inc,8429 Miller Rd,Pelham,Westchester,NY,10803,914-868-5965,914-883-3061,mireya.frerking@hotmail.com,http://www.robertssupplycoinc.com +Annelle,Tagala,Vico Products Mfg Co,5 W 7th St,Parkville,Baltimore,MD,21234,410-757-1035,410-234-2267,annelle@yahoo.com,http://www.vicoproductsmfgco.com +Dean,Ketelsen,J M Custom Design Millwork,2 Flynn Rd,Hicksville,Nassau,NY,11801,516-847-4418,516-732-6649,dean_ketelsen@gmail.com,http://www.jmcustomdesignmillwork.com +Levi,Munis,Farrell & Johnson Office Equip,2094 Ne 36th Ave,Worcester,Worcester,MA,1603,508-456-4907,508-658-7802,levi.munis@gmail.com,http://www.farrelljohnsonofficeequip.com +Sylvie,Ryser,Millers Market & Deli,649 Tulane Ave,Tulsa,Tulsa,OK,74105,918-644-9555,918-565-1706,sylvie@aol.com,http://www.millersmarketdeli.com +Sharee,Maile,Holiday Inn Naperville,2094 Montour Blvd,Muskegon,Muskegon,MI,49442,231-467-9978,231-265-6940,sharee_maile@aol.com,http://www.holidayinnnaperville.com +Cordelia,Storment,"Burrows, Jon H Esq",393 Hammond Dr,Lafayette,Lafayette,LA,70506,337-566-6001,337-255-3427,cordelia_storment@aol.com,http://www.burrowsjonhesq.com +Mollie,Mcdoniel,Dock Seal Specialty,8590 Lake Lizzie Dr,Bowling Green,Wood,OH,43402,419-975-3182,419-417-4674,mollie_mcdoniel@yahoo.com,http://www.docksealspecialty.com +Brett,Mccullan,Five Star Limousines Of Tx Inc,87895 Concord Rd,La Mesa,San Diego,CA,91942,619-461-9984,619-727-3892,brett.mccullan@mccullan.com,http://www.fivestarlimousinesoftxinc.com +Teddy,Pedrozo,"Barkan, Neal J Esq",46314 Route 130,Bridgeport,Fairfield,CT,6610,203-892-3863,203-918-3939,teddy_pedrozo@aol.com,http://www.barkannealjesq.com +Tasia,Andreason,"Campbell, Robert A",4 Cowesett Ave,Kearny,Hudson,NJ,7032,201-920-9002,201-969-7063,tasia_andreason@yahoo.com,http://www.campbellroberta.com +Hubert,Walthall,"Dee, Deanna",95 Main Ave #2,Barberton,Summit,OH,44203,330-903-1345,330-566-8898,hubert@walthall.org,http://www.deedeanna.com +Arthur,Farrow,"Young, Timothy L Esq",28 S 7th St #2824,Englewood,Bergen,NJ,7631,201-238-5688,201-772-4377,arthur.farrow@yahoo.com,http://www.youngtimothylesq.com +Vilma,Berlanga,"Wells, D Fred Esq",79 S Howell Ave,Grand Rapids,Kent,MI,49546,616-737-3085,616-568-4113,vberlanga@berlanga.com,http://www.wellsdfredesq.com +Billye,Miro,"Gray, Francine H Esq",36 Lancaster Dr Se,Pearl,Rankin,MS,39208,601-567-5386,601-637-5479,billye_miro@cox.net,http://www.grayfrancinehesq.com +Glenna,Slayton,Toledo Iv Care,2759 Livingston Ave,Memphis,Shelby,TN,38118,901-640-9178,901-869-4314,glenna_slayton@cox.net,http://www.toledoivcare.com +Mitzie,Hudnall,Cangro Transmission Co,17 Jersey Ave,Englewood,Arapahoe,CO,80110,303-402-1940,303-997-7760,mitzie_hudnall@yahoo.com,http://www.cangrotransmissionco.com +Bernardine,Rodefer,Sat Poly Inc,2 W Grand Ave,Memphis,Shelby,TN,38112,901-901-4726,901-739-5892,bernardine_rodefer@yahoo.com,http://www.satpolyinc.com +Staci,Schmaltz,Midwest Contracting & Mfg Inc,18 Coronado Ave #563,Pasadena,Los Angeles,CA,91106,626-866-2339,626-293-7678,staci_schmaltz@aol.com,http://www.midwestcontractingmfginc.com +Nichelle,Meteer,Print Doctor,72 Beechwood Ter,Chicago,Cook,IL,60657,773-225-9985,773-857-2231,nichelle_meteer@meteer.com,http://www.printdoctor.com +Janine,Rhoden,Nordic Group Inc,92 Broadway,Astoria,Queens,NY,11103,718-228-5894,718-728-5051,jrhoden@yahoo.com,http://www.nordicgroupinc.com +Ettie,Hoopengardner,Jackson Millwork Co,39 Franklin Ave,Richland,Benton,WA,99352,509-755-5393,509-847-3352,ettie.hoopengardner@hotmail.com,http://www.jacksonmillworkco.com +Eden,Jayson,Harris Corporation,4 Iwaena St,Baltimore,Baltimore City,MD,21202,410-890-7866,410-429-4888,eden_jayson@yahoo.com,http://www.harriscorporation.com +Lynelle,Auber,United Cerebral Palsy Of Ne Pa,32820 Corkwood Rd,Newark,Essex,NJ,7104,973-860-8610,973-605-6492,lynelle_auber@gmail.com,http://www.unitedcerebralpalsyofnepa.com +Merissa,Tomblin,One Day Surgery Center Inc,34 Raritan Center Pky,Bellflower,Los Angeles,CA,90706,562-579-6900,562-719-7922,merissa.tomblin@gmail.com,http://www.onedaysurgerycenterinc.com +Golda,Kaniecki,Calaveras Prospect,6201 S Nevada Ave,Toms River,Ocean,NJ,8755,732-628-9909,732-617-5310,golda_kaniecki@yahoo.com,http://www.calaverasprospect.com +Catarina,Gleich,"Terk, Robert E Esq",78 Maryland Dr #146,Denville,Morris,NJ,7834,973-210-3994,973-491-8723,catarina_gleich@hotmail.com,http://www.terkroberteesq.com +Virgie,Kiel,"Cullen, Terrence P Esq",76598 Rd I 95 #1,Denver,Denver,CO,80216,303-776-7548,303-845-5408,vkiel@hotmail.com,http://www.cullenterrencepesq.com +Jolene,Ostolaza,Central Die Casting Mfg Co Inc,1610 14th St Nw,Newport News,Newport News City,VA,23608,757-682-7116,757-940-1741,jolene@yahoo.com,http://www.centraldiecastingmfgcoinc.com +Keneth,Borgman,Centerline Engineering,86350 Roszel Rd,Phoenix,Maricopa,AZ,85012,602-919-4211,602-442-3092,keneth@yahoo.com,http://www.centerlineengineering.com +Rikki,Nayar,Targan & Kievit Pa,1644 Clove Rd,Miami,Miami-Dade,FL,33155,305-968-9487,305-978-2069,rikki@nayar.com,http://www.targankievitpa.com +Elke,Sengbusch,Riley Riper Hollin & Colagreco,9 W Central Ave,Phoenix,Maricopa,AZ,85013,602-896-2993,602-575-3457,elke_sengbusch@yahoo.com,http://www.rileyriperhollincolagreco.com +Hoa,Sarao,"Kaplan, Joel S Esq",27846 Lafayette Ave,Oak Hill,Volusia,FL,32759,386-526-7800,386-599-7296,hoa@sarao.org,http://www.kaplanjoelsesq.com +Trinidad,Mcrae,Water Office,10276 Brooks St,San Francisco,San Francisco,CA,94105,415-331-9634,415-419-1597,trinidad_mcrae@yahoo.com,http://www.wateroffice.com +Mari,Lueckenbach,"Westbrooks, Nelson E Jr",1 Century Park E,San Diego,San Diego,CA,92110,858-793-9684,858-228-5683,mari_lueckenbach@yahoo.com,http://www.westbrooksnelsonejr.com +Selma,Husser,Armon Communications,9 State Highway 57 #22,Jersey City,Hudson,NJ,7306,201-991-8369,201-772-7699,selma.husser@cox.net,http://www.armoncommunications.com +Antione,Onofrio,Jacobs & Gerber Inc,4 S Washington Ave,San Bernardino,San Bernardino,CA,92410,909-430-7765,909-665-3223,aonofrio@onofrio.com,http://www.jacobsgerberinc.com +Luisa,Jurney,Forest Fire Laboratory,25 Se 176th Pl,Cambridge,Middlesex,MA,2138,617-365-2134,617-544-2541,ljurney@hotmail.com,http://www.forestfirelaboratory.com +Clorinda,Heimann,"Haughey, Charles Jr",105 Richmond Valley Rd,Escondido,San Diego,CA,92025,760-291-5497,760-261-4786,clorinda.heimann@hotmail.com,http://www.haugheycharlesjr.com +Dick,Wenzinger,Wheaton Plastic Products,22 Spruce St #595,Gardena,Los Angeles,CA,90248,310-510-9713,310-936-2258,dick@yahoo.com,http://www.wheatonplasticproducts.com +Ahmed,Angalich,Reese Plastics,2 W Beverly Blvd,Harrisburg,Dauphin,PA,17110,717-528-8996,717-632-5831,ahmed.angalich@angalich.com,http://www.reeseplastics.com +Iluminada,Ohms,Nazette Marner Good Wendt,72 Southern Blvd,Mesa,Maricopa,AZ,85204,480-293-2882,480-866-6544,iluminada.ohms@yahoo.com,http://www.nazettemarnergoodwendt.com +Joanna,Leinenbach,Levinson Axelrod Wheaton,1 Washington St,Lake Worth,Palm Beach,FL,33461,561-470-4574,561-951-9734,joanna_leinenbach@hotmail.com,http://www.levinsonaxelrodwheaton.com +Caprice,Suell,"Egnor, W Dan Esq",90177 N 55th Ave,Nashville,Davidson,TN,37211,615-246-1824,615-726-4537,caprice@aol.com,http://www.egnorwdanesq.com +Stephane,Myricks,Portland Central Thriftlodge,9 Tower Ave,Burlington,Boone,KY,41005,859-717-7638,859-308-4286,stephane_myricks@cox.net,http://www.portlandcentralthriftlodge.com +Quentin,Swayze,Ulbrich Trucking,278 Bayview Ave,Milan,Monroe,MI,48160,734-561-6170,734-851-8571,quentin_swayze@yahoo.com,http://www.ulbrichtrucking.com +Annmarie,Castros,Tipiak Inc,80312 W 32nd St,Conroe,Montgomery,TX,77301,936-751-7961,936-937-2334,annmarie_castros@gmail.com,http://www.tipiakinc.com +Shonda,Greenbush,Saint George Well Drilling,82 Us Highway 46,Clifton,Passaic,NJ,7011,973-482-2430,973-644-2974,shonda_greenbush@cox.net,http://www.saintgeorgewelldrilling.com +Cecil,Lapage,"Hawkes, Douglas D",4 Stovall St #72,Union City,Hudson,NJ,7087,201-693-3967,201-856-2720,clapage@lapage.com,http://www.hawkesdouglasd.com +Jeanice,Claucherty,Accurel Systems Intrntl Corp,19 Amboy Ave,Miami,Miami-Dade,FL,33142,305-988-4162,305-306-7834,jeanice.claucherty@yahoo.com,http://www.accurelsystemsintrntlcorp.com +Josphine,Villanueva,Santa Cruz Community Internet,63 Smith Ln #8343,Moss,Clay,TN,38575,931-553-9774,931-486-6946,josphine_villanueva@villanueva.com,http://www.santacruzcommunityinternet.com +Daniel,Perruzza,Gersh & Danielson,11360 S Halsted St,Santa Ana,Orange,CA,92705,714-771-3880,714-531-1391,dperruzza@perruzza.com,http://www.gershdanielson.com +Cassi,Wildfong,"Cobb, James O Esq",26849 Jefferson Hwy,Rolling Meadows,Cook,IL,60008,847-633-3216,847-755-9041,cassi.wildfong@aol.com,http://www.cobbjamesoesq.com +Britt,Galam,Wheatley Trucking Company,2500 Pringle Rd Se #508,Hatfield,Montgomery,PA,19440,215-888-3304,215-351-8523,britt@galam.org,http://www.wheatleytruckingcompany.com +Adell,Lipkin,Systems Graph Inc Ab Dick Dlr,65 Mountain View Dr,Whippany,Morris,NJ,7981,973-654-1561,973-662-8988,adell.lipkin@lipkin.com,http://www.systemsgraphincabdickdlr.com +Jacqueline,Rowling,John Hancock Mutl Life Ins Co,1 N San Saba,Erie,Erie,PA,16501,814-865-8113,814-481-1700,jacqueline.rowling@yahoo.com,http://www.johnhancockmutllifeinsco.com +Lonny,Weglarz,History Division Of State,51120 State Route 18,Salt Lake City,Salt Lake,UT,84115,801-293-9853,801-892-8781,lonny_weglarz@gmail.com,http://www.historydivisionofstate.com +Lonna,Diestel,"Dimmock, Thomas J Esq",1482 College Ave,Fayetteville,Cumberland,NC,28301,910-922-3672,910-200-7912,lonna_diestel@gmail.com,http://www.dimmockthomasjesq.com +Cristal,Samara,Intermed Inc,4119 Metropolitan Dr,Los Angeles,Los Angeles,CA,90021,213-975-8026,213-696-8004,cristal@cox.net,http://www.intermedinc.com +Kenneth,Grenet,Bank Of New York,2167 Sierra Rd,East Lansing,Ingham,MI,48823,517-499-2322,517-867-8077,kenneth.grenet@grenet.org,http://www.bankofnewyork.com +Elli,Mclaird,Sportmaster Intrnatl,6 Sunrise Ave,Utica,Oneida,NY,13501,315-818-2638,315-474-5570,emclaird@mclaird.com,http://www.sportmasterintrnatl.com +Alline,Jeanty,W W John Holden Inc,55713 Lake City Hwy,South Bend,St Joseph,IN,46601,574-656-2800,574-405-1983,ajeanty@gmail.com,http://www.wwjohnholdeninc.com +Sharika,Eanes,Maccani & Delp,75698 N Fiesta Blvd,Orlando,Orange,FL,32806,407-312-1691,407-472-1332,sharika.eanes@aol.com,http://www.maccanidelp.com +Nu,Mcnease,Amazonia Film Project,88 Sw 28th Ter,Harrison,Hudson,NJ,7029,973-751-9003,973-903-4175,nu@gmail.com,http://www.amazoniafilmproject.com +Daniela,Comnick,Water & Sewer Department,7 Flowers Rd #403,Trenton,Mercer,NJ,8611,609-200-8577,609-398-2805,dcomnick@cox.net,http://www.watersewerdepartment.com +Cecilia,Colaizzo,Switchcraft Inc,4 Nw 12th St #3849,Madison,Dane,WI,53717,608-382-4541,608-302-3387,cecilia_colaizzo@colaizzo.com,http://www.switchcraftinc.com +Leslie,Threets,C W D C Metal Fabricators,2 A Kelley Dr,Katonah,Westchester,NY,10536,914-861-9748,914-396-2615,leslie@cox.net,http://www.cwdcmetalfabricators.com +Nan,Koppinger,"Shimotani, Grace T",88827 Frankford Ave,Greensboro,Guilford,NC,27401,336-370-5333,336-564-1492,nan@koppinger.com,http://www.shimotanigracet.com +Izetta,Dewar,"Lisatoni, Jean Esq",2 W Scyene Rd #3,Baltimore,Baltimore City,MD,21217,410-473-1708,410-522-7621,idewar@dewar.com,http://www.lisatonijeanesq.com +Tegan,Arceo,Ceramic Tile Sales Inc,62260 Park Stre,Monroe Township,Middlesex,NJ,8831,732-730-2692,732-705-6719,tegan.arceo@arceo.org,http://www.ceramictilesalesinc.com +Ruthann,Keener,Maiden Craft Inc,3424 29th St Se,Kerrville,Kerr,TX,78028,830-258-2769,830-919-5991,ruthann@hotmail.com,http://www.maidencraftinc.com +Joni,Breland,Carriage House Cllsn Rpr Inc,35 E Main St #43,Elk Grove Village,Cook,IL,60007,847-519-5906,847-740-5304,joni_breland@cox.net,http://www.carriagehousecllsnrprinc.com +Vi,Rentfro,Video Workshop,7163 W Clark Rd,Freehold,Monmouth,NJ,7728,732-605-4781,732-724-7251,vrentfro@cox.net,http://www.videoworkshop.com +Colette,Kardas,Fresno Tile Center Inc,21575 S Apple Creek Rd,Omaha,Douglas,NE,68124,402-896-5943,402-707-1602,colette.kardas@yahoo.com,http://www.fresnotilecenterinc.com +Malcolm,Tromblay,Versatile Sash & Woodwork,747 Leonis Blvd,Annandale,Fairfax,VA,22003,703-221-5602,703-874-4248,malcolm_tromblay@cox.net,http://www.versatilesashwoodwork.com +Ryan,Harnos,Warner Electric Brk & Cltch Co,13 Gunnison St,Plano,Collin,TX,75075,972-558-1665,972-961-4968,ryan@cox.net,http://www.warnerelectricbrkcltchco.com +Jess,Chaffins,New York Public Library,18 3rd Ave,New York,New York,NY,10016,212-510-4633,212-428-9538,jess.chaffins@chaffins.org,http://www.newyorkpubliclibrary.com +Sharen,Bourbon,"Mccaleb, John A Esq",62 W Austin St,Syosset,Nassau,NY,11791,516-816-1541,516-749-3188,sbourbon@yahoo.com,http://www.mccalebjohnaesq.com +Nickolas,Juvera,United Oil Co Inc,177 S Rider Trl #52,Crystal River,Citrus,FL,34429,352-598-8301,352-947-6152,nickolas_juvera@cox.net,http://www.unitedoilcoinc.com +Gary,Nunlee,Irving Foot Center,2 W Mount Royal Ave,Fortville,Hancock,IN,46040,317-542-6023,317-887-8486,gary_nunlee@nunlee.org,http://www.irvingfootcenter.com +Diane,Devreese,Acme Supply Co,1953 Telegraph Rd,Saint Joseph,Buchanan,MO,64504,816-557-9673,816-329-5565,diane@cox.net,http://www.acmesupplyco.com +Roslyn,Chavous,"Mcrae, James L",63517 Dupont St,Jackson,Hinds,MS,39211,601-234-9632,601-973-5754,roslyn.chavous@chavous.org,http://www.mcraejamesl.com +Glory,Schieler,Mcgraths Seafood,5 E Truman Rd,Abilene,Taylor,TX,79602,325-869-2649,325-740-3778,glory@yahoo.com,http://www.mcgrathsseafood.com +Rasheeda,Sayaphon,"Kummerer, J Michael Esq",251 Park Ave #979,Saratoga,Santa Clara,CA,95070,408-805-4309,408-997-7490,rasheeda@aol.com,http://www.kummererjmichaelesq.com +Alpha,Palaia,"Stoffer, James M Jr",43496 Commercial Dr #29,Cherry Hill,Camden,NJ,8003,856-312-2629,856-513-7024,alpha@yahoo.com,http://www.stofferjamesmjr.com +Refugia,Jacobos,North Central Fl Sfty Cncl,2184 Worth St,Hayward,Alameda,CA,94545,510-974-8671,510-509-3496,refugia.jacobos@jacobos.com,http://www.northcentralflsftycncl.com +Shawnda,Yori,Fiorucci Foods Usa Inc,50126 N Plankinton Ave,Longwood,Seminole,FL,32750,407-538-5106,407-564-8113,shawnda.yori@yahoo.com,http://www.fioruccifoodsusainc.com +Mona,Delasancha,Sign All,38773 Gravois Ave,Cheyenne,Laramie,WY,82001,307-403-1488,307-816-7115,mdelasancha@hotmail.com,http://www.signall.com +Gilma,Liukko,Sammys Steak Den,16452 Greenwich St,Garden City,Nassau,NY,11530,516-393-9967,516-407-9573,gilma_liukko@gmail.com,http://www.sammyssteakden.com +Janey,Gabisi,"Dobscha, Stephen F Esq",40 Cambridge Ave,Madison,Dane,WI,53715,608-967-7194,608-586-6912,jgabisi@hotmail.com,http://www.dobschastephenfesq.com +Lili,Paskin,Morgan Custom Homes,20113 4th Ave E,Kearny,Hudson,NJ,7032,201-431-2989,201-478-8540,lili.paskin@cox.net,http://www.morgancustomhomes.com +Loren,Asar,Olsen Payne & Company,6 Ridgewood Center Dr,Old Forge,Lackawanna,PA,18518,570-648-3035,570-569-2356,loren.asar@aol.com,http://www.olsenpaynecompany.com +Dorothy,Chesterfield,Cowan & Kelly,469 Outwater Ln,San Diego,San Diego,CA,92126,858-617-7834,858-732-1884,dorothy@cox.net,http://www.cowankelly.com +Gail,Similton,"Johnson, Wes Esq",62 Monroe St,Thousand Palms,Riverside,CA,92276,760-616-5388,760-493-9208,gail_similton@similton.com,http://www.johnsonwesesq.com +Catalina,Tillotson,Icn Pharmaceuticals Inc,3338 A Lockport Pl #6,Margate City,Atlantic,NJ,8402,609-373-3332,609-826-4990,catalina@hotmail.com,http://www.icnpharmaceuticalsinc.com +Lawrence,Lorens,New England Sec Equip Co Inc,9 Hwy,Providence,Providence,RI,2906,401-465-6432,401-893-1820,lawrence.lorens@hotmail.com,http://www.newenglandsecequipcoinc.com +Carlee,Boulter,"Tippett, Troy M Ii",8284 Hart St,Abilene,Dickinson,KS,67410,785-347-1805,785-253-7049,carlee.boulter@hotmail.com,http://www.tippetttroymii.com +Thaddeus,Ankeny,Atc Contracting,5 Washington St #1,Roseville,Placer,CA,95678,916-920-3571,916-459-2433,tankeny@ankeny.org,http://www.atccontracting.com +Jovita,Oles,"Pagano, Philip G Esq",8 S Haven St,Daytona Beach,Volusia,FL,32114,386-248-4118,386-208-6976,joles@gmail.com,http://www.paganophilipgesq.com +Alesia,Hixenbaugh,Kwikprint,9 Front St,Washington,District of Columbia,DC,20001,202-646-7516,202-276-6826,alesia_hixenbaugh@hixenbaugh.org,http://www.kwikprint.com +Lai,Harabedian,Buergi & Madden Scale,1933 Packer Ave #2,Novato,Marin,CA,94945,415-423-3294,415-926-6089,lai@gmail.com,http://www.buergimaddenscale.com +Brittni,Gillaspie,Inner Label,67 Rv Cent,Boise,Ada,ID,83709,208-709-1235,208-206-9848,bgillaspie@gillaspie.com,http://www.innerlabel.com +Raylene,Kampa,Hermar Inc,2 Sw Nyberg Rd,Elkhart,Elkhart,IN,46514,574-499-1454,574-330-1884,rkampa@kampa.org,http://www.hermarinc.com +Flo,Bookamer,Simonton Howe & Schneider Pc,89992 E 15th St,Alliance,Box Butte,NE,69301,308-726-2182,308-250-6987,flo.bookamer@cox.net,http://www.simontonhoweschneiderpc.com +Jani,Biddy,Warehouse Office & Paper Prod,61556 W 20th Ave,Seattle,King,WA,98104,206-711-6498,206-395-6284,jbiddy@yahoo.com,http://www.warehouseofficepaperprod.com +Chauncey,Motley,Affiliated With Travelodge,63 E Aurora Dr,Orlando,Orange,FL,32804,407-413-4842,407-557-8857,chauncey_motley@aol.com,http://www.affiliatedwithtravelodge.com \ No newline at end of file From 01f07150f4246caea7aa336d17a46e6462a8a5d2 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Tue, 14 Oct 2025 23:31:56 -0700 Subject: [PATCH 02/18] fixed ActiveMQ Private Lambda Java SAM project --- .../ActiveMQAndClientEC2.yaml | 89 +++++++------- activemq-private-lambda-java-sam/VPCOnly.yaml | 116 ++++++++++++++++++ .../template_original.yaml | 31 ++--- .../activemq_message_sender_json/commands.sh | 7 ++ .../producer/SecretsManagerDecoder.java | 2 +- .../create-activemq.sh | 39 ++++++ activemq-private-lambda-java-sam/test-mq.yaml | 12 ++ 7 files changed, 237 insertions(+), 59 deletions(-) create mode 100644 activemq-private-lambda-java-sam/VPCOnly.yaml create mode 100644 activemq-private-lambda-java-sam/activemq_message_sender_json/commands.sh create mode 100755 activemq-private-lambda-java-sam/create-activemq.sh create mode 100644 activemq-private-lambda-java-sam/test-mq.yaml diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index 2a41b7654..3543f57a2 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -5,7 +5,7 @@ Parameters: Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' ActiveMQEngineVersion: Type: String - Default: 5.18.3 + Default: 5.18 Description: ActiveMQ engine version JavaVersion: Type: String @@ -340,58 +340,29 @@ Resources: ToPort: 22 SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - # ActiveMQ Subnet Group - ActiveMQSubnetGroup: - Type: AWS::MQ::Configuration + # ActiveMQ Configuration + ActiveMQConfiguration: + Type: AWS::AmazonMQ::Configuration Properties: Name: !Sub "${AWS::StackName}-activemq-config" Description: ActiveMQ configuration for the cluster EngineType: ACTIVEMQ EngineVersion: !Ref ActiveMQEngineVersion - Data: | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8YnJva2VyIHhtbG5zPSJodHRwOi8vYWN0aXZlbXEuYXBhY2hlLm9yZy9zY2hlbWEvY29yZSI+CiAgPGRlc3RpbmF0aW9uUG9saWN5PgogICAgPHBvbGljeU1hcD4KICAgICAgPHBvbGljeUVudHJpZXM+CiAgICAgICAgPHBvbGljeUVudHJ5IHRvcGljPSI+IiBwcm9kdWNlckZsb3dDb250cm9sPSJ0cnVlIj4KICAgICAgICAgIDxwZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgICAgIDxzcG9vbGluZ1N1YnNjcmlwdGlvblBlbmRpbmdNZXNzYWdlTGltaXRTdHJhdGVneSBsaW1pdD0iMTAwMCIvPgogICAgICAgICAgPC9wZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgPC9wb2xpY3lFbnRyeT4KICAgICAgICA8cG9saWN5RW50cnkgcXVldWU9Ij4iIHByb2R1Y2VyRmxvd0NvbnRyb2w9InRydWUiIG1lbW9yeUxpbWl0PSIxbWIiPgogICAgICAgIDwvcG9saWN5RW50cnk+CiAgICAgIDwvcG9saWN5RW50cmllcz4KICAgIDwvcG9saWN5TWFwPgogIDwvZGVzdGluYXRpb25Qb2xpY3k+CiAgPHN5c3RlbVVzYWdlPgogICAgPHN5c3RlbVVzYWdlPgogICAgICA8bWVtb3J5VXNhZ2U+CiAgICAgICAgPG1lbW9yeVVzYWdlIGxpbWl0PSI2NCBtYiIvPgogICAgICA8L21lbW9yeVVzYWdlPgogICAgICA8c3RvcmVVc2FnZT4KICAgICAgICA8c3RvcmVVc2FnZSBsaW1pdD0iNTEyIG1iIi8+CiAgICAgIDwvc3RvcmVVc2FnZT4KICAgICAgPHRlbXBVc2FnZT4KICAgICAgICA8dGVtcFVzYWdlIGxpbWl0PSIxMjggbWIiLz4KICAgICAgPC90ZW1wVXNhZ2U+CiAgICA8L3N5c3RlbVVzYWdlPgogIDwvc3lzdGVtVXNhZ2U+CjwvYnJva2VyPgo= # ActiveMQ Broker ActiveMQBroker: - Type: AWS::MQ::Broker + Type: AWS::AmazonMQ::Broker Properties: BrokerName: !Ref ActiveMQBrokerName - DeploymentMode: ACTIVE_STANDBY_MULTI_AZ + DeploymentMode: CLUSTER_MULTI_AZ EngineType: ACTIVEMQ EngineVersion: !Ref ActiveMQEngineVersion HostInstanceType: mq.t3.micro PubliclyAccessible: false - AutoMinorVersionUpgrade: false + AutoMinorVersionUpgrade: true Configuration: - Id: !Ref ActiveMQSubnetGroup + Id: !Ref ActiveMQConfiguration Revision: 1 Users: - Username: !Ref ActiveMQBrokerAdminUser @@ -402,6 +373,7 @@ Resources: SubnetIds: - !Ref PrivateSubnetActiveMQOne - !Ref PrivateSubnetActiveMQTwo + - !Ref PrivateSubnetActiveMQThree SecurityGroups: - !Ref ActiveMQSecurityGroup Tags: @@ -596,6 +568,7 @@ Resources: # Set environment variables ACTIVEMQ_BROKER_ID=${activemq_broker_id} + ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} ACTIVEMQ_BROKER_ENDPOINT=${activemq_broker_endpoint} ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} @@ -609,6 +582,7 @@ Resources: SECURITY_GROUP=${security_group_id} echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile @@ -631,6 +605,36 @@ Resources: cd activemq-private-lambda-java-sam sudo chown -R ec2-user . + #Substitute SAM template variables + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + cd activemq_consumer_dynamo_sam + cp template_original.yaml template.yaml + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/ACTIVEMQ_BROKER_ARN/$ACTIVEMQ_BROKER_ARN/g" template.yaml + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" template.yaml + sed -i "s/ACTIVEMQ_SECRET_ARN/$ACTIVEMQ_SECRET_ARN/g" template.yaml + sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_ONE/$ACTIVEMQ_SUBNET_ONE/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_TWO/$ACTIVEMQ_SUBNET_TWO/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_THREE/$ACTIVEMQ_SUBNET_THREE/g" template.yaml + sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + + #Install ActiveMQ (needed in case you want to use the CLI as a client to look at queues etc.) + mkdir /home/ec2-user/activemq_client + cd /home/ec2-user/activemq_client + wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz + tar zxvf apache-activemq-5.18.6-bin.tar.gz + sudo chown -R ec2-user . + + #Update Shell script for sending ActiveMQ messages to Lambda function + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json + sudo chown ec2-user ./commands.sh + sed -i "s/ACTIVEMQ_BROKER_ENDPOINT/$ACTIVEMQ_BROKER_ENDPOINT/g" commands.sh + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh + mvn clean install + + # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user mkdir -p ip_prefix @@ -645,9 +649,8 @@ Resources: aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP - activemq_broker_id: !Ref ActiveMQBroker - activemq_broker_endpoint: !Sub - - "ssl://${endpoint}:61617" - - endpoint: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + activemq_broker_arn: !GetAtt ActiveMQBroker.Arn + activemq_broker_endpoint: !GetAtt ActiveMQBroker.OpenWireEndpoints activemq_queue_name: !Ref ActiveMQQueueName activemq_secret_arn: !Ref ActiveMQSecret serverless_land_github_location: !Ref ServerlessLandGithubLocation @@ -816,9 +819,7 @@ Outputs: Name: !Sub "${AWS::StackName}-VPCStackName" ActiveMQBrokerEndpoint: Description: ActiveMQ Broker OpenWire Endpoint - Value: !Sub - - "ssl://${endpoint}:61617" - - endpoint: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Value: !GetAtt ActiveMQBroker.OpenWireEndpoints Export: Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint" ActiveMQBrokerConsoleURL: diff --git a/activemq-private-lambda-java-sam/VPCOnly.yaml b/activemq-private-lambda-java-sam/VPCOnly.yaml new file mode 100644 index 000000000..09773014b --- /dev/null +++ b/activemq-private-lambda-java-sam/VPCOnly.yaml @@ -0,0 +1,116 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PublicThree: + CIDR: '10.0.2.0/24' + PrivateSubnetActiveMQOne: + CIDR: '10.0.3.0/24' + PrivateSubnetActiveMQTwo: + CIDR: '10.0.4.0/24' + PrivateSubnetActiveMQThree: + CIDR: '10.0.5.0/24' + +Resources: + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'ActiveMQVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + + PrivateSubnetActiveMQOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQOne' + + PrivateSubnetActiveMQTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQTwo' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + ActiveMQSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: ActiveMQ Security Group + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 61617 + ToPort: 61617 + CidrIp: 10.0.0.0/16 + - IpProtocol: tcp + FromPort: 8162 + ToPort: 8162 + CidrIp: 10.0.0.0/16 + +Outputs: + VPCId: + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PrivateSubnetOne: + Value: !Ref 'PrivateSubnetActiveMQOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetOne" + PrivateSubnetTwo: + Value: !Ref 'PrivateSubnetActiveMQTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetTwo" + SecurityGroupId: + Value: !GetAtt ActiveMQSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml index 53269fa6e..cf252bbd5 100755 --- a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml @@ -31,20 +31,19 @@ Resources: SubnetIds: - !Ref Subnet1 - !Ref Subnet2 + - !Ref Subnet3 Events: MQEvent: Type: MQ Properties: BatchSize: 100 MaximumBatchingWindowInSeconds: 5 - Broker: - !Join ['', ["arn:", "aws:", "mq:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "broker:", !Ref ActiveMQBrokerName, ":", !Ref ActiveMQBrokerUniqueString]] + Broker: !Ref ActiveMQBrokerArn Queues: - !Ref ActiveMQQueue SourceAccessConfigurations: - Type: BASIC_AUTH - URI: - !Join ['', ["arn:", "aws:", "secretsmanager:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "secret:", !Ref SecretsManagerSecretForMQName, "-", !Ref SecretsManagerSecretForMQUniqueString]] + URI: !Ref SecretsManagerSecretForMQ Policies: - Statement: @@ -89,30 +88,34 @@ Resources: Name: MessageID Type: String Parameters: - ActiveMQBrokerName: + ActiveMQBrokerArn: Type: String - Description: Enter the name of the ActiveMQBroker that is part of the ARN - ActiveMQBrokerUniqueString: - Type: String - Description: Enter the unique string of the ActiveMQBroker after the broker name in the ARN + Description: Enter the ARN of the ActiveMQBroker + Default: ACTIVEMQ_BROKER_ARN ActiveMQQueue: Type: String Description: Enter the name of the ActiveMQ queue from which the lambda function will consume messages - SecretsManagerSecretForMQName: + Default: ACTIVEMQ_QUEUE_NAME + SecretsManagerSecretForMQ: Type: String Description: Enter the name of the secret that has username/password for Active MQ - SecretsManagerSecretForMQUniqueString: - Type: String - Description: Enter the unique string of the secret that has username/password for Active MQ + Default: ACTIVEMQ_SECRET_ARN Subnet1: Type: String Description: The first of the three private subnets in the ActiveMQ broker's VPC + Default: ACTIVEMQ_SUBNET_ONE Subnet2: Type: String Description: The second of the three private subnets in the ActiveMQ broker's VPC + Default: ACTIVEMQ_SUBNET_TWO + Subnet3: + Type: String + Description: The second of the three private subnets in the ActiveMQ broker's VPC + Default: ACTIVEMQ_SUBNET_THREE SecurityGroup: Type: String - Description: The security group associated with this function (use same ActiveMQ) + Description: The security group associated with this function + Default: SECURITY_GROUP Outputs: LambdaActiveMQConsumerJavaFunction: Description: "Queue Consumer Lambda Function ARN" diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/commands.sh b/activemq-private-lambda-java-sam/activemq_message_sender_json/commands.sh new file mode 100644 index 000000000..65e781592 --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/commands.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Pass a random string as the first command-line argument to this shell script. It will be used to uniquely identify a batch of messages +# Pass an integer as the second command-line argument to this shell script < 500. For example if you want to send 100 messages, pass 100 +# Example sh commands.sh firstbatch 100 + +java -classpath /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json/target/json-activemq-producer-0.0.1-SNAPSHOT.jar activemq.producer.JsonActiveMQProducer ACTIVEMQ_BROKER_ENDPOINT ACTIVEMQ_QUEUE_NAME $1 $2 \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java index a5c340af2..5bebed3c5 100755 --- a/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java +++ b/activemq-private-lambda-java-sam/activemq_message_sender_json/src/main/java/activemq/producer/SecretsManagerDecoder.java @@ -12,7 +12,7 @@ public class SecretsManagerDecoder { public static String getSecret() { - String secretName = "AmazonMQCredentials"; + String secretName = "AmazonActiveMQCredentials"; DefaultAwsRegionProviderChain defaultAwsRegionProviderChain = new DefaultAwsRegionProviderChain(); Region region = defaultAwsRegionProviderChain.getRegion(); diff --git a/activemq-private-lambda-java-sam/create-activemq.sh b/activemq-private-lambda-java-sam/create-activemq.sh new file mode 100755 index 000000000..2d49fb96f --- /dev/null +++ b/activemq-private-lambda-java-sam/create-activemq.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Deploy VPC first +aws cloudformation deploy \ + --template-file VPCOnly.yaml \ + --stack-name activemq-vpc \ + --region us-west-2 \ + --profile indranil8724 + +# Get VPC outputs +VPC_ID=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`VPCId`].OutputValue' --output text) +SUBNET1=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`PrivateSubnetOne`].OutputValue' --output text) +SUBNET2=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`PrivateSubnetTwo`].OutputValue' --output text) +SG_ID=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`SecurityGroupId`].OutputValue' --output text) + +# Create MQ Configuration +CONFIG_ID=$(aws mq create-configuration \ + --name activemq-config \ + --engine-type ACTIVEMQ \ + --engine-version 5.18 \ + --region us-west-2 \ + --profile indranil8724 \ + --query 'Id' --output text) + +# Create MQ Broker +aws mq create-broker \ + --broker-name ActiveMQJavaLambdaBroker \ + --engine-type ACTIVEMQ \ + --engine-version 5.18 \ + --host-instance-type mq.t3.micro \ + --deployment-mode ACTIVE_STANDBY_MULTI_AZ \ + --users Username=activemqadmin,Password=activemqPassword123,ConsoleAccess=true \ + --subnet-ids $SUBNET1 $SUBNET2 \ + --security-groups $SG_ID \ + --configuration Id=$CONFIG_ID,Revision=1 \ + --region us-west-2 \ + --profile indranil8724 + +echo "MQ Broker creation initiated. Check AWS Console for status." diff --git a/activemq-private-lambda-java-sam/test-mq.yaml b/activemq-private-lambda-java-sam/test-mq.yaml new file mode 100644 index 000000000..815f9237b --- /dev/null +++ b/activemq-private-lambda-java-sam/test-mq.yaml @@ -0,0 +1,12 @@ +AWSTemplateFormatVersion: '2010-09-09' +Resources: + TestConfig: + Type: AWS::MQ::Configuration + Properties: + Name: test-config + EngineType: ACTIVEMQ + EngineVersion: 5.18 + Data: | + + + From b581668cddd6f53fed9f5ba951ed3c0616f4ede5 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Wed, 15 Oct 2025 23:41:40 -0700 Subject: [PATCH 03/18] Fixed ActiveMQ Private Lambda Java SAM project --- .../ActiveMQAndClientEC2.yaml | 21 +- .../DocumentDBAndMongoClientEC2.yaml | 946 ------------------ activemq-private-lambda-java-sam/VPCOnly.yaml | 116 --- .../create-activemq.sh | 39 - activemq-private-lambda-java-sam/test-mq.yaml | 12 - 5 files changed, 14 insertions(+), 1120 deletions(-) delete mode 100644 activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml delete mode 100644 activemq-private-lambda-java-sam/VPCOnly.yaml delete mode 100755 activemq-private-lambda-java-sam/create-activemq.sh delete mode 100644 activemq-private-lambda-java-sam/test-mq.yaml diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index 3543f57a2..a2150211a 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -355,7 +355,7 @@ Resources: Type: AWS::AmazonMQ::Broker Properties: BrokerName: !Ref ActiveMQBrokerName - DeploymentMode: CLUSTER_MULTI_AZ + DeploymentMode: ACTIVE_STANDBY_MULTI_AZ EngineType: ACTIVEMQ EngineVersion: !Ref ActiveMQEngineVersion HostInstanceType: mq.t3.micro @@ -373,7 +373,6 @@ Resources: SubnetIds: - !Ref PrivateSubnetActiveMQOne - !Ref PrivateSubnetActiveMQTwo - - !Ref PrivateSubnetActiveMQThree SecurityGroups: - !Ref ActiveMQSecurityGroup Tags: @@ -569,7 +568,9 @@ Resources: # Set environment variables ACTIVEMQ_BROKER_ID=${activemq_broker_id} ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} - ACTIVEMQ_BROKER_ENDPOINT=${activemq_broker_endpoint} + #ACTIVEMQ_BROKER_ENDPOINT1=${activemq_broker_endpoint1} + #ACTIVEMQ_BROKER_ENDPOINT2=${activemq_broker_endpoint2} + ACTIVEMQ_BROKER_ENDPOINT="failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})" ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} @@ -650,7 +651,8 @@ Resources: - activemq_broker_id: !Ref ActiveMQBroker activemq_broker_arn: !GetAtt ActiveMQBroker.Arn - activemq_broker_endpoint: !GetAtt ActiveMQBroker.OpenWireEndpoints + activemq_broker_endpoint1: !Select [ 0, !GetAtt ActiveMQBroker.OpenWireEndpoints ] + activemq_broker_endpoint2: !Select [ 1, !GetAtt ActiveMQBroker.OpenWireEndpoints ] activemq_queue_name: !Ref ActiveMQQueueName activemq_secret_arn: !Ref ActiveMQSecret serverless_land_github_location: !Ref ServerlessLandGithubLocation @@ -817,11 +819,16 @@ Outputs: Value: !Ref 'AWS::StackName' Export: Name: !Sub "${AWS::StackName}-VPCStackName" - ActiveMQBrokerEndpoint: + ActiveMQBrokerEndpoint1: Description: ActiveMQ Broker OpenWire Endpoint - Value: !GetAtt ActiveMQBroker.OpenWireEndpoints + Value: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint" + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint1" + ActiveMQBrokerEndpoint2: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Select [1, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint2" ActiveMQBrokerConsoleURL: Description: ActiveMQ Broker Web Console URL Value: !Sub diff --git a/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml b/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml deleted file mode 100644 index eba751ca8..000000000 --- a/activemq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml +++ /dev/null @@ -1,946 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Parameters: - LatestAmiId: - Type: 'AWS::SSM::Parameter::Value' - Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' - DocumentDBEngineVersion: - Type: String - Default: 5.0.0 - Description: DocumentDB engine version - JavaVersion: - Type: String - Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 - AllowedValues: - - java11 - - java17 - - java21 - Default: java21 - DocumentDBDatabaseName: - Type: String - Default: DocumentDBJavaLambdaDB - Description: DocumentDB database name for Lambda function - DocumentDBCollectionName: - Type: String - Default: DocumentDBJavaLambdaCollection - Description: DocumentDB collection name for Lambda function - DocumentDBClusterAdminUser: - Type: String - Description: Password for the DocumentDB Cluster - Default: docdbadmin - DocumentDBClusterPassword: - Type: String - Description: Password for the DocumentDB Cluster - Default: docdbPassword123 - NoEcho: true - DocumentDBTrustStorePassword: - Type: String - Description: Password for the DocumentDB Client TLS Truststore Password - Default: docdbTrustPass123 - NoEcho: true - ServerlessLandGithubLocation: - Type: String - Default: https://github.com/aws-samples/serverless-patterns.git - Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork - -Mappings: - SubnetConfig: - VPC: - CIDR: '10.0.0.0/16' - PublicOne: - CIDR: '10.0.0.0/24' - PublicTwo: - CIDR: '10.0.1.0/24' - PublicThree: - CIDR: '10.0.2.0/24' - PrivateSubnetDocDBOne: - CIDR: '10.0.3.0/24' - PrivateSubnetDocDBTwo: - CIDR: '10.0.4.0/24' - PrivateSubnetDocDBThree: - CIDR: '10.0.5.0/24' - -Resources: - # Secrets Manager Secret for DocumentDB credentials - DocumentDBSecret: - Type: AWS::SecretsManager::Secret - Properties: - Name: 'AmazonDocumentDBCredentials' - Description: DocumentDB cluster master user credentials - SecretString: !Sub | - { - "username": "${DocumentDBClusterAdminUser}", - "password": "${DocumentDBClusterPassword}" - } - - DocumentDBTrustStoreSecret: - Type: AWS::SecretsManager::Secret - Properties: - Name: 'AmazonDocumentDBTruststore' - Description: DocumentDB secret for truststore for SSL client to connect - SecretString: !Sub | - { - "truststore": "/home/ec2-user/mongotruststore/rds-truststore.jks", - "truststorepassword": "${DocumentDBTrustStorePassword}" - } - - VPC: - Type: AWS::EC2::VPC - Properties: - EnableDnsSupport: true - EnableDnsHostnames: true - CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - Tags: - - Key: 'Name' - Value: 'DocumentDBVPC' - - PublicSubnetOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetOne' - PublicSubnetTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetTwo' - PublicSubnetThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetThree' - PrivateSubnetDocDBOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBOne', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetDocDBOne' - PrivateSubnetDocDBTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBTwo', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetDocDBTwo' - PrivateSubnetDocDBThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBThree', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetDocDBThree' - - InternetGateway: - Type: AWS::EC2::InternetGateway - GatewayAttachement: - Type: AWS::EC2::VPCGatewayAttachment - Properties: - VpcId: !Ref 'VPC' - InternetGatewayId: !Ref 'InternetGateway' - - NATEIP1: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway1: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP1.AllocationId - SubnetId: !Ref 'PublicSubnetOne' - Tags: - - Key: 'Name' - Value: 'DocumentDBNATGateway1' - - NATEIP2: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway2: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP2.AllocationId - SubnetId: !Ref 'PublicSubnetTwo' - Tags: - - Key: 'Name' - Value: 'DocumentDBNATGateway2' - - NATEIP3: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway3: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP3.AllocationId - SubnetId: !Ref 'PublicSubnetThree' - Tags: - - Key: 'Name' - Value: 'DocumentDBNATGateway3' - - PublicRouteTable: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PublicRoute: - Type: AWS::EC2::Route - DependsOn: GatewayAttachement - Properties: - RouteTableId: !Ref 'PublicRouteTable' - DestinationCidrBlock: '0.0.0.0/0' - GatewayId: !Ref 'InternetGateway' - - PublicSubnetOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetOne - RouteTableId: !Ref PublicRouteTable - - PublicSubnetTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetTwo - RouteTableId: !Ref PublicRouteTable - - PublicSubnetThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetThree - RouteTableId: !Ref PublicRouteTable - - PrivateRouteTable1: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute1: - Type: AWS::EC2::Route - DependsOn: NATGateway1 - Properties: - RouteTableId: !Ref 'PrivateRouteTable1' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway1' - - PrivateRouteTable2: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute2: - Type: AWS::EC2::Route - DependsOn: NATGateway2 - Properties: - RouteTableId: !Ref 'PrivateRouteTable2' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway2' - - PrivateRouteTable3: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute3: - Type: AWS::EC2::Route - DependsOn: NATGateway3 - Properties: - RouteTableId: !Ref 'PrivateRouteTable3' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway3' - - PrivateSubnetDocDBOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable1 - SubnetId: !Ref PrivateSubnetDocDBOne - - PrivateSubnetDocDBTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable2 - SubnetId: !Ref PrivateSubnetDocDBTwo - - PrivateSubnetDocDBThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable3 - SubnetId: !Ref PrivateSubnetDocDBThree - - DocumentDBClientInstanceSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup - GroupName: !Sub "${AWS::StackName} Security group attached to the DocumentDB client" - VpcId: !Ref VPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 10.0.0.0/16 - - DocumentDBSecurityGroup: - Type: AWS::EC2::SecurityGroup - DependsOn: [VPC,DocumentDBClientInstanceSecurityGroup] - Properties: - GroupDescription: DocumentDB Security Group - GroupName: !Sub "${AWS::StackName} Security group for the DocumentDB cluster" - VpcId: !Ref 'VPC' - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 27017 - ToPort: 27017 - SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: 0 - ToPort: 65535 - CidrIp: 10.0.0.0/16 - - DocumentDBClientSelfIngressAllowRule: - Type: AWS::EC2::SecurityGroupIngress - DependsOn: DocumentDBClientInstanceSecurityGroup - Properties: - GroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - - DocumentDBClientEC2Instance: - DependsOn: DocumentDBCluster - Type: AWS::EC2::Instance - Properties: - InstanceType: m5.large - IamInstanceProfile: !Ref EC2InstanceProfile - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - SubnetId: !Ref PublicSubnetOne - SecurityGroupIds: [!GetAtt DocumentDBClientInstanceSecurityGroup.GroupId] - ImageId: !Ref LatestAmiId - Tags: - - Key: 'Name' - Value: 'DocumentDBClientInstance' - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: 50 - VolumeType: gp2 - DeleteOnTermination: true - UserData: - Fn::Base64: - !Sub - - | - #!/bin/bash - yum update -y - - # install Java - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum update -y - # yum install java-openjdk11-devel -y - - # install Java - JAVA_VERSION=${java_version} - echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile - if [ "$JAVA_VERSION" == "java11" ]; then - sudo yum install java-11-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java17" ]; then - sudo yum install java-17-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java21" ]; then - sudo yum install java-21-amazon-corretto-devel -y - else - sudo yum install java-21-amazon-corretto-devel -y - fi - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of Java succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install nmap-ncat -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of nmap succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install git -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of git succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum erase awscli -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum erase of awscli succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install jq -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of jq succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y docker - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of docker succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - service docker start - usermod -a -G docker ec2-user - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y maven - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of maven succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - cd /home/ec2-user - su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user - su -c "pip3 install boto3 --user" -s /bin/sh ec2-user - su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user - - # install AWS CLI 2 - access with aws2 - cd /home/ec2-user - mkdir -p awscli - cd awscli - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install - - - # Install MongoDB shell - cd /home/ec2-user - wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-amazon2-x86_64-100.9.4.tgz - tar -zxvf mongodb-database-tools-amazon2-x86_64-100.9.4.tgz - sudo cp mongodb-database-tools-amazon2-x86_64-100.9.4/bin/* /usr/local/bin/ - - - # Install AWS SAM CLI - cd /home/ec2-user - mkdir -p awssam - cd awssam - wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip - unzip aws-sam-cli-linux-x86_64.zip -d sam-installation - sudo ./sam-installation/install - - # Set environment variables - DOCDB_CLUSTER_ENDPOINT=${docdb_cluster_endpoint} - DOCDB_CLUSTER_RESOURCE=${docdb_cluster_resource} - DOCDB_CLUSTER_IDENTIFIER=${docdb_cluster_identifier} - DOCDB_DATABASE=${docdb_database} - DOCDB_COLLECTION=${docdb_collection} - DOCDB_SECRET_ARN=${docdb_secret_arn} - AWS_REGION=${aws_region} - DOCDB_SUBNET_ONE=${docdb_subnet_one} - DOCDB_SUBNET_TWO=${docdb_subnet_two} - DOCDB_SUBNET_THREE=${docdb_subnet_three} - DOCDB_SECURITY_GROUP=${docdb_security_group} - DOCDB_CLUSTER_ADMIN_USER=${docdb_cluster_admin_user} - DOCDB_CLUSTER_PASSWORD=${docdb_cluster_password} - DOCDB_TRUST_STORE_PASSWORD=${docdb_trust_store_password} - SECURITY_GROUP=${security_group_id} - - - echo "export DOCDB_CLUSTER_ENDPOINT=$DOCDB_CLUSTER_ENDPOINT" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_RESOURCE=$DOCDB_CLUSTER_RESOURCE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_IDENTIFIER=$DOCDB_CLUSTER_IDENTIFIER" >> /home/ec2-user/.bash_profile - echo "export DOCDB_DATABASE=$DOCDB_DATABASE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_COLLECTION=$DOCDB_COLLECTION" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SECRET_ARN=$DOCDB_SECRET_ARN" >> /home/ec2-user/.bash_profile - echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_ONE=$DOCDB_SUBNET_ONE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_TWO=$DOCDB_SUBNET_TWO" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_THREE=$DOCDB_SUBNET_THREE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SECURITY_GROUP=$DOCDB_SECURITY_GROUP" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_ADMIN_USER=$DOCDB_CLUSTER_ADMIN_USER" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_PASSWORD=$DOCDB_CLUSTER_PASSWORD" >> /home/ec2-user/.bash_profile - echo "export DOCDB_TRUST_STORE_PASSWORD=$DOCDB_TRUST_STORE_PASSWORD" >> /home/ec2-user/.bash_profile - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - - - # Clone serverless patterns - cd /home/ec2-user - SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} - git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION - cd ./serverless-patterns - git sparse-checkout set --no-cone /documentdb-lambda-java-sam - git checkout - cd documentdb-lambda-java-sam - sudo chown -R ec2-user . - - #Install MongoShell - sudo cp ./mongodb-org-8.0.repo /etc/yum.repos.d - cd /home/ec2-user - mkdir mongoshell - cd mongoshell - sudo yum install -y mongodb-mongosh - - #Create Java Keystore to connect to DocumentDB - cd /home/ec2-user - mkdir mongotruststore - cd /home/ec2-user/mongotruststore - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/java_keystore_script.sh . - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/TRUSTSTORE_PASSWORD/$DOCDB_TRUST_STORE_PASSWORD/g" java_keystore_script.sh - chmod +x java_keystore_script.sh - sh ./java_keystore_script.sh - - #Create DocumentDB database and collection - cd /home/ec2-user/mongoshell - wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/docdb_db_collection.sh . - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/mongodbcolcreate.js . - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/connect_to_mongo_shell.sh . - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" docdb_db_collection.sh - sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" docdb_db_collection.sh - sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" docdb_db_collection.sh - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" docdb_db_collection.sh - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" docdb_db_collection.sh - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" mongodbcolcreate.js - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" mongodbcolcreate.js - sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" connect_to_mongo_shell.sh - sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" connect_to_mongo_shell.sh - sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" connect_to_mongo_shell.sh - chmod +x docdb_db_collection.sh - chmod +x connect_to_mongo_shell.sh - sh ./docdb_db_collection.sh - - #Substitute SAM template variables - cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam - cd documentdb_streams_consumer_dynamo_sam - cp template_original.yaml template.yaml - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/DOCDB_CLUSTER_IDENTIFIER/$DOCDB_CLUSTER_IDENTIFIER/g" template.yaml - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" template.yaml - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" template.yaml - sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml - sed -i "s/DOCDB_SECRET_ARN/$DOCDB_SECRET_ARN/g" template.yaml - sed -i "s/DOCDB_SUBNET_ONE/$DOCDB_SUBNET_ONE/g" template.yaml - sed -i "s/DOCDB_SUBNET_TWO/$DOCDB_SUBNET_TWO/g" template.yaml - sed -i "s/DOCDB_SUBNET_THREE/$DOCDB_SUBNET_THREE/g" template.yaml - sed -i "s/DOCDB_SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml - - #Adding DocumentDB variables to DocumentDB secret as CloudFormation cannot create a secret of type DocumentDB like you manually can - aws secretsmanager put-secret-value --secret-id AmazonDocumentDBCredentials --secret-string "{\"host\":\"$DOCDB_CLUSTER_ENDPOINT\",\"port\":\"27017\",\"username\":\"$DOCDB_CLUSTER_ADMIN_USER\",\"password\":\"$DOCDB_CLUSTER_PASSWORD\",\"engine\":\"mongo\",\"ssl\":\"true\",\"dbClusterIdentifier\":\"$DOCDB_CLUSTER_IDENTIFIER\"}" - - #Compiling Sender Program and Updating Command File with DocumentDB Database and Collection names - cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/documentdb_streams_message_sender_json - sudo chown -R ec2-user . - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" commands.sh - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" commands.sh - mvn clean install - - # Get IP CIDR range for EC2 Instance Connect - cd /home/ec2-user - mkdir -p ip_prefix - cd ip_prefix - git clone https://github.com/joetek/aws-ip-ranges-json.git - cd aws-ip-ranges-json - AWS_REGION=${aws_region} - EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') - echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile - SECURITY_GROUP=${security_group_id} - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP - - - docdb_cluster_endpoint: !GetAtt DocumentDBCluster.Endpoint - docdb_cluster_resource: !GetAtt DocumentDBCluster.ClusterResourceId - docdb_cluster_identifier: !Ref DocumentDBCluster - docdb_database: !Ref DocumentDBDatabaseName - docdb_collection: !Ref DocumentDBCollectionName - docdb_secret_arn: !Ref DocumentDBSecret - serverless_land_github_location: !Ref ServerlessLandGithubLocation - aws_region: !Ref 'AWS::Region' - java_version: !Ref JavaVersion - security_group_id : !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - docdb_subnet_one: !Ref PrivateSubnetDocDBOne - docdb_subnet_two: !Ref PrivateSubnetDocDBTwo - docdb_subnet_three: !Ref PrivateSubnetDocDBThree - docdb_security_group: !GetAtt DocumentDBSecurityGroup.GroupId - docdb_cluster_admin_user: !Ref DocumentDBClusterAdminUser - docdb_cluster_password: !Ref DocumentDBClusterPassword - docdb_trust_store_password: !Ref DocumentDBTrustStorePassword - - - EC2InstanceEndpoint: - Type: AWS::EC2::InstanceConnectEndpoint - Properties: - PreserveClientIp: true - SecurityGroupIds: - - !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - SubnetId: !Ref PublicSubnetOne - - EC2Role: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: '' - Effect: Allow - Principal: - Service: ec2.amazonaws.com - Action: 'sts:AssumeRole' - Path: "/" - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonDocDBFullAccess - - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - - arn:aws:iam::aws:policy/CloudWatchFullAccess - - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - - arn:aws:iam::aws:policy/AmazonS3FullAccess - - arn:aws:iam::aws:policy/IAMFullAccess - - arn:aws:iam::aws:policy/AWSLambda_FullAccess - - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 - Policies: - - PolicyName: DocumentDBAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "DocumentDBFullAccess", - "Effect": "Allow", - "Action": [ - "docdb:*", - "docdb-elastic:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecretsManagerAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:PutSecretValue", - "secretsmanager:DescribeSecret" - ], - "Resource": "${DocumentDBSecret}" - }, - { - "Effect": "Allow", - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret" - ], - "Resource": "${DocumentDBTrustStoreSecret}" - } - ] - }' - - PolicyName: CloudformationDeploy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "iam:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecurityGroupsPolicy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeSecurityGroups", - "ec2:DescribeSecurityGroupRules", - "ec2:DescribeTags" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:RevokeSecurityGroupIngress", - "ec2:AuthorizeSecurityGroupEgress", - "ec2:RevokeSecurityGroupEgress", - "ec2:ModifySecurityGroupRules", - "ec2:UpdateSecurityGroupRuleDescriptionsIngress", - "ec2:UpdateSecurityGroupRuleDescriptionsEgress" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "ec2:ModifySecurityGroupRules" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" - ] - } - ] - }' - - EC2InstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - InstanceProfileName: !Join - - '-' - - - 'EC2DocumentDBProfile' - - !Ref 'AWS::StackName' - Roles: - - !Ref EC2Role - - - # DocumentDB Subnet Group - DocumentDBSubnetGroup: - Type: AWS::DocDB::DBSubnetGroup - Properties: - DBSubnetGroupDescription: Subnet group for DocumentDB cluster - SubnetIds: - - !Ref PrivateSubnetDocDBOne - - !Ref PrivateSubnetDocDBTwo - - !Ref PrivateSubnetDocDBThree - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-subnet-group" - - # DocumentDB Instance-Based Cluster - DocumentDBCluster: - Type: AWS::DocDB::DBCluster - Properties: - DBClusterIdentifier: !Sub "${AWS::StackName}-docdb-cluster" - MasterUsername: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:username}}" - MasterUserPassword: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:password}}" - EngineVersion: !Ref DocumentDBEngineVersion - DBSubnetGroupName: !Ref DocumentDBSubnetGroup - VpcSecurityGroupIds: - - !Ref DocumentDBSecurityGroup - BackupRetentionPeriod: 7 - PreferredBackupWindow: "07:00-09:00" - PreferredMaintenanceWindow: "sun:09:00-sun:11:00" - StorageEncrypted: true - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-cluster" - - DocumentDBInstance1: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-1" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-1" - - DocumentDBInstance2: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-2" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-2" - - DocumentDBInstance3: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-3" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-31" - -Outputs: - VPCId: - Description: The ID of the VPC created - Value: !Ref 'VPC' - Export: - Name: !Sub "${AWS::StackName}-VPCID" - PublicSubnetOne: - Description: The name of the public subnet created - Value: !Ref 'PublicSubnetOne' - Export: - Name: !Sub "${AWS::StackName}-PublicSubnetOne" - PrivateSubnetDocDBOne: - Description: The ID of private subnet one created - Value: !Ref 'PrivateSubnetDocDBOne' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBOne" - PrivateSubnetDocDBTwo: - Description: The ID of private subnet two created - Value: !Ref 'PrivateSubnetDocDBTwo' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBTwo" - PrivateSubnetDocDBThree: - Description: The ID of private subnet three created - Value: !Ref 'PrivateSubnetDocDBThree' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBThree" - VPCStackName: - Description: The name of the VPC Stack - Value: !Ref 'AWS::StackName' - Export: - Name: !Sub "${AWS::StackName}-VPCStackName" - DocumentDBClusterEndpoint: - Description: DocumentDB Instance-Based Cluster Endpoint - Value: !GetAtt DocumentDBCluster.Endpoint - Export: - Name: !Sub "${AWS::StackName}-DocumentDBClusterEndpoint" - DocumentDBSecretArn: - Description: ARN of the DocumentDB credentials secret - Value: !Ref DocumentDBSecret - Export: - Name: !Sub "${AWS::StackName}-DocumentDBSecretArn" - SecurityGroupId: - Description: ID of security group for DocumentDB clients - Value: !GetAtt DocumentDBSecurityGroup.GroupId - Export: - Name: !Sub "${AWS::StackName}-SecurityGroupId" - EC2InstanceEndpointID: - Description: The ID of the EC2 Instance Endpoint - Value: !Ref EC2InstanceEndpoint - DocumentDBDatabaseName: - Description: The Database name to use for the Java Lambda Function - Value: !Ref DocumentDBDatabaseName - Export: - Name: !Sub "${AWS::StackName}-DocumentDBDatabaseName" - DocumentDBCollectionName: - Description: The Collection name to use for the Java Lambda Function - Value: !Ref DocumentDBCollectionName - Export: - Name: !Sub "${AWS::StackName}-DocumentDBCollectionName" diff --git a/activemq-private-lambda-java-sam/VPCOnly.yaml b/activemq-private-lambda-java-sam/VPCOnly.yaml deleted file mode 100644 index 09773014b..000000000 --- a/activemq-private-lambda-java-sam/VPCOnly.yaml +++ /dev/null @@ -1,116 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Parameters: - LatestAmiId: - Type: 'AWS::SSM::Parameter::Value' - Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' - -Mappings: - SubnetConfig: - VPC: - CIDR: '10.0.0.0/16' - PublicOne: - CIDR: '10.0.0.0/24' - PublicTwo: - CIDR: '10.0.1.0/24' - PublicThree: - CIDR: '10.0.2.0/24' - PrivateSubnetActiveMQOne: - CIDR: '10.0.3.0/24' - PrivateSubnetActiveMQTwo: - CIDR: '10.0.4.0/24' - PrivateSubnetActiveMQThree: - CIDR: '10.0.5.0/24' - -Resources: - VPC: - Type: AWS::EC2::VPC - Properties: - EnableDnsSupport: true - EnableDnsHostnames: true - CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - Tags: - - Key: 'Name' - Value: 'ActiveMQVPC' - - PublicSubnetOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetOne' - - PrivateSubnetActiveMQOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQOne' - - PrivateSubnetActiveMQTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQTwo' - - InternetGateway: - Type: AWS::EC2::InternetGateway - GatewayAttachement: - Type: AWS::EC2::VPCGatewayAttachment - Properties: - VpcId: !Ref 'VPC' - InternetGatewayId: !Ref 'InternetGateway' - - ActiveMQSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: ActiveMQ Security Group - VpcId: !Ref 'VPC' - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 61617 - ToPort: 61617 - CidrIp: 10.0.0.0/16 - - IpProtocol: tcp - FromPort: 8162 - ToPort: 8162 - CidrIp: 10.0.0.0/16 - -Outputs: - VPCId: - Value: !Ref 'VPC' - Export: - Name: !Sub "${AWS::StackName}-VPCID" - PrivateSubnetOne: - Value: !Ref 'PrivateSubnetActiveMQOne' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetOne" - PrivateSubnetTwo: - Value: !Ref 'PrivateSubnetActiveMQTwo' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetTwo" - SecurityGroupId: - Value: !GetAtt ActiveMQSecurityGroup.GroupId - Export: - Name: !Sub "${AWS::StackName}-SecurityGroupId" diff --git a/activemq-private-lambda-java-sam/create-activemq.sh b/activemq-private-lambda-java-sam/create-activemq.sh deleted file mode 100755 index 2d49fb96f..000000000 --- a/activemq-private-lambda-java-sam/create-activemq.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# Deploy VPC first -aws cloudformation deploy \ - --template-file VPCOnly.yaml \ - --stack-name activemq-vpc \ - --region us-west-2 \ - --profile indranil8724 - -# Get VPC outputs -VPC_ID=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`VPCId`].OutputValue' --output text) -SUBNET1=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`PrivateSubnetOne`].OutputValue' --output text) -SUBNET2=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`PrivateSubnetTwo`].OutputValue' --output text) -SG_ID=$(aws cloudformation describe-stacks --stack-name activemq-vpc --region us-west-2 --profile indranil8724 --query 'Stacks[0].Outputs[?OutputKey==`SecurityGroupId`].OutputValue' --output text) - -# Create MQ Configuration -CONFIG_ID=$(aws mq create-configuration \ - --name activemq-config \ - --engine-type ACTIVEMQ \ - --engine-version 5.18 \ - --region us-west-2 \ - --profile indranil8724 \ - --query 'Id' --output text) - -# Create MQ Broker -aws mq create-broker \ - --broker-name ActiveMQJavaLambdaBroker \ - --engine-type ACTIVEMQ \ - --engine-version 5.18 \ - --host-instance-type mq.t3.micro \ - --deployment-mode ACTIVE_STANDBY_MULTI_AZ \ - --users Username=activemqadmin,Password=activemqPassword123,ConsoleAccess=true \ - --subnet-ids $SUBNET1 $SUBNET2 \ - --security-groups $SG_ID \ - --configuration Id=$CONFIG_ID,Revision=1 \ - --region us-west-2 \ - --profile indranil8724 - -echo "MQ Broker creation initiated. Check AWS Console for status." diff --git a/activemq-private-lambda-java-sam/test-mq.yaml b/activemq-private-lambda-java-sam/test-mq.yaml deleted file mode 100644 index 815f9237b..000000000 --- a/activemq-private-lambda-java-sam/test-mq.yaml +++ /dev/null @@ -1,12 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Resources: - TestConfig: - Type: AWS::MQ::Configuration - Properties: - Name: test-config - EngineType: ACTIVEMQ - EngineVersion: 5.18 - Data: | - - - From 87b3305c7cb22e5ef3069d7d124fe1e9ccbd63ac Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Fri, 17 Oct 2025 22:50:58 -0700 Subject: [PATCH 04/18] Fixed ActiveMQ Private Lambda Java SAM project --- .../ActiveMQAndClientEC2.yaml | 27 +++++++++++++++---- .../activemq_queue_browser.sh | 11 ++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 activemq-private-lambda-java-sam/activemq_queue_browser.sh diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index a2150211a..4b46afda0 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -418,7 +418,7 @@ Resources: # install Java JAVA_VERSION=${java_version} - echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile if [ "$JAVA_VERSION" == "java11" ]; then sudo yum install java-11-amazon-corretto-devel -y elif [ "$JAVA_VERSION" == "java17" ]; then @@ -568,9 +568,9 @@ Resources: # Set environment variables ACTIVEMQ_BROKER_ID=${activemq_broker_id} ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} - #ACTIVEMQ_BROKER_ENDPOINT1=${activemq_broker_endpoint1} - #ACTIVEMQ_BROKER_ENDPOINT2=${activemq_broker_endpoint2} - ACTIVEMQ_BROKER_ENDPOINT="failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})" + ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} + ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} + ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} @@ -584,6 +584,8 @@ Resources: echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile @@ -628,14 +630,29 @@ Resources: tar zxvf apache-activemq-5.18.6-bin.tar.gz sudo chown -R ec2-user . + + #Update Shell script for sending ActiveMQ messages to Lambda function cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json sudo chown ec2-user ./commands.sh - sed -i "s/ACTIVEMQ_BROKER_ENDPOINT/$ACTIVEMQ_BROKER_ENDPOINT/g" commands.sh + source /home/ec2-user/.bash_profile + echo "ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|\"${ACTIVEMQ_BROKER_ENDPOINT}\"|g" commands.sh sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh mvn clean install + #Update Shell script for browsing messages in ActiveMQ queue + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + sudo chown ec2-user ./activemq_queue_browser.sh + source /home/ec2-user/.bash_profile + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|$ACTIVEMQ_BROKER_ENDPOINT_ONE|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|$ACTIVEMQ_BROKER_ENDPOINT_TWO|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh + + # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user mkdir -p ip_prefix diff --git a/activemq-private-lambda-java-sam/activemq_queue_browser.sh b/activemq-private-lambda-java-sam/activemq_queue_browser.sh new file mode 100644 index 000000000..834cd798f --- /dev/null +++ b/activemq-private-lambda-java-sam/activemq_queue_browser.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +#This command can be used to find messages in the queue created for the Lambda function +#Modify the below command to use the activemq client to execute other commands on the cluster + +/home/ec2-user/activemq_client/apache-activemq-5.18.6/bin/activemq browse --amqurl ACTIVEMQ_BROKER_ENDPOINT_ONE --user ACTIVEMQ_BROKER_ADMIN_USER --password ACTIVEMQ_BROKER_PASSWORD ACTIVEMQ_QUEUE_NAME + + +#Use the below command if the primary ActiveMQ broker is down for whatever reason + +#/home/ec2-user/activemq_client/apache-activemq-5.18.6/bin/activemq browse --amqurl ACTIVEMQ_BROKER_ENDPOINT_TWO --user ACTIVEMQ_BROKER_ADMIN_USER --password ACTIVEMQ_BROKER_PASSWORD ACTIVEMQ_QUEUE_NAME \ No newline at end of file From e43e02f81a94c450500c02523ad84398d351baf1 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sat, 18 Oct 2025 00:20:11 -0700 Subject: [PATCH 05/18] Fixed ActiveMQ Private Lambda Java SAM Project --- .../ActiveMQAndClientEC2.yaml | 11 +- .../ActiveMQAndClientEC2Backup.yaml | 878 ++++++++++++++++++ 2 files changed, 884 insertions(+), 5 deletions(-) create mode 100644 activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index 4b46afda0..d5f895c94 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -570,7 +570,8 @@ Resources: ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} - ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" + #ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" + ACTIVEMQ_BROKER_ENDPOINT="\"failover:($ACTIVEMQ_BROKER_ENDPOINT_ONE,$ACTIVEMQ_BROKER_ENDPOINT_ONE)\"" ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} @@ -584,8 +585,8 @@ Resources: echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile + #echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile + #echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile @@ -646,8 +647,8 @@ Resources: cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam sudo chown ec2-user ./activemq_queue_browser.sh source /home/ec2-user/.bash_profile - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|$ACTIVEMQ_BROKER_ENDPOINT_ONE|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|$ACTIVEMQ_BROKER_ENDPOINT_TWO|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml new file mode 100644 index 000000000..75c5e7a8a --- /dev/null +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml @@ -0,0 +1,878 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + ActiveMQEngineVersion: + Type: String + Default: 5.18 + Description: ActiveMQ engine version + JavaVersion: + Type: String + Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 + AllowedValues: + - java11 + - java17 + - java21 + Default: java21 + ActiveMQBrokerName: + Type: String + Default: ActiveMQJavaLambdaBroker + Description: ActiveMQ broker name for Lambda function + ActiveMQQueueName: + Type: String + Default: ActiveMQJavaLambdaQueue + Description: ActiveMQ queue name for Lambda function + ActiveMQBrokerAdminUser: + Type: String + Description: Username for the ActiveMQ Broker + Default: activemqadmin + ActiveMQBrokerPassword: + Type: String + Description: Password for the ActiveMQ Broker + Default: activemqPassword123 + NoEcho: true + ServerlessLandGithubLocation: + Type: String + Default: https://github.com/aws-samples/serverless-patterns.git + Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PublicThree: + CIDR: '10.0.2.0/24' + PrivateSubnetActiveMQOne: + CIDR: '10.0.3.0/24' + PrivateSubnetActiveMQTwo: + CIDR: '10.0.4.0/24' + PrivateSubnetActiveMQThree: + CIDR: '10.0.5.0/24' + +Resources: + # Secrets Manager Secret for ActiveMQ credentials + ActiveMQSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonActiveMQCredentials' + Description: ActiveMQ broker master user credentials + SecretString: !Sub | + { + "username": "${ActiveMQBrokerAdminUser}", + "password": "${ActiveMQBrokerPassword}" + } + + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'ActiveMQVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetTwo' + PublicSubnetThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetThree' + PrivateSubnetActiveMQOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQOne' + PrivateSubnetActiveMQTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQTwo' + PrivateSubnetActiveMQThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQThree', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetActiveMQThree' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + NATEIP1: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP1.AllocationId + SubnetId: !Ref 'PublicSubnetOne' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway1' + + NATEIP2: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP2.AllocationId + SubnetId: !Ref 'PublicSubnetTwo' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway2' + + NATEIP3: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway3: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP3.AllocationId + SubnetId: !Ref 'PublicSubnetThree' + Tags: + - Key: 'Name' + Value: 'ActiveMQNATGateway3' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + PublicSubnetThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetThree + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute1: + Type: AWS::EC2::Route + DependsOn: NATGateway1 + Properties: + RouteTableId: !Ref 'PrivateRouteTable1' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway1' + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute2: + Type: AWS::EC2::Route + DependsOn: NATGateway2 + Properties: + RouteTableId: !Ref 'PrivateRouteTable2' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway2' + + PrivateRouteTable3: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute3: + Type: AWS::EC2::Route + DependsOn: NATGateway3 + Properties: + RouteTableId: !Ref 'PrivateRouteTable3' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway3' + + PrivateSubnetActiveMQOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnetActiveMQOne + + PrivateSubnetActiveMQTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnetActiveMQTwo + + PrivateSubnetActiveMQThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable3 + SubnetId: !Ref PrivateSubnetActiveMQThree + + ActiveMQClientInstanceSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup + GroupName: !Sub "${AWS::StackName} Security group attached to the ActiveMQ client" + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 10.0.0.0/16 + + ActiveMQSecurityGroup: + Type: AWS::EC2::SecurityGroup + DependsOn: [VPC,ActiveMQClientInstanceSecurityGroup] + Properties: + GroupDescription: ActiveMQ Security Group + GroupName: !Sub "${AWS::StackName} Security group for the ActiveMQ broker" + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 61617 + ToPort: 61617 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 8162 + ToPort: 8162 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 0 + ToPort: 65535 + CidrIp: 10.0.0.0/16 + + ActiveMQClientSelfIngressAllowRule: + Type: AWS::EC2::SecurityGroupIngress + DependsOn: ActiveMQClientInstanceSecurityGroup + Properties: + GroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + + # ActiveMQ Configuration + ActiveMQConfiguration: + Type: AWS::AmazonMQ::Configuration + Properties: + Name: !Sub "${AWS::StackName}-activemq-config" + Description: ActiveMQ configuration for the cluster + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + Data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8YnJva2VyIHhtbG5zPSJodHRwOi8vYWN0aXZlbXEuYXBhY2hlLm9yZy9zY2hlbWEvY29yZSI+CiAgPGRlc3RpbmF0aW9uUG9saWN5PgogICAgPHBvbGljeU1hcD4KICAgICAgPHBvbGljeUVudHJpZXM+CiAgICAgICAgPHBvbGljeUVudHJ5IHRvcGljPSI+IiBwcm9kdWNlckZsb3dDb250cm9sPSJ0cnVlIj4KICAgICAgICAgIDxwZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgICAgIDxzcG9vbGluZ1N1YnNjcmlwdGlvblBlbmRpbmdNZXNzYWdlTGltaXRTdHJhdGVneSBsaW1pdD0iMTAwMCIvPgogICAgICAgICAgPC9wZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgPC9wb2xpY3lFbnRyeT4KICAgICAgICA8cG9saWN5RW50cnkgcXVldWU9Ij4iIHByb2R1Y2VyRmxvd0NvbnRyb2w9InRydWUiIG1lbW9yeUxpbWl0PSIxbWIiPgogICAgICAgIDwvcG9saWN5RW50cnk+CiAgICAgIDwvcG9saWN5RW50cmllcz4KICAgIDwvcG9saWN5TWFwPgogIDwvZGVzdGluYXRpb25Qb2xpY3k+CiAgPHN5c3RlbVVzYWdlPgogICAgPHN5c3RlbVVzYWdlPgogICAgICA8bWVtb3J5VXNhZ2U+CiAgICAgICAgPG1lbW9yeVVzYWdlIGxpbWl0PSI2NCBtYiIvPgogICAgICA8L21lbW9yeVVzYWdlPgogICAgICA8c3RvcmVVc2FnZT4KICAgICAgICA8c3RvcmVVc2FnZSBsaW1pdD0iNTEyIG1iIi8+CiAgICAgIDwvc3RvcmVVc2FnZT4KICAgICAgPHRlbXBVc2FnZT4KICAgICAgICA8dGVtcFVzYWdlIGxpbWl0PSIxMjggbWIiLz4KICAgICAgPC90ZW1wVXNhZ2U+CiAgICA8L3N5c3RlbVVzYWdlPgogIDwvc3lzdGVtVXNhZ2U+CjwvYnJva2VyPgo= + + # ActiveMQ Broker + ActiveMQBroker: + Type: AWS::AmazonMQ::Broker + Properties: + BrokerName: !Ref ActiveMQBrokerName + DeploymentMode: ACTIVE_STANDBY_MULTI_AZ + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + HostInstanceType: mq.t3.micro + PubliclyAccessible: false + AutoMinorVersionUpgrade: true + Configuration: + Id: !Ref ActiveMQConfiguration + Revision: 1 + Users: + - Username: !Ref ActiveMQBrokerAdminUser + Password: !Ref ActiveMQBrokerPassword + ConsoleAccess: true + Groups: + - admin + SubnetIds: + - !Ref PrivateSubnetActiveMQOne + - !Ref PrivateSubnetActiveMQTwo + SecurityGroups: + - !Ref ActiveMQSecurityGroup + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-activemq-broker" + + ActiveMQClientEC2Instance: + DependsOn: ActiveMQBroker + Type: AWS::EC2::Instance + Properties: + InstanceType: m5.large + IamInstanceProfile: !Ref EC2InstanceProfile + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + SubnetId: !Ref PublicSubnetOne + SecurityGroupIds: [!GetAtt ActiveMQClientInstanceSecurityGroup.GroupId] + ImageId: !Ref LatestAmiId + Tags: + - Key: 'Name' + Value: 'ActiveMQClientInstance' + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: 50 + VolumeType: gp2 + DeleteOnTermination: true + UserData: + Fn::Base64: + !Sub + - | + #!/bin/bash + yum update -y + + # install Java + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum update -y + + # install Java + JAVA_VERSION=${java_version} + echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + if [ "$JAVA_VERSION" == "java11" ]; then + sudo yum install java-11-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java17" ]; then + sudo yum install java-17-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java21" ]; then + sudo yum install java-21-amazon-corretto-devel -y + else + sudo yum install java-21-amazon-corretto-devel -y + fi + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of Java succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install nmap-ncat -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of nmap succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install git -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of git succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum erase awscli -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum erase of awscli succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install jq -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of jq succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y docker + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of docker succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + service docker start + usermod -a -G docker ec2-user + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y maven + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of maven succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + cd /home/ec2-user + su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user + su -c "pip3 install boto3 --user" -s /bin/sh ec2-user + su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user + + # install AWS CLI 2 - access with aws2 + cd /home/ec2-user + mkdir -p awscli + cd awscli + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + # Install AWS SAM CLI + cd /home/ec2-user + mkdir -p awssam + cd awssam + wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + unzip aws-sam-cli-linux-x86_64.zip -d sam-installation + sudo ./sam-installation/install + + # Set environment variables + ACTIVEMQ_BROKER_ID=${activemq_broker_id} + ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} + ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" + #ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} + #ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} + ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} + ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} + AWS_REGION=${aws_region} + ACTIVEMQ_SUBNET_ONE=${activemq_subnet_one} + ACTIVEMQ_SUBNET_TWO=${activemq_subnet_two} + ACTIVEMQ_SUBNET_THREE=${activemq_subnet_three} + ACTIVEMQ_SECURITY_GROUP=${activemq_security_group} + ACTIVEMQ_BROKER_ADMIN_USER=${activemq_broker_admin_user} + ACTIVEMQ_BROKER_PASSWORD=${activemq_broker_password} + SECURITY_GROUP=${security_group_id} + + echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile + #echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile + #echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_ONE=$ACTIVEMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_TWO=$ACTIVEMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_THREE=$ACTIVEMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECURITY_GROUP=$ACTIVEMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ADMIN_USER=$ACTIVEMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_PASSWORD=$ACTIVEMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + + # Clone serverless patterns + cd /home/ec2-user + SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} + git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION + cd ./serverless-patterns + git sparse-checkout set --no-cone /activemq-private-lambda-java-sam + git checkout + cd activemq-private-lambda-java-sam + sudo chown -R ec2-user . + + #Substitute SAM template variables + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + cd activemq_consumer_dynamo_sam + cp template_original.yaml template.yaml + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/ACTIVEMQ_BROKER_ARN/$ACTIVEMQ_BROKER_ARN/g" template.yaml + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" template.yaml + sed -i "s/ACTIVEMQ_SECRET_ARN/$ACTIVEMQ_SECRET_ARN/g" template.yaml + sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_ONE/$ACTIVEMQ_SUBNET_ONE/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_TWO/$ACTIVEMQ_SUBNET_TWO/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_THREE/$ACTIVEMQ_SUBNET_THREE/g" template.yaml + sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + + #Install ActiveMQ (needed in case you want to use the CLI as a client to look at queues etc.) + mkdir /home/ec2-user/activemq_client + cd /home/ec2-user/activemq_client + wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz + tar zxvf apache-activemq-5.18.6-bin.tar.gz + sudo chown -R ec2-user . + + + + #Update Shell script for sending ActiveMQ messages to Lambda function + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json + sudo chown ec2-user ./commands.sh + source /home/ec2-user/.bash_profile + echo "ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|\"${ACTIVEMQ_BROKER_ENDPOINT}\"|g" commands.sh + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh + mvn clean install + + + #Update Shell script for browsing messages in ActiveMQ queue + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + sudo chown ec2-user ./activemq_queue_browser.sh + source /home/ec2-user/.bash_profile + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh + + + # Get IP CIDR range for EC2 Instance Connect + cd /home/ec2-user + mkdir -p ip_prefix + cd ip_prefix + git clone https://github.com/joetek/aws-ip-ranges-json.git + cd aws-ip-ranges-json + AWS_REGION=${aws_region} + EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') + echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile + SECURITY_GROUP=${security_group_id} + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP + + - activemq_broker_id: !Ref ActiveMQBroker + activemq_broker_arn: !GetAtt ActiveMQBroker.Arn + activemq_broker_endpoint1: !Select [ 0, !GetAtt ActiveMQBroker.OpenWireEndpoints ] + activemq_broker_endpoint2: !Select [ 1, !GetAtt ActiveMQBroker.OpenWireEndpoints ] + activemq_queue_name: !Ref ActiveMQQueueName + activemq_secret_arn: !Ref ActiveMQSecret + serverless_land_github_location: !Ref ServerlessLandGithubLocation + aws_region: !Ref 'AWS::Region' + java_version: !Ref JavaVersion + security_group_id : !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + activemq_subnet_one: !Ref PrivateSubnetActiveMQOne + activemq_subnet_two: !Ref PrivateSubnetActiveMQTwo + activemq_subnet_three: !Ref PrivateSubnetActiveMQThree + activemq_security_group: !GetAtt ActiveMQSecurityGroup.GroupId + activemq_broker_admin_user: !Ref ActiveMQBrokerAdminUser + activemq_broker_password: !Ref ActiveMQBrokerPassword + + EC2InstanceEndpoint: + Type: AWS::EC2::InstanceConnectEndpoint + Properties: + PreserveClientIp: true + SecurityGroupIds: + - !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + SubnetId: !Ref PublicSubnetOne + + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Action: 'sts:AssumeRole' + Path: "/" + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonMQFullAccess + - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore + - arn:aws:iam::aws:policy/AmazonS3FullAccess + - arn:aws:iam::aws:policy/IAMFullAccess + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 + Policies: + - PolicyName: ActiveMQAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ActiveMQFullAccess", + "Effect": "Allow", + "Action": [ + "mq:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecretsManagerAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${ActiveMQSecret}" + } + ] + }' + - PolicyName: CloudformationDeploy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecurityGroupsPolicy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupEgress", + "ec2:ModifySecurityGroupRules", + "ec2:UpdateSecurityGroupRuleDescriptionsIngress", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:ModifySecurityGroupRules" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" + ] + } + ] + }' + + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Join + - '-' + - - 'EC2ActiveMQProfile' + - !Ref 'AWS::StackName' + Roles: + - !Ref EC2Role + +Outputs: + VPCId: + Description: The ID of the VPC created + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PublicSubnetOne: + Description: The name of the public subnet created + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Sub "${AWS::StackName}-PublicSubnetOne" + PrivateSubnetActiveMQOne: + Description: The ID of private subnet one created + Value: !Ref 'PrivateSubnetActiveMQOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQOne" + PrivateSubnetActiveMQTwo: + Description: The ID of private subnet two created + Value: !Ref 'PrivateSubnetActiveMQTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQTwo" + PrivateSubnetActiveMQThree: + Description: The ID of private subnet three created + Value: !Ref 'PrivateSubnetActiveMQThree' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQThree" + VPCStackName: + Description: The name of the VPC Stack + Value: !Ref 'AWS::StackName' + Export: + Name: !Sub "${AWS::StackName}-VPCStackName" + ActiveMQBrokerEndpoint1: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint1" + ActiveMQBrokerEndpoint2: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Select [1, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint2" + ActiveMQBrokerConsoleURL: + Description: ActiveMQ Broker Web Console URL + Value: !Sub + - "https://${endpoint}" + - endpoint: !Select [0, !GetAtt ActiveMQBroker.IpAddresses] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerConsoleURL" + ActiveMQSecretArn: + Description: ARN of the ActiveMQ credentials secret + Value: !Ref ActiveMQSecret + Export: + Name: !Sub "${AWS::StackName}-ActiveMQSecretArn" + SecurityGroupId: + Description: ID of security group for ActiveMQ clients + Value: !GetAtt ActiveMQSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" + EC2InstanceEndpointID: + Description: The ID of the EC2 Instance Endpoint + Value: !Ref EC2InstanceEndpoint + ActiveMQBrokerName: + Description: The Broker name to use for the Java Lambda Function + Value: !Ref ActiveMQBrokerName + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerName" + ActiveMQQueueName: + Description: The Queue name to use for the Java Lambda Function + Value: !Ref ActiveMQQueueName + Export: + Name: !Sub "${AWS::StackName}-ActiveMQQueueName" From 61ede022680cd466db33dff3337cdda6a52ac9b3 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sat, 18 Oct 2025 00:20:19 -0700 Subject: [PATCH 06/18] Revert "Fixed ActiveMQ Private Lambda Java SAM Project" This reverts commit e43e02f81a94c450500c02523ad84398d351baf1. --- .../ActiveMQAndClientEC2.yaml | 11 +- .../ActiveMQAndClientEC2Backup.yaml | 878 ------------------ 2 files changed, 5 insertions(+), 884 deletions(-) delete mode 100644 activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index d5f895c94..4b46afda0 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -570,8 +570,7 @@ Resources: ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} - #ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" - ACTIVEMQ_BROKER_ENDPOINT="\"failover:($ACTIVEMQ_BROKER_ENDPOINT_ONE,$ACTIVEMQ_BROKER_ENDPOINT_ONE)\"" + ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} @@ -585,8 +584,8 @@ Resources: echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - #echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile - #echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile @@ -647,8 +646,8 @@ Resources: cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam sudo chown ec2-user ./activemq_queue_browser.sh source /home/ec2-user/.bash_profile - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|$ACTIVEMQ_BROKER_ENDPOINT_ONE|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|$ACTIVEMQ_BROKER_ENDPOINT_TWO|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml deleted file mode 100644 index 75c5e7a8a..000000000 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2Backup.yaml +++ /dev/null @@ -1,878 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Parameters: - LatestAmiId: - Type: 'AWS::SSM::Parameter::Value' - Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' - ActiveMQEngineVersion: - Type: String - Default: 5.18 - Description: ActiveMQ engine version - JavaVersion: - Type: String - Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 - AllowedValues: - - java11 - - java17 - - java21 - Default: java21 - ActiveMQBrokerName: - Type: String - Default: ActiveMQJavaLambdaBroker - Description: ActiveMQ broker name for Lambda function - ActiveMQQueueName: - Type: String - Default: ActiveMQJavaLambdaQueue - Description: ActiveMQ queue name for Lambda function - ActiveMQBrokerAdminUser: - Type: String - Description: Username for the ActiveMQ Broker - Default: activemqadmin - ActiveMQBrokerPassword: - Type: String - Description: Password for the ActiveMQ Broker - Default: activemqPassword123 - NoEcho: true - ServerlessLandGithubLocation: - Type: String - Default: https://github.com/aws-samples/serverless-patterns.git - Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork - -Mappings: - SubnetConfig: - VPC: - CIDR: '10.0.0.0/16' - PublicOne: - CIDR: '10.0.0.0/24' - PublicTwo: - CIDR: '10.0.1.0/24' - PublicThree: - CIDR: '10.0.2.0/24' - PrivateSubnetActiveMQOne: - CIDR: '10.0.3.0/24' - PrivateSubnetActiveMQTwo: - CIDR: '10.0.4.0/24' - PrivateSubnetActiveMQThree: - CIDR: '10.0.5.0/24' - -Resources: - # Secrets Manager Secret for ActiveMQ credentials - ActiveMQSecret: - Type: AWS::SecretsManager::Secret - Properties: - Name: 'AmazonActiveMQCredentials' - Description: ActiveMQ broker master user credentials - SecretString: !Sub | - { - "username": "${ActiveMQBrokerAdminUser}", - "password": "${ActiveMQBrokerPassword}" - } - - VPC: - Type: AWS::EC2::VPC - Properties: - EnableDnsSupport: true - EnableDnsHostnames: true - CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - Tags: - - Key: 'Name' - Value: 'ActiveMQVPC' - - PublicSubnetOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetOne' - PublicSubnetTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetTwo' - PublicSubnetThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetThree' - PrivateSubnetActiveMQOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQOne' - PrivateSubnetActiveMQTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQTwo' - PrivateSubnetActiveMQThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQThree', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQThree' - - InternetGateway: - Type: AWS::EC2::InternetGateway - GatewayAttachement: - Type: AWS::EC2::VPCGatewayAttachment - Properties: - VpcId: !Ref 'VPC' - InternetGatewayId: !Ref 'InternetGateway' - - NATEIP1: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway1: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP1.AllocationId - SubnetId: !Ref 'PublicSubnetOne' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway1' - - NATEIP2: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway2: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP2.AllocationId - SubnetId: !Ref 'PublicSubnetTwo' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway2' - - NATEIP3: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway3: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP3.AllocationId - SubnetId: !Ref 'PublicSubnetThree' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway3' - - PublicRouteTable: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PublicRoute: - Type: AWS::EC2::Route - DependsOn: GatewayAttachement - Properties: - RouteTableId: !Ref 'PublicRouteTable' - DestinationCidrBlock: '0.0.0.0/0' - GatewayId: !Ref 'InternetGateway' - - PublicSubnetOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetOne - RouteTableId: !Ref PublicRouteTable - - PublicSubnetTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetTwo - RouteTableId: !Ref PublicRouteTable - - PublicSubnetThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetThree - RouteTableId: !Ref PublicRouteTable - - PrivateRouteTable1: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute1: - Type: AWS::EC2::Route - DependsOn: NATGateway1 - Properties: - RouteTableId: !Ref 'PrivateRouteTable1' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway1' - - PrivateRouteTable2: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute2: - Type: AWS::EC2::Route - DependsOn: NATGateway2 - Properties: - RouteTableId: !Ref 'PrivateRouteTable2' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway2' - - PrivateRouteTable3: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute3: - Type: AWS::EC2::Route - DependsOn: NATGateway3 - Properties: - RouteTableId: !Ref 'PrivateRouteTable3' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway3' - - PrivateSubnetActiveMQOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable1 - SubnetId: !Ref PrivateSubnetActiveMQOne - - PrivateSubnetActiveMQTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable2 - SubnetId: !Ref PrivateSubnetActiveMQTwo - - PrivateSubnetActiveMQThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable3 - SubnetId: !Ref PrivateSubnetActiveMQThree - - ActiveMQClientInstanceSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup - GroupName: !Sub "${AWS::StackName} Security group attached to the ActiveMQ client" - VpcId: !Ref VPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 10.0.0.0/16 - - ActiveMQSecurityGroup: - Type: AWS::EC2::SecurityGroup - DependsOn: [VPC,ActiveMQClientInstanceSecurityGroup] - Properties: - GroupDescription: ActiveMQ Security Group - GroupName: !Sub "${AWS::StackName} Security group for the ActiveMQ broker" - VpcId: !Ref 'VPC' - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 61617 - ToPort: 61617 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: 8162 - ToPort: 8162 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: 0 - ToPort: 65535 - CidrIp: 10.0.0.0/16 - - ActiveMQClientSelfIngressAllowRule: - Type: AWS::EC2::SecurityGroupIngress - DependsOn: ActiveMQClientInstanceSecurityGroup - Properties: - GroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - # ActiveMQ Configuration - ActiveMQConfiguration: - Type: AWS::AmazonMQ::Configuration - Properties: - Name: !Sub "${AWS::StackName}-activemq-config" - Description: ActiveMQ configuration for the cluster - EngineType: ACTIVEMQ - EngineVersion: !Ref ActiveMQEngineVersion - Data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8YnJva2VyIHhtbG5zPSJodHRwOi8vYWN0aXZlbXEuYXBhY2hlLm9yZy9zY2hlbWEvY29yZSI+CiAgPGRlc3RpbmF0aW9uUG9saWN5PgogICAgPHBvbGljeU1hcD4KICAgICAgPHBvbGljeUVudHJpZXM+CiAgICAgICAgPHBvbGljeUVudHJ5IHRvcGljPSI+IiBwcm9kdWNlckZsb3dDb250cm9sPSJ0cnVlIj4KICAgICAgICAgIDxwZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgICAgIDxzcG9vbGluZ1N1YnNjcmlwdGlvblBlbmRpbmdNZXNzYWdlTGltaXRTdHJhdGVneSBsaW1pdD0iMTAwMCIvPgogICAgICAgICAgPC9wZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgPC9wb2xpY3lFbnRyeT4KICAgICAgICA8cG9saWN5RW50cnkgcXVldWU9Ij4iIHByb2R1Y2VyRmxvd0NvbnRyb2w9InRydWUiIG1lbW9yeUxpbWl0PSIxbWIiPgogICAgICAgIDwvcG9saWN5RW50cnk+CiAgICAgIDwvcG9saWN5RW50cmllcz4KICAgIDwvcG9saWN5TWFwPgogIDwvZGVzdGluYXRpb25Qb2xpY3k+CiAgPHN5c3RlbVVzYWdlPgogICAgPHN5c3RlbVVzYWdlPgogICAgICA8bWVtb3J5VXNhZ2U+CiAgICAgICAgPG1lbW9yeVVzYWdlIGxpbWl0PSI2NCBtYiIvPgogICAgICA8L21lbW9yeVVzYWdlPgogICAgICA8c3RvcmVVc2FnZT4KICAgICAgICA8c3RvcmVVc2FnZSBsaW1pdD0iNTEyIG1iIi8+CiAgICAgIDwvc3RvcmVVc2FnZT4KICAgICAgPHRlbXBVc2FnZT4KICAgICAgICA8dGVtcFVzYWdlIGxpbWl0PSIxMjggbWIiLz4KICAgICAgPC90ZW1wVXNhZ2U+CiAgICA8L3N5c3RlbVVzYWdlPgogIDwvc3lzdGVtVXNhZ2U+CjwvYnJva2VyPgo= - - # ActiveMQ Broker - ActiveMQBroker: - Type: AWS::AmazonMQ::Broker - Properties: - BrokerName: !Ref ActiveMQBrokerName - DeploymentMode: ACTIVE_STANDBY_MULTI_AZ - EngineType: ACTIVEMQ - EngineVersion: !Ref ActiveMQEngineVersion - HostInstanceType: mq.t3.micro - PubliclyAccessible: false - AutoMinorVersionUpgrade: true - Configuration: - Id: !Ref ActiveMQConfiguration - Revision: 1 - Users: - - Username: !Ref ActiveMQBrokerAdminUser - Password: !Ref ActiveMQBrokerPassword - ConsoleAccess: true - Groups: - - admin - SubnetIds: - - !Ref PrivateSubnetActiveMQOne - - !Ref PrivateSubnetActiveMQTwo - SecurityGroups: - - !Ref ActiveMQSecurityGroup - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-activemq-broker" - - ActiveMQClientEC2Instance: - DependsOn: ActiveMQBroker - Type: AWS::EC2::Instance - Properties: - InstanceType: m5.large - IamInstanceProfile: !Ref EC2InstanceProfile - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - SubnetId: !Ref PublicSubnetOne - SecurityGroupIds: [!GetAtt ActiveMQClientInstanceSecurityGroup.GroupId] - ImageId: !Ref LatestAmiId - Tags: - - Key: 'Name' - Value: 'ActiveMQClientInstance' - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: 50 - VolumeType: gp2 - DeleteOnTermination: true - UserData: - Fn::Base64: - !Sub - - | - #!/bin/bash - yum update -y - - # install Java - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum update -y - - # install Java - JAVA_VERSION=${java_version} - echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile - if [ "$JAVA_VERSION" == "java11" ]; then - sudo yum install java-11-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java17" ]; then - sudo yum install java-17-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java21" ]; then - sudo yum install java-21-amazon-corretto-devel -y - else - sudo yum install java-21-amazon-corretto-devel -y - fi - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of Java succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install nmap-ncat -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of nmap succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install git -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of git succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum erase awscli -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum erase of awscli succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install jq -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of jq succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y docker - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of docker succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - service docker start - usermod -a -G docker ec2-user - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y maven - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of maven succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - cd /home/ec2-user - su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user - su -c "pip3 install boto3 --user" -s /bin/sh ec2-user - su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user - - # install AWS CLI 2 - access with aws2 - cd /home/ec2-user - mkdir -p awscli - cd awscli - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install - - # Install AWS SAM CLI - cd /home/ec2-user - mkdir -p awssam - cd awssam - wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip - unzip aws-sam-cli-linux-x86_64.zip -d sam-installation - sudo ./sam-installation/install - - # Set environment variables - ACTIVEMQ_BROKER_ID=${activemq_broker_id} - ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} - ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" - #ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} - #ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} - ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} - ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} - AWS_REGION=${aws_region} - ACTIVEMQ_SUBNET_ONE=${activemq_subnet_one} - ACTIVEMQ_SUBNET_TWO=${activemq_subnet_two} - ACTIVEMQ_SUBNET_THREE=${activemq_subnet_three} - ACTIVEMQ_SECURITY_GROUP=${activemq_security_group} - ACTIVEMQ_BROKER_ADMIN_USER=${activemq_broker_admin_user} - ACTIVEMQ_BROKER_PASSWORD=${activemq_broker_password} - SECURITY_GROUP=${security_group_id} - - echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - #echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile - #echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile - echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_ONE=$ACTIVEMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_TWO=$ACTIVEMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_THREE=$ACTIVEMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SECURITY_GROUP=$ACTIVEMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ADMIN_USER=$ACTIVEMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_PASSWORD=$ACTIVEMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - - # Clone serverless patterns - cd /home/ec2-user - SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} - git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION - cd ./serverless-patterns - git sparse-checkout set --no-cone /activemq-private-lambda-java-sam - git checkout - cd activemq-private-lambda-java-sam - sudo chown -R ec2-user . - - #Substitute SAM template variables - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam - cd activemq_consumer_dynamo_sam - cp template_original.yaml template.yaml - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/ACTIVEMQ_BROKER_ARN/$ACTIVEMQ_BROKER_ARN/g" template.yaml - sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" template.yaml - sed -i "s/ACTIVEMQ_SECRET_ARN/$ACTIVEMQ_SECRET_ARN/g" template.yaml - sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_ONE/$ACTIVEMQ_SUBNET_ONE/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_TWO/$ACTIVEMQ_SUBNET_TWO/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_THREE/$ACTIVEMQ_SUBNET_THREE/g" template.yaml - sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml - - #Install ActiveMQ (needed in case you want to use the CLI as a client to look at queues etc.) - mkdir /home/ec2-user/activemq_client - cd /home/ec2-user/activemq_client - wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz - tar zxvf apache-activemq-5.18.6-bin.tar.gz - sudo chown -R ec2-user . - - - - #Update Shell script for sending ActiveMQ messages to Lambda function - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json - sudo chown ec2-user ./commands.sh - source /home/ec2-user/.bash_profile - echo "ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|\"${ACTIVEMQ_BROKER_ENDPOINT}\"|g" commands.sh - sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh - mvn clean install - - - #Update Shell script for browsing messages in ActiveMQ queue - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam - sudo chown ec2-user ./activemq_queue_browser.sh - source /home/ec2-user/.bash_profile - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh - - - # Get IP CIDR range for EC2 Instance Connect - cd /home/ec2-user - mkdir -p ip_prefix - cd ip_prefix - git clone https://github.com/joetek/aws-ip-ranges-json.git - cd aws-ip-ranges-json - AWS_REGION=${aws_region} - EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') - echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile - SECURITY_GROUP=${security_group_id} - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP - - - activemq_broker_id: !Ref ActiveMQBroker - activemq_broker_arn: !GetAtt ActiveMQBroker.Arn - activemq_broker_endpoint1: !Select [ 0, !GetAtt ActiveMQBroker.OpenWireEndpoints ] - activemq_broker_endpoint2: !Select [ 1, !GetAtt ActiveMQBroker.OpenWireEndpoints ] - activemq_queue_name: !Ref ActiveMQQueueName - activemq_secret_arn: !Ref ActiveMQSecret - serverless_land_github_location: !Ref ServerlessLandGithubLocation - aws_region: !Ref 'AWS::Region' - java_version: !Ref JavaVersion - security_group_id : !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - activemq_subnet_one: !Ref PrivateSubnetActiveMQOne - activemq_subnet_two: !Ref PrivateSubnetActiveMQTwo - activemq_subnet_three: !Ref PrivateSubnetActiveMQThree - activemq_security_group: !GetAtt ActiveMQSecurityGroup.GroupId - activemq_broker_admin_user: !Ref ActiveMQBrokerAdminUser - activemq_broker_password: !Ref ActiveMQBrokerPassword - - EC2InstanceEndpoint: - Type: AWS::EC2::InstanceConnectEndpoint - Properties: - PreserveClientIp: true - SecurityGroupIds: - - !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - SubnetId: !Ref PublicSubnetOne - - EC2Role: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: '' - Effect: Allow - Principal: - Service: ec2.amazonaws.com - Action: 'sts:AssumeRole' - Path: "/" - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonMQFullAccess - - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - - arn:aws:iam::aws:policy/CloudWatchFullAccess - - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - - arn:aws:iam::aws:policy/AmazonS3FullAccess - - arn:aws:iam::aws:policy/IAMFullAccess - - arn:aws:iam::aws:policy/AWSLambda_FullAccess - - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 - Policies: - - PolicyName: ActiveMQAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ActiveMQFullAccess", - "Effect": "Allow", - "Action": [ - "mq:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecretsManagerAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:PutSecretValue", - "secretsmanager:DescribeSecret" - ], - "Resource": "${ActiveMQSecret}" - } - ] - }' - - PolicyName: CloudformationDeploy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "iam:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecurityGroupsPolicy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeSecurityGroups", - "ec2:DescribeSecurityGroupRules", - "ec2:DescribeTags" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:RevokeSecurityGroupIngress", - "ec2:AuthorizeSecurityGroupEgress", - "ec2:RevokeSecurityGroupEgress", - "ec2:ModifySecurityGroupRules", - "ec2:UpdateSecurityGroupRuleDescriptionsIngress", - "ec2:UpdateSecurityGroupRuleDescriptionsEgress" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "ec2:ModifySecurityGroupRules" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" - ] - } - ] - }' - - EC2InstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - InstanceProfileName: !Join - - '-' - - - 'EC2ActiveMQProfile' - - !Ref 'AWS::StackName' - Roles: - - !Ref EC2Role - -Outputs: - VPCId: - Description: The ID of the VPC created - Value: !Ref 'VPC' - Export: - Name: !Sub "${AWS::StackName}-VPCID" - PublicSubnetOne: - Description: The name of the public subnet created - Value: !Ref 'PublicSubnetOne' - Export: - Name: !Sub "${AWS::StackName}-PublicSubnetOne" - PrivateSubnetActiveMQOne: - Description: The ID of private subnet one created - Value: !Ref 'PrivateSubnetActiveMQOne' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQOne" - PrivateSubnetActiveMQTwo: - Description: The ID of private subnet two created - Value: !Ref 'PrivateSubnetActiveMQTwo' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQTwo" - PrivateSubnetActiveMQThree: - Description: The ID of private subnet three created - Value: !Ref 'PrivateSubnetActiveMQThree' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQThree" - VPCStackName: - Description: The name of the VPC Stack - Value: !Ref 'AWS::StackName' - Export: - Name: !Sub "${AWS::StackName}-VPCStackName" - ActiveMQBrokerEndpoint1: - Description: ActiveMQ Broker OpenWire Endpoint - Value: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint1" - ActiveMQBrokerEndpoint2: - Description: ActiveMQ Broker OpenWire Endpoint - Value: !Select [1, !GetAtt ActiveMQBroker.OpenWireEndpoints] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint2" - ActiveMQBrokerConsoleURL: - Description: ActiveMQ Broker Web Console URL - Value: !Sub - - "https://${endpoint}" - - endpoint: !Select [0, !GetAtt ActiveMQBroker.IpAddresses] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerConsoleURL" - ActiveMQSecretArn: - Description: ARN of the ActiveMQ credentials secret - Value: !Ref ActiveMQSecret - Export: - Name: !Sub "${AWS::StackName}-ActiveMQSecretArn" - SecurityGroupId: - Description: ID of security group for ActiveMQ clients - Value: !GetAtt ActiveMQSecurityGroup.GroupId - Export: - Name: !Sub "${AWS::StackName}-SecurityGroupId" - EC2InstanceEndpointID: - Description: The ID of the EC2 Instance Endpoint - Value: !Ref EC2InstanceEndpoint - ActiveMQBrokerName: - Description: The Broker name to use for the Java Lambda Function - Value: !Ref ActiveMQBrokerName - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerName" - ActiveMQQueueName: - Description: The Queue name to use for the Java Lambda Function - Value: !Ref ActiveMQQueueName - Export: - Name: !Sub "${AWS::StackName}-ActiveMQQueueName" From 2f7e2e92b3f27579fe32f91aa4e1647f9c810006 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sat, 18 Oct 2025 14:37:26 -0700 Subject: [PATCH 07/18] Fixed ActiveMQ Private Lambda Java SAM Project --- .../ActiveMQAndClientEC2.yaml | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index 4b46afda0..9d987123e 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -40,19 +40,19 @@ Parameters: Mappings: SubnetConfig: VPC: - CIDR: '10.0.0.0/16' + CIDR: '10.1.0.0/16' PublicOne: - CIDR: '10.0.0.0/24' + CIDR: '10.1.0.0/24' PublicTwo: - CIDR: '10.0.1.0/24' + CIDR: '10.1.1.0/24' PublicThree: - CIDR: '10.0.2.0/24' + CIDR: '10.1.2.0/24' PrivateSubnetActiveMQOne: - CIDR: '10.0.3.0/24' + CIDR: '10.1.3.0/24' PrivateSubnetActiveMQTwo: - CIDR: '10.0.4.0/24' + CIDR: '10.1.4.0/24' PrivateSubnetActiveMQThree: - CIDR: '10.0.5.0/24' + CIDR: '10.1.5.0/24' Resources: # Secrets Manager Secret for ActiveMQ credentials @@ -568,9 +568,7 @@ Resources: # Set environment variables ACTIVEMQ_BROKER_ID=${activemq_broker_id} ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} - ACTIVEMQ_BROKER_ENDPOINT_ONE=${activemq_broker_endpoint1} - ACTIVEMQ_BROKER_ENDPOINT_TWO=${activemq_broker_endpoint2} - ACTIVEMQ_BROKER_ENDPOINT="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" + activemq_broker_endpoint="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} @@ -584,9 +582,7 @@ Resources: echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT_ONE=$ACTIVEMQ_BROKER_ENDPOINT_ONE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT_TWO=$ACTIVEMQ_BROKER_ENDPOINT_TWO" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile @@ -629,30 +625,26 @@ Resources: wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz tar zxvf apache-activemq-5.18.6-bin.tar.gz sudo chown -R ec2-user . - - - + #Update Shell script for sending ActiveMQ messages to Lambda function cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json sudo chown ec2-user ./commands.sh source /home/ec2-user/.bash_profile - echo "ACTIVEMQ_BROKER_ENDPOINT=$ACTIVEMQ_BROKER_ENDPOINT" - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|\"${ACTIVEMQ_BROKER_ENDPOINT}\"|g" commands.sh + echo "ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|$activemq_broker_endpoint|g" commands.sh sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh mvn clean install - #Update Shell script for browsing messages in ActiveMQ queue cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam sudo chown ec2-user ./activemq_queue_browser.sh source /home/ec2-user/.bash_profile - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|$ACTIVEMQ_BROKER_ENDPOINT_ONE|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|$ACTIVEMQ_BROKER_ENDPOINT_TWO|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh - - + # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user mkdir -p ip_prefix From 275c1ac62a82b87a05ef3fcbd324b332d5c762b9 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sun, 19 Oct 2025 22:33:11 -0700 Subject: [PATCH 08/18] Fixed ActiveMQ Private Lambda Java SAM Project --- .../ActiveMQAndClientEC2.yaml | 2 +- activemq-private-lambda-java-sam/README.md | 172 ++++++++++++++++-- .../template_original.yaml | 4 +- .../activemq_queue_browser.sh | 2 +- 4 files changed, 162 insertions(+), 18 deletions(-) diff --git a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index 9d987123e..542c09a9a 100644 --- a/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ b/activemq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -328,7 +328,7 @@ Resources: - IpProtocol: tcp FromPort: 0 ToPort: 65535 - CidrIp: 10.0.0.0/16 + CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] ActiveMQClientSelfIngressAllowRule: Type: AWS::EC2::SecurityGroupIngress diff --git a/activemq-private-lambda-java-sam/README.md b/activemq-private-lambda-java-sam/README.md index 30114baba..55f2b791a 100755 --- a/activemq-private-lambda-java-sam/README.md +++ b/activemq-private-lambda-java-sam/README.md @@ -1,26 +1,170 @@ -# javaActiveMQLambdaDynamoDB -Java samples for ActiveMQ --> Lambda --> DynamoDB +# activemq-private-lambda-java-sam +# Java AWS Lambda DocumentDB Streams consumer, using AWS SAM -This repository has code samples for implementing a Lambda function in Java that listens on an Amazon ActiveMQ queue as its event source and upon receipt of messages from the Amazon ActiveMQ queue, the code in the lambda function parses the contents of the message (both metadata as well as payload data) and outputs the contents into an Amazon DynamoDB table +This pattern is an example of a Lambda function written in Java that consumes messages from Amazon MQ (Apache ActiveMQ) -Each example has two Java Maven projects - a Sender Project and a Lambda Receiver Project +This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. -The sender project has instructions on how to generate messages on the Amazon ActiveMQ queue such that those messages can then be received by the corresponding lambda receiver +- activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java - Code for the application's Lambda function that will listen for Amazon MQ (Apache ActiveMQ) messages and write them to a DynamoDB table +- activemq_message_sender_json/src/main/java - Code for publishing messages with JSON payload into an Amazon MQ (ActiveMQ cluster), that will in turn be consumed by the Lambda function +- activemq_consumer_dynamo_sam/template_original.yaml - A template that defines the application's Lambda function to be used by SAM to deploy the lambda function +- ActiveMQAndClientEC2.yaml - A Cloudformation template file that can be used to deploy an Amazon MQ (Apache ActiveMQ) cluster and also deploy an EC2 machine with all pre-requisities already installed, so you can directly build and deploy the lambda function and test it out. +- activemq_queue_browser.sh - A shell script that can be used to connect to the Amazon MQ (Apache ActiveMQ) brokers using the activemq command-line tool -Currently, the following samples exist in this repository +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. -1) JSONMessage - In this example, the sender program generates Amazon ActiveMQ messages with a JSON payload +## Requirements -More examples will be added in the future +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. -In order to run these examples, create the following in an AWS account +## Run the Cloudformation template to create the Amazon MQ (Apache ActiveMQ) Cluster and Client EC2 machine -1) A VPC with 3 public and 3 private subnets and an internet gateway and 3 NAT gateways for each of the three private subnets - For an example of a Cloudformation template to create a VPC, refer to this document - https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html +* [Run the Cloudformation template using the file ActiveMQAndClientEC2.yaml] - You can go to the AWS Cloudformation console, create a new stack by specifying the template file. You can keep the defaults for input parameters or modify them as necessary. Wait for the Cloudformation stack to be created. This Cloudformation template will create an Amazon MQ (Apache ActiveMQ) cluster. It will also create an EC2 machine that you can use as a client. -2) Create an AWS Cloud9 environment and use one of the public subnets created in the VPC above for creating the Cloud9 environment - For an example of a Cloudformation template to create a Cloud9 environment, refer to the document - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloud9-environmentec2.html +* [Connect to the EC2 machine] - Once the CloudFormation stack is created, you can go to the EC2 console and log into the machine using either "Connect using EC2 Instance Connect" or "Connect using EC2 Instance Connect Endpoint" option under the "EC2 Instance Connect" tab. +Note: You may need to wait for some time after the CloudFormation stack is created, as some UserData scripts continue running after the Cloudformation stack shows Created. -3) Create a Security Group and assign it to the EC2 instance of the Cloud9 environment +## Pre-requisites to Deploy the sample Lambda function -4) Create an IAM role and attach it to the EC2 instance of the Cloud9 environment +The EC2 machine that was created by running the CloudFormation template has all the software that will be needed to deploy the Lambda function. -5) Under each sample, refer to the README files inside the sender and the receiver folders - For example under the JSONMessage folder, refer to the README files inside the sub-folders activemq_message_sender_json (sender) and activemq_consumer_dynamo_sam (receiver) for instructions \ No newline at end of file +The AWS SAM CLI is a serverless tool for building and testing Lambda applications. + +* Java - On the EC2 machine, we have installed the version of Java that you selected. We have installed Amazon Corrretto JDK of the version that you had selected at the time of specifying the input parameters in the Cloudformation template. At the time of publishing this pattern, only Java versions 11, 17 and 21 are supported by AWS SAM +* Maven - On the EC2 machine, we have installed Maven (https://maven.apache.org/install.html) +* AWS SAM CLI - We have installed the AWS SAM CLI (https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) + +We have also cloned the Github repository for serverless-patterns on the EC2 machine already by running the below command + ``` + git clone https://github.com/aws-samples/serverless-patterns.git + ``` +Change directory to the pattern directory: + ``` + cd serverless-patterns/activemq-private-lambda-java-sam + ``` + +## Use the SAM CLI to build and deploy the lambda function + +Build your application with the `sam build` command. + +```bash +cd activemq_consumer_dynamo_sam +sam build +``` + +The SAM CLI installs dependencies defined in `documentdb_streams_consumer_dynamo_sam/documentdb_streams_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. + +``` + +## Test the build locally + +Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. + +Run functions locally and invoke them with the `sam local invoke` command. + +```bash +sam local invoke --event events/event.json +``` + +You should see a response such as the below: + +``` +***** Begin sam local invoke response ***** + +Begin Event *************{"eventSource":"aws:mq","eventSourceArn":"arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0","messages":[{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:1","messageType":"jms/text-message","timestamp":1687328148384,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-1","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9","brokerInTime":1687328148385,"brokerOutTime":1687328148385},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:38","messageType":"jms/text-message","timestamp":1687328148471,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-38","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJWYWxlbnRpbmUiLCJsYXN0bmFtZSI6IkdpbGxpYW4iLCJjb21wYW55IjoiRmJzIEJ1c2luZXNzIEZpbmFuY2UiLCJzdHJlZXQiOiI3NzUgVyAxN3RoIFN0IiwiY2l0eSI6IlNhbiBBbnRvbmlvIiwiY291bnR5IjoiQmV4YXIiLCJzdGF0ZSI6IlRYIiwiemlwIjoiNzgyMDQiLCJob21lUGhvbmUiOiIyMTAtODEyLTk1OTciLCJjZWxsUGhvbmUiOiIyMTAtMzAwLTYyNDQiLCJlbWFpbCI6InZhbGVudGluZV9naWxsaWFuQGdtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmZic2J1c2luZXNzZmluYW5jZS5jb20ifQ==","brokerInTime":1687328148472,"brokerOutTime":1687328148495},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:48","messageType":"jms/text-message","timestamp":1687328148491,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-48","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJFbWVyc29uIiwibGFzdG5hbWUiOiJCb3dsZXkiLCJjb21wYW55IjoiS25pZ2h0cyBJbm4iLCJzdHJlZXQiOiI3NjIgUyBNYWluIFN0IiwiY2l0eSI6Ik1hZGlzb24iLCJjb3VudHkiOiJEYW5lIiwic3RhdGUiOiJXSSIsInppcCI6IjUzNzExIiwiaG9tZVBob25lIjoiNjA4LTMzNi03NDQ0IiwiY2VsbFBob25lIjoiNjA4LTY1OC03OTQwIiwiZW1haWwiOiJlbWVyc29uLmJvd2xleUBib3dsZXkub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cua25pZ2h0c2lubi5jb20ifQ==","brokerInTime":1687328148492,"brokerOutTime":1687328148534},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:53","messageType":"jms/text-message","timestamp":1687328148498,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-53","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJNYXJqb3J5IiwibGFzdG5hbWUiOiJNYXN0ZWxsYSIsImNvbXBhbnkiOiJWaWNvbiBDb3Jwb3JhdGlvbiIsInN0cmVldCI6IjcxIFNhbiBNYXRlbyBBdmUiLCJjaXR5IjoiV2F5bmUiLCJjb3VudHkiOiJEZWxhd2FyZSIsInN0YXRlIjoiUEEiLCJ6aXAiOiIxOTA4NyIsImhvbWVQaG9uZSI6IjYxMC04MTQtNTUzMyIsImNlbGxQaG9uZSI6IjYxMC0zNzktNzEyNSIsImVtYWlsIjoibW1hc3RlbGxhQG1hc3RlbGxhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnZpY29uY29ycG9yYXRpb24uY29tIn0=","brokerInTime":1687328148503,"brokerOutTime":1687328148538},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:58","messageType":"jms/text-message","timestamp":1687328148514,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-58","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJEZWxteSIsImxhc3RuYW1lIjoiQWhsZSIsImNvbXBhbnkiOiJXeWUgVGVjaG5vbG9naWVzIEluYyIsInN0cmVldCI6IjY1ODk1IFMgMTZ0aCBTdCIsImNpdHkiOiJQcm92aWRlbmNlIiwiY291bnR5IjoiUHJvdmlkZW5jZSIsInN0YXRlIjoiUkkiLCJ6aXAiOiIyOTA5IiwiaG9tZVBob25lIjoiNDAxLTQ1OC0yNTQ3IiwiY2VsbFBob25lIjoiNDAxLTU1OS04OTYxIiwiZW1haWwiOiJkZWxteS5haGxlQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cud3lldGVjaG5vbG9naWVzaW5jLmNvbSJ9","brokerInTime":1687328148514,"brokerOutTime":1687328148552},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:63","messageType":"jms/text-message","timestamp":1687328148520,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-63","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJDYXJtZWxpbmEiLCJsYXN0bmFtZSI6IkxpbmRhbGwiLCJjb21wYW55IjoiR2VvcmdlIEplc3NvcCBDYXJ0ZXIgSmV3ZWxlcnMiLCJzdHJlZXQiOiIyNjY0IExld2lzIFJkIiwiY2l0eSI6IkxpdHRsZXRvbiIsImNvdW50eSI6IkRvdWdsYXMiLCJzdGF0ZSI6IkNPIiwiemlwIjoiODAxMjYiLCJob21lUGhvbmUiOiIzMDMtNzI0LTczNzEiLCJjZWxsUGhvbmUiOiIzMDMtODc0LTUxNjAiLCJlbWFpbCI6ImNhcm1lbGluYV9saW5kYWxsQGxpbmRhbGwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZ2VvcmdlamVzc29wY2FydGVyamV3ZWxlcnMuY29tIn0=","brokerInTime":1687328148520,"brokerOutTime":1687328148556},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:68","messageType":"jms/text-message","timestamp":1687328148526,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-68","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJJbGVuZSIsImxhc3RuYW1lIjoiRXJvbWFuIiwiY29tcGFueSI6IlwiUm9iaW5zb24sIFdpbGxpYW0gSiBFc3FcIiIsInN0cmVldCI6IjI4NTMgUyBDZW50cmFsIEV4cHkiLCJjaXR5IjoiR2xlbiBCdXJuaWUiLCJjb3VudHkiOiJBbm5lIEFydW5kZWwiLCJzdGF0ZSI6Ik1EIiwiemlwIjoiMjEwNjEiLCJob21lUGhvbmUiOiI0MTAtOTE0LTkwMTgiLCJjZWxsUGhvbmUiOiI0MTAtOTM3LTQ1NDMiLCJlbWFpbCI6ImlsZW5lLmVyb21hbkBob3RtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnJvYmluc29ud2lsbGlhbWplc3EuY29tIn0=","brokerInTime":1687328148527,"brokerOutTime":1687328148559},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:75","messageType":"jms/text-message","timestamp":1687328148534,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-75","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJNb29uIiwibGFzdG5hbWUiOiJQYXJsYXRvIiwiY29tcGFueSI6IlwiQW1iZWxhbmcsIEplc3NpY2EgTSBNZFwiIiwic3RyZWV0IjoiNzQ5ODkgQnJhbmRvbiBTdCIsImNpdHkiOiJXZWxsc3ZpbGxlIiwiY291bnR5IjoiQWxsZWdhbnkiLCJzdGF0ZSI6Ik5ZIiwiemlwIjoiMTQ4OTUiLCJob21lUGhvbmUiOiI1ODUtODY2LTgzMTMiLCJjZWxsUGhvbmUiOiI1ODUtNDk4LTQyNzgiLCJlbWFpbCI6Im1vb25AeWFob28uY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuYW1iZWxhbmdqZXNzaWNhbW1kLmNvbSJ9","brokerInTime":1687328148534,"brokerOutTime":1687328148574},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:78","messageType":"jms/text-message","timestamp":1687328148537,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-78","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJWaXZhIiwibGFzdG5hbWUiOiJUb2Vsa2VzIiwiY29tcGFueSI6Ik1hcmsgSXYgUHJlc3MgTHRkIiwic3RyZWV0IjoiNDI4NCBEb3JpZ28gTG4iLCJjaXR5IjoiQ2hpY2FnbyIsImNvdW50eSI6IkNvb2siLCJzdGF0ZSI6IklMIiwiemlwIjoiNjA2NDciLCJob21lUGhvbmUiOiI3NzMtNDQ2LTU1NjkiLCJjZWxsUGhvbmUiOiI3NzMtMzUyLTM0MzciLCJlbWFpbCI6InZpdmEudG9lbGtlc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tYXJraXZwcmVzc2x0ZC5jb20ifQ==","brokerInTime":1687328148538,"brokerOutTime":1687328148576},{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:81","messageType":"jms/text-message","timestamp":1687328148540,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-81","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJUaW1vdGh5IiwibGFzdG5hbWUiOiJNdWxxdWVlbiIsImNvbXBhbnkiOiJTYXJvbml4IE55bXBoIFByb2R1Y3RzIiwic3RyZWV0IjoiNDQgVyA0dGggU3QiLCJjaXR5IjoiU3RhdGVuIElzbGFuZCIsImNvdW50eSI6IlJpY2htb25kIiwic3RhdGUiOiJOWSIsInppcCI6IjEwMzA5IiwiaG9tZVBob25lIjoiNzE4LTMzMi02NTI3IiwiY2VsbFBob25lIjoiNzE4LTY1NC03MDYzIiwiZW1haWwiOiJ0aW1vdGh5X211bHF1ZWVuQG11bHF1ZWVuLm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnNhcm9uaXhueW1waHByb2R1Y3RzLmNvbSJ9","brokerInTime":1687328148541,"brokerOutTime":1687328148578}]}End Event ***************Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:1","messageType":"jms/text-message","timestamp":1687328148384,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-1","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9","brokerInTime":1687328148385,"brokerOutTime":1687328148385}End Message ***************Begin Message Body *************{"firstname":"Josephine","lastname":"Darakjy","company":"\"Chanay, Jeffrey A Esq\"","street":"4 B Blue Ridge Blvd","city":"Brighton","county":"Livingston","state":"MI","zip":"48116","homePhone":"810-292-9388","cellPhone":"810-374-9840","email":"josephine_darakjy@darakjy.org","website":"http://www.chanayjeffreyaesq.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-1MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:1MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148385BrokerOutTime = 1687328148385DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148384Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Josephine","lastname":"Darakjy","company":"\"Chanay, Jeffrey A Esq\"","street":"4 B Blue Ridge Blvd","city":"Brighton","county":"Livingston","state":"MI","zip":"48116","homePhone":"810-292-9388","cellPhone":"810-374-9840","email":"josephine_darakjy@darakjy.org","website":"http://www.chanayjeffreyaesq.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:38","messageType":"jms/text-message","timestamp":1687328148471,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-38","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJWYWxlbnRpbmUiLCJsYXN0bmFtZSI6IkdpbGxpYW4iLCJjb21wYW55IjoiRmJzIEJ1c2luZXNzIEZpbmFuY2UiLCJzdHJlZXQiOiI3NzUgVyAxN3RoIFN0IiwiY2l0eSI6IlNhbiBBbnRvbmlvIiwiY291bnR5IjoiQmV4YXIiLCJzdGF0ZSI6IlRYIiwiemlwIjoiNzgyMDQiLCJob21lUGhvbmUiOiIyMTAtODEyLTk1OTciLCJjZWxsUGhvbmUiOiIyMTAtMzAwLTYyNDQiLCJlbWFpbCI6InZhbGVudGluZV9naWxsaWFuQGdtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmZic2J1c2luZXNzZmluYW5jZS5jb20ifQ==","brokerInTime":1687328148472,"brokerOutTime":1687328148495}End Message ***************Begin Message Body *************{"firstname":"Valentine","lastname":"Gillian","company":"Fbs Business Finance","street":"775 W 17th St","city":"San Antonio","county":"Bexar","state":"TX","zip":"78204","homePhone":"210-812-9597","cellPhone":"210-300-6244","email":"valentine_gillian@gmail.com","website":"http://www.fbsbusinessfinance.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-38MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:38MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148472BrokerOutTime = 1687328148495DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148471Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Valentine","lastname":"Gillian","company":"Fbs Business Finance","street":"775 W 17th St","city":"San Antonio","county":"Bexar","state":"TX","zip":"78204","homePhone":"210-812-9597","cellPhone":"210-300-6244","email":"valentine_gillian@gmail.com","website":"http://www.fbsbusinessfinance.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:48","messageType":"jms/text-message","timestamp":1687328148491,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-48","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJFbWVyc29uIiwibGFzdG5hbWUiOiJCb3dsZXkiLCJjb21wYW55IjoiS25pZ2h0cyBJbm4iLCJzdHJlZXQiOiI3NjIgUyBNYWluIFN0IiwiY2l0eSI6Ik1hZGlzb24iLCJjb3VudHkiOiJEYW5lIiwic3RhdGUiOiJXSSIsInppcCI6IjUzNzExIiwiaG9tZVBob25lIjoiNjA4LTMzNi03NDQ0IiwiY2VsbFBob25lIjoiNjA4LTY1OC03OTQwIiwiZW1haWwiOiJlbWVyc29uLmJvd2xleUBib3dsZXkub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cua25pZ2h0c2lubi5jb20ifQ==","brokerInTime":1687328148492,"brokerOutTime":1687328148534}End Message ***************Begin Message Body *************{"firstname":"Emerson","lastname":"Bowley","company":"Knights Inn","street":"762 S Main St","city":"Madison","county":"Dane","state":"WI","zip":"53711","homePhone":"608-336-7444","cellPhone":"608-658-7940","email":"emerson.bowley@bowley.org","website":"http://www.knightsinn.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-48MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:48MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148492BrokerOutTime = 1687328148534DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148491Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Emerson","lastname":"Bowley","company":"Knights Inn","street":"762 S Main St","city":"Madison","county":"Dane","state":"WI","zip":"53711","homePhone":"608-336-7444","cellPhone":"608-658-7940","email":"emerson.bowley@bowley.org","website":"http://www.knightsinn.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:53","messageType":"jms/text-message","timestamp":1687328148498,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-53","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJNYXJqb3J5IiwibGFzdG5hbWUiOiJNYXN0ZWxsYSIsImNvbXBhbnkiOiJWaWNvbiBDb3Jwb3JhdGlvbiIsInN0cmVldCI6IjcxIFNhbiBNYXRlbyBBdmUiLCJjaXR5IjoiV2F5bmUiLCJjb3VudHkiOiJEZWxhd2FyZSIsInN0YXRlIjoiUEEiLCJ6aXAiOiIxOTA4NyIsImhvbWVQaG9uZSI6IjYxMC04MTQtNTUzMyIsImNlbGxQaG9uZSI6IjYxMC0zNzktNzEyNSIsImVtYWlsIjoibW1hc3RlbGxhQG1hc3RlbGxhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnZpY29uY29ycG9yYXRpb24uY29tIn0=","brokerInTime":1687328148503,"brokerOutTime":1687328148538}End Message ***************Begin Message Body *************{"firstname":"Marjory","lastname":"Mastella","company":"Vicon Corporation","street":"71 San Mateo Ave","city":"Wayne","county":"Delaware","state":"PA","zip":"19087","homePhone":"610-814-5533","cellPhone":"610-379-7125","email":"mmastella@mastella.com","website":"http://www.viconcorporation.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-53MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:53MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148503BrokerOutTime = 1687328148538DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148498Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Marjory","lastname":"Mastella","company":"Vicon Corporation","street":"71 San Mateo Ave","city":"Wayne","county":"Delaware","state":"PA","zip":"19087","homePhone":"610-814-5533","cellPhone":"610-379-7125","email":"mmastella@mastella.com","website":"http://www.viconcorporation.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:58","messageType":"jms/text-message","timestamp":1687328148514,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-58","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJEZWxteSIsImxhc3RuYW1lIjoiQWhsZSIsImNvbXBhbnkiOiJXeWUgVGVjaG5vbG9naWVzIEluYyIsInN0cmVldCI6IjY1ODk1IFMgMTZ0aCBTdCIsImNpdHkiOiJQcm92aWRlbmNlIiwiY291bnR5IjoiUHJvdmlkZW5jZSIsInN0YXRlIjoiUkkiLCJ6aXAiOiIyOTA5IiwiaG9tZVBob25lIjoiNDAxLTQ1OC0yNTQ3IiwiY2VsbFBob25lIjoiNDAxLTU1OS04OTYxIiwiZW1haWwiOiJkZWxteS5haGxlQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cud3lldGVjaG5vbG9naWVzaW5jLmNvbSJ9","brokerInTime":1687328148514,"brokerOutTime":1687328148552}End Message ***************Begin Message Body *************{"firstname":"Delmy","lastname":"Ahle","company":"Wye Technologies Inc","street":"65895 S 16th St","city":"Providence","county":"Providence","state":"RI","zip":"2909","homePhone":"401-458-2547","cellPhone":"401-559-8961","email":"delmy.ahle@hotmail.com","website":"http://www.wyetechnologiesinc.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-58MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:58MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148514BrokerOutTime = 1687328148552DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148514Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Delmy","lastname":"Ahle","company":"Wye Technologies Inc","street":"65895 S 16th St","city":"Providence","county":"Providence","state":"RI","zip":"2909","homePhone":"401-458-2547","cellPhone":"401-559-8961","email":"delmy.ahle@hotmail.com","website":"http://www.wyetechnologiesinc.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:63","messageType":"jms/text-message","timestamp":1687328148520,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-63","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJDYXJtZWxpbmEiLCJsYXN0bmFtZSI6IkxpbmRhbGwiLCJjb21wYW55IjoiR2VvcmdlIEplc3NvcCBDYXJ0ZXIgSmV3ZWxlcnMiLCJzdHJlZXQiOiIyNjY0IExld2lzIFJkIiwiY2l0eSI6IkxpdHRsZXRvbiIsImNvdW50eSI6IkRvdWdsYXMiLCJzdGF0ZSI6IkNPIiwiemlwIjoiODAxMjYiLCJob21lUGhvbmUiOiIzMDMtNzI0LTczNzEiLCJjZWxsUGhvbmUiOiIzMDMtODc0LTUxNjAiLCJlbWFpbCI6ImNhcm1lbGluYV9saW5kYWxsQGxpbmRhbGwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZ2VvcmdlamVzc29wY2FydGVyamV3ZWxlcnMuY29tIn0=","brokerInTime":1687328148520,"brokerOutTime":1687328148556}End Message ***************Begin Message Body *************{"firstname":"Carmelina","lastname":"Lindall","company":"George Jessop Carter Jewelers","street":"2664 Lewis Rd","city":"Littleton","county":"Douglas","state":"CO","zip":"80126","homePhone":"303-724-7371","cellPhone":"303-874-5160","email":"carmelina_lindall@lindall.com","website":"http://www.georgejessopcarterjewelers.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-63MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:63MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148520BrokerOutTime = 1687328148556DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148520Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Carmelina","lastname":"Lindall","company":"George Jessop Carter Jewelers","street":"2664 Lewis Rd","city":"Littleton","county":"Douglas","state":"CO","zip":"80126","homePhone":"303-724-7371","cellPhone":"303-874-5160","email":"carmelina_lindall@lindall.com","website":"http://www.georgejessopcarterjewelers.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:68","messageType":"jms/text-message","timestamp":1687328148526,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-68","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJJbGVuZSIsImxhc3RuYW1lIjoiRXJvbWFuIiwiY29tcGFueSI6IlwiUm9iaW5zb24sIFdpbGxpYW0gSiBFc3FcIiIsInN0cmVldCI6IjI4NTMgUyBDZW50cmFsIEV4cHkiLCJjaXR5IjoiR2xlbiBCdXJuaWUiLCJjb3VudHkiOiJBbm5lIEFydW5kZWwiLCJzdGF0ZSI6Ik1EIiwiemlwIjoiMjEwNjEiLCJob21lUGhvbmUiOiI0MTAtOTE0LTkwMTgiLCJjZWxsUGhvbmUiOiI0MTAtOTM3LTQ1NDMiLCJlbWFpbCI6ImlsZW5lLmVyb21hbkBob3RtYWlsLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnJvYmluc29ud2lsbGlhbWplc3EuY29tIn0=","brokerInTime":1687328148527,"brokerOutTime":1687328148559}End Message ***************Begin Message Body *************{"firstname":"Ilene","lastname":"Eroman","company":"\"Robinson, William J Esq\"","street":"2853 S Central Expy","city":"Glen Burnie","county":"Anne Arundel","state":"MD","zip":"21061","homePhone":"410-914-9018","cellPhone":"410-937-4543","email":"ilene.eroman@hotmail.com","website":"http://www.robinsonwilliamjesq.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-68MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:68MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148527BrokerOutTime = 1687328148559DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148526Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Ilene","lastname":"Eroman","company":"\"Robinson, William J Esq\"","street":"2853 S Central Expy","city":"Glen Burnie","county":"Anne Arundel","state":"MD","zip":"21061","homePhone":"410-914-9018","cellPhone":"410-937-4543","email":"ilene.eroman@hotmail.com","website":"http://www.robinsonwilliamjesq.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:75","messageType":"jms/text-message","timestamp":1687328148534,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-75","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJNb29uIiwibGFzdG5hbWUiOiJQYXJsYXRvIiwiY29tcGFueSI6IlwiQW1iZWxhbmcsIEplc3NpY2EgTSBNZFwiIiwic3RyZWV0IjoiNzQ5ODkgQnJhbmRvbiBTdCIsImNpdHkiOiJXZWxsc3ZpbGxlIiwiY291bnR5IjoiQWxsZWdhbnkiLCJzdGF0ZSI6Ik5ZIiwiemlwIjoiMTQ4OTUiLCJob21lUGhvbmUiOiI1ODUtODY2LTgzMTMiLCJjZWxsUGhvbmUiOiI1ODUtNDk4LTQyNzgiLCJlbWFpbCI6Im1vb25AeWFob28uY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuYW1iZWxhbmdqZXNzaWNhbW1kLmNvbSJ9","brokerInTime":1687328148534,"brokerOutTime":1687328148574}End Message ***************Begin Message Body *************{"firstname":"Moon","lastname":"Parlato","company":"\"Ambelang, Jessica M Md\"","street":"74989 Brandon St","city":"Wellsville","county":"Allegany","state":"NY","zip":"14895","homePhone":"585-866-8313","cellPhone":"585-498-4278","email":"moon@yahoo.com","website":"http://www.ambelangjessicammd.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-75MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:75MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148534BrokerOutTime = 1687328148574DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148534Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Moon","lastname":"Parlato","company":"\"Ambelang, Jessica M Md\"","street":"74989 Brandon St","city":"Wellsville","county":"Allegany","state":"NY","zip":"14895","homePhone":"585-866-8313","cellPhone":"585-498-4278","email":"moon@yahoo.com","website":"http://www.ambelangjessicammd.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:78","messageType":"jms/text-message","timestamp":1687328148537,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-78","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJWaXZhIiwibGFzdG5hbWUiOiJUb2Vsa2VzIiwiY29tcGFueSI6Ik1hcmsgSXYgUHJlc3MgTHRkIiwic3RyZWV0IjoiNDI4NCBEb3JpZ28gTG4iLCJjaXR5IjoiQ2hpY2FnbyIsImNvdW50eSI6IkNvb2siLCJzdGF0ZSI6IklMIiwiemlwIjoiNjA2NDciLCJob21lUGhvbmUiOiI3NzMtNDQ2LTU1NjkiLCJjZWxsUGhvbmUiOiI3NzMtMzUyLTM0MzciLCJlbWFpbCI6InZpdmEudG9lbGtlc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tYXJraXZwcmVzc2x0ZC5jb20ifQ==","brokerInTime":1687328148538,"brokerOutTime":1687328148576}End Message ***************Begin Message Body *************{"firstname":"Viva","lastname":"Toelkes","company":"Mark Iv Press Ltd","street":"4284 Dorigo Ln","city":"Chicago","county":"Cook","state":"IL","zip":"60647","homePhone":"773-446-5569","cellPhone":"773-352-3437","email":"viva.toelkes@gmail.com","website":"http://www.markivpressltd.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-78MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:78MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148538BrokerOutTime = 1687328148576DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148537Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Viva","lastname":"Toelkes","company":"Mark Iv Press Ltd","street":"4284 Dorigo Ln","city":"Chicago","county":"Cook","state":"IL","zip":"60647","homePhone":"773-446-5569","cellPhone":"773-352-3437","email":"viva.toelkes@gmail.com","website":"http://www.markivpressltd.com"}Begin Message *************{"messageID":"ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:81","messageType":"jms/text-message","timestamp":1687328148540,"deliveryMode":1,"correlationID":"TestMessage07-06-21-2023-06-06-02-81","replyTo":"null","destination":{"physicalName":"LambdaActiveMQQueue"},"redelivered":false,"type":"TextMessage","expiration":0,"priority":4,"data":"eyJmaXJzdG5hbWUiOiJUaW1vdGh5IiwibGFzdG5hbWUiOiJNdWxxdWVlbiIsImNvbXBhbnkiOiJTYXJvbml4IE55bXBoIFByb2R1Y3RzIiwic3RyZWV0IjoiNDQgVyA0dGggU3QiLCJjaXR5IjoiU3RhdGVuIElzbGFuZCIsImNvdW50eSI6IlJpY2htb25kIiwic3RhdGUiOiJOWSIsInppcCI6IjEwMzA5IiwiaG9tZVBob25lIjoiNzE4LTMzMi02NTI3IiwiY2VsbFBob25lIjoiNzE4LTY1NC03MDYzIiwiZW1haWwiOiJ0aW1vdGh5X211bHF1ZWVuQG11bHF1ZWVuLm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnNhcm9uaXhueW1waHByb2R1Y3RzLmNvbSJ9","brokerInTime":1687328148541,"brokerOutTime":1687328148578}End Message ***************Begin Message Body *************{"firstname":"Timothy","lastname":"Mulqueen","company":"Saronix Nymph Products","street":"44 W 4th St","city":"Staten Island","county":"Richmond","state":"NY","zip":"10309","homePhone":"718-332-6527","cellPhone":"718-654-7063","email":"timothy_mulqueen@mulqueen.org","website":"http://www.saronixnymphproducts.com"}End Message Body ***************EventSource = aws:mqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-activemq-broker:b-aeb08c0d-6e46-412a-ad45-1507816242b0CorrelationID = TestMessage07-06-21-2023-06-06-02-81MessageID = ID:ip-10-192-10-195.us-west-2.compute.internal-33249-1687328148123-1:1:1:1:81MessageType = jms/text-messageReplyTo = nullType = TextMessageBrokerInTime = 1687328148541BrokerOutTime = 1687328148578DeliveryMode = 1Expiration = 0Priority = 4TimeStamp = 1687328148540Queue = LambdaActiveMQQueueWhetherRedelivered = falseThis person = {"firstname":"Timothy","lastname":"Mulqueen","company":"Saronix Nymph Products","street":"44 W 4th St","city":"Staten Island","county":"Richmond","state":"NY","zip":"10309","homePhone":"718-332-6527","cellPhone":"718-654-7063","email":"timothy_mulqueen@mulqueen.org","website":"http://www.saronixnymphproducts.com"}END RequestId: 30acfa0a-5be4-490b-9d02-f13814482aea +REPORT RequestId: 30acfa0a-5be4-490b-9d02-f13814482aea Init Duration: 0.42 ms Duration: 1218.03 ms Billed Duration: 1219 ms Memory Size: 512 MB Max Memory Used: 512 MB + +***** End sam local invoke response ***** +``` + + +## Deploy the sample application + + +To deploy your application for the first time, run the following in your shell: + +```bash +sam deploy --capabilities CAPABILITY_IAM --no-confirm-changeset --no-disable-rollback --region $AWS_REGION --stack-name activemq-lambda-java-sam --guided +``` + +The sam deploy command will package and deploy your application to AWS, with a series of prompts. You can accept all the defaults by hitting Enter: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Parameter ActiveMQBrokerArn**: The ARN of the ActiveMQBroker that was created by the CloudFormation template +* **Parameter ActiveMQQueue**: The name of the ActiveMQ queue from which the lambda function will consume messages +* **Parameter SecretsManagerSecretForMQ**: The ARN of the secret that has username/password for Active MQ +* **Parameter Subnet1**: The first of the three private subnets where the DocumentDB cluster is deployed +* **Parameter Subnet2**: The second of the three private subnets where the DocumentDB cluster is deployed +* **Parameter Subnet3**: The third of the three private subnets where the DocumentDB cluster is deployed +* **Parameter SecurityGroup**: The security group of the lambda function. This can be the same as the security group of the EC2 machine that was created by the CloudFormation template +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails +* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. +* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally +* **SAM configuration environment [default]**: Environment for storing deployment information locally + +You should get a message "Successfully created/updated stack - in " if all goes well + +**Note: In case you want to deploy the Lambda function by pointing to an existing Amazon MQ (Apache ActiveMQ) Cluster and not the one created by running the CloudFormation template provided in this pattern, you will need to modify the values of the above parameters accordingly** + + +## Test the application + +Once the lambda function is deployed, send some messages to the Amazon MQ (Apache ActiveMQ) cluster on the queue that have been configured on the lambda function's event listener. + +For your convenience, a Java program and a shell script has been created on the EC2 machine that was provisioned using Cloudformation. + +cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json + +You should see a script called commands.sh. Run that script by passing a random string and a number between 1 and 500 + +``` +[ec2-user@ip-10-0-0-126 ~]$ sh ./commands.sh firstBatch 10 +Sent out one message - Number 1 at time = 1760937987906 +Sent out one message - Number 2 at time = 1760937987909 +Sent out one message - Number 3 at time = 1760937987910 +Sent out one message - Number 4 at time = 1760937987911 +Sent out one message - Number 5 at time = 1760937987913 +Sent out one message - Number 6 at time = 1760937987914 +Sent out one message - Number 7 at time = 1760937987915 +Sent out one message - Number 8 at time = 1760937987916 +Sent out one message - Number 9 at time = 1760937987918 +Sent out one message - Number 10 at time = 1760937987919 +``` + +Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) + +Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. + +When you run the above script, it sends messages with JSON records to the Amazon MQ (Apache ActiveMQ) cluster on the queue on which the lambda function is listening on. The lambda function listens on the published ActiveMQ messages on the queue. + +The lambda code parses the ActiveMQ messages and outputs the fields in the messages to Cloudwatch logs + +The lambda function also inputs each record into a DynamoDB table called ActiveMQDynamoDBTableJava (if you did not modify the default name in the sam template.yaml file) + +You can go to the DynamoDB console and view the records. + +You can also use the aws cli command below to view the count of records inserted into DynamoDB + +``` +aws dynamodb scan --table-name ActiveMQDynamoDBTableJava --select "COUNT" + +``` + + + +## Cleanup + +You can first clean-up the Lambda function by running the sam delete command + +``` +cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam +sam delete + +``` +confirm by pressing y for both the questions +You should see the lambda function getting deleted and a final confirmation "Deleted successfully" on the command-line + +Next you need to delete the Cloudformation template that created the Amazon MQ (Apache ActiveMQ) cluster and the EC2 machine by going to the Cloudformation console and selecting the stack and then hitting the "Delete" button. It will run for sometime but eventually you should see the stack getting cleaned up. If you get an error message that says the stack could not be deleted, please retry again and do a Force Delete. The reason this may happen is because ENIs created by the deplayed Lambda function in your VPC may prevent the VPC from being deleted even after deleting the lambda function. \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml index cf252bbd5..36c1673b6 100755 --- a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml +++ b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/template_original.yaml @@ -17,7 +17,7 @@ Resources: FunctionName: java-activemq-consumer-dynamodb-sam CodeUri: activemq_event_consumer_function Handler: com.amazonaws.services.lambda.samples.events.activemq.HandlerActiveMQ::handleRequest - Runtime: java21 + Runtime: JAVA_VERSION Architectures: - x86_64 MemorySize: 512 @@ -98,7 +98,7 @@ Parameters: Default: ACTIVEMQ_QUEUE_NAME SecretsManagerSecretForMQ: Type: String - Description: Enter the name of the secret that has username/password for Active MQ + Description: Enter the ARN of the secret that has username/password for Active MQ Default: ACTIVEMQ_SECRET_ARN Subnet1: Type: String diff --git a/activemq-private-lambda-java-sam/activemq_queue_browser.sh b/activemq-private-lambda-java-sam/activemq_queue_browser.sh index 834cd798f..f37013e10 100644 --- a/activemq-private-lambda-java-sam/activemq_queue_browser.sh +++ b/activemq-private-lambda-java-sam/activemq_queue_browser.sh @@ -6,6 +6,6 @@ /home/ec2-user/activemq_client/apache-activemq-5.18.6/bin/activemq browse --amqurl ACTIVEMQ_BROKER_ENDPOINT_ONE --user ACTIVEMQ_BROKER_ADMIN_USER --password ACTIVEMQ_BROKER_PASSWORD ACTIVEMQ_QUEUE_NAME -#Use the below command if the primary ActiveMQ broker is down for whatever reason +#Uncomment and use the below command if you get a "Broker not available at:" message with the first broker endpoint #/home/ec2-user/activemq_client/apache-activemq-5.18.6/bin/activemq browse --amqurl ACTIVEMQ_BROKER_ENDPOINT_TWO --user ACTIVEMQ_BROKER_ADMIN_USER --password ACTIVEMQ_BROKER_PASSWORD ACTIVEMQ_QUEUE_NAME \ No newline at end of file From a5b0fe9591e845a585709bc34e23feb6ff47b6c2 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sun, 19 Oct 2025 22:35:15 -0700 Subject: [PATCH 09/18] Fixed ActiveMQ Private Lambda Java SAM Project --- .../activemq_consumer_dynamo_sam/README.md | 104 ------------------ .../activemq_message_sender_json/Commands.txt | 5 - .../activemq_message_sender_json/README.md | 27 ----- 3 files changed, 136 deletions(-) delete mode 100755 activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md delete mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt delete mode 100755 activemq-private-lambda-java-sam/activemq_message_sender_json/README.md diff --git a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md b/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md deleted file mode 100755 index 4d4d15497..000000000 --- a/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# activemq-consumer-dynamo-sam - -This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. - -- activemq_event_consumer_function/src/main/java - Code for the application's Lambda function. -- events - Invocation events that you can use to invoke the function. -- activemq_event_consumer_function/src/test/java - Unit tests for the application code. -- template.yaml - A template that defines the application's AWS resources. - -The application uses several AWS resources, including a Lambda function, an ActiveMQ event source and a DynamoDB table to which the lambda function will write. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. - - -## Use the SAM CLI to build and test locally - -Build your application with the `sam build` command. - -```bash -sam build -``` - -The SAM CLI installs dependencies defined in `activemq_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. - -Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. - -Run functions locally and invoke them with the `sam local invoke` command. - -```bash -sam local invoke --event events/event.json -``` - -## Deploy the sample application - -The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. - -To use the SAM CLI, you need the following tools. - -* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) -* Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) - -To build and deploy your application for the first time, run the following in your shell: - -```bash -sam build -sam deploy --guided -``` - -The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: - -* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. -* **AWS Region**: The AWS region you want to deploy your app to. -* **Parameter ActiveMQBrokerName**: The name of the ActiveMQ Broker -* **Parameter ActiveMQBrokerUniqueString**: The unique string of the ActiveMQ Broker -* **Parameter ActiveMQQueue**: The name of the ActiveMQ Queue -* **Parameter SecretsManagerSecretForMQName**: The name of the Secrets Manager secret that has the ActiveMQ broker Username and Password -* **Parameter SecretsManagerSecretForMQUniqueString**: The unique string of the Secrets Manager secret that has the ActiveMQ broker Username and Password -* **Parameter Subnet1**: The name of the first subnet where the ActiveMQ broker has been configured -* **Parameter Subnet2**: The name of the second subnet where the ActiveMQ broker has been configured -* **Parameter SecurityGroup**: The name of the security group where the ActiveMQ broker has been configured -* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. -* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. -* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails -* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. -* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally -* **SAM configuration environment [default]**: Environment for storing deployment information locally - -You should get a message "Successfully created/updated stack - in " if all goes well - - -## Test the sample application - -Once the lambda function is deployed, send some ActiveMQ messages on the queue that the lambda function is listening on. - -Use the project ../activemq_message_sender_json. - -Look at the Readme of that project to determine how to build that project and run the command that will send ActiveMQ messages with a Json payload to the lambda function built using this project. The lambda function will receive the ActiveMQ messages with a JSON payload and input fields from the ActiveMQ message into a DynamoDB table. - -The value field of each SQS message that will be sent out will be a Json element of the format - -"person": { - "firstname": "Myra", - "lastname": "Munns", - "company": "Anker Law Office", - "street": "461 Prospect Pl #316", - "city": "Euless", - "county": "Tarrant", - "state": "TX", - "zip": "76040", - "homePhone": "817-914-7518", - "cellPhone": "817-451-3518", - "email": "mmunns@cox.net", - "website": "http://www.ankerlawoffice.com" -} - -Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) - -Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. - -The lambda code parses the ActiveMQ messages and outputs the fields in the ActiveMQ messages to Cloudwatch logs - -A single lambda function receives a batch of messages. - -The code in this example prints out the fields in the ActiveMQ message and logs them in Cloudwatch logs. - -Apart from outputting to Cloudwatch logs, the lambda function also inputs fields from the ActiveMQ message (both message metadata fields as well as payload fields from the JSON payload) into a DynamoDB table created by the SAM template. You can log into the AWS console and look at the DynamoDB table and run a scan to see data getting input from the ActiveMQ message into the DynamoDB table diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt b/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt deleted file mode 100755 index c56ac3bf8..000000000 --- a/activemq-private-lambda-java-sam/activemq_message_sender_json/Commands.txt +++ /dev/null @@ -1,5 +0,0 @@ -java -classpath /activemq_message_sender_json/target/json-activemq-producer-0.0.1-SNAPSHOT.jar activemq.producer.JsonActiveMQProducer - -Example: - -java -classpath ~/environment/JavaExamples/activemq_message_sender_json/target/json-activemq-producer-0.0.1-SNAPSHOT.jar activemq.producer.JsonActiveMQProducer "failover:(ssl://b-aeb08c0d-6e46-412a-ad45-1507816242b0-1.mq.us-west-2.amazonaws.com:61617,ssl://b-aeb08c0d-6e46-412a-ad45-1507816242b0-2.mq.us-west-2.amazonaws.com:61617)" LambdaActiveMQQueue TestMessage12 10 \ No newline at end of file diff --git a/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md b/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md deleted file mode 100755 index c72cc7d00..000000000 --- a/activemq-private-lambda-java-sam/activemq_message_sender_json/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# activemq-message-sender-json - -This project contains source code and supporting files for a Java application that you can use to generate messages to an ActiveMQ broker queue, that can in turn be consumed by a Lambda function - -- activemq_message_sender_json/src/main/java - Code for the application. -- activemq_message_sender_json/Commands - A file that contains the command to run this application so messages can be generated on an ActiveMQ queue, to invoke the corresponding Lambda function - -## Set-up and run this application - -The steps required before this application can be run are - -1) Install and configure an ActiveMQ cluster (use AWS console or a Cloudformation template) - for detailed instructions look at the AWS documentation - https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-creating-configuring-broker.html. For information on how to use Cloudformation to create an ActiveMQ cluster, take a look at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amazonmq-broker.html - -2) Create a secret in AWS Secrets Manager called AmazonMQCredentials - Choose a secret of type "Other Type of Secret" when creating the secret. Provide the username and password to connect to the ActiveMQ broker, as had been specified at the time of cluster creation. Name this secret AmazonMQCredentials - -3) After cloning the code for this project from Github, go to the folder where the project was cloned and run the command 'mvn clean install' (without the quotes). Make sure maven is installed on the computer from where you are running this command, prior to running the command - -4) If you are running the command to send ActiveMQ messages from a Cloud9 or EC2 instance, make sure that the security group of the ActiveMQ cluster allows inbound traffic from the security group of the Cloud9 or EC2 instance on port 61617. Also make sure that the role associated with the Cloud9 or EC2 instance has policies attached to it that allow the permissions that are needed. For example, you can use the AmazonMQFullAccess policy on the role. - -5) Use the command specified in the activemq_message_sender_json/Commands file to generate ActiveMQ queue messages that can be consumed by the Lambda function. The command specified in the Commands file takes four parameters - - a) The ActiveMQ broker URL of the ActiveMQ cluster created in Step 1 - b) The name of the ActiveMQ queue on which messages will be published. This must match the name of the ActiveMQ queue that is configured in the event source of the lambda function - c) A Unique String that can be used to identify the batch of ActiveMQ queue messages that will be generated - d) The number of ActiveMQ queue messages to generate as part of this batch - -6) If a Lambda function consumer of the ActiveMQ queue messages has already been deployed, then you should be able to see the content of the messages in the Lambda function logs in Cloudwatch \ No newline at end of file From 7aad9e244242731310b9b9d2570dc0090cda1f1e Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Mon, 20 Oct 2025 19:05:32 -0700 Subject: [PATCH 10/18] Added CloudFormation template and other artifacts for RabbitMQ Private Lambda Java SAM Project --- .../example-pattern.json | 93 ++ ...ientEC2.yaml => ActiveMQAndClientEC2.yaml} | 530 +++++------ .../RabbitMQAndClientEC2.yaml | 841 ++++++++++++++++++ .../example-pattern.json | 93 ++ .../{template.yaml => template_original.yaml} | 28 +- .../rabbitmq_message_sender_json/commands.sh | 7 + 6 files changed, 1275 insertions(+), 317 deletions(-) create mode 100644 activemq-private-lambda-java-sam/example-pattern.json rename rabbitmq-private-lambda-java-sam/{DocumentDBAndMongoClientEC2.yaml => ActiveMQAndClientEC2.yaml} (58%) create mode 100644 rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml create mode 100644 rabbitmq-private-lambda-java-sam/example-pattern.json rename rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/{template.yaml => template_original.yaml} (81%) create mode 100755 rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh diff --git a/activemq-private-lambda-java-sam/example-pattern.json b/activemq-private-lambda-java-sam/example-pattern.json new file mode 100644 index 000000000..5eb3fb455 --- /dev/null +++ b/activemq-private-lambda-java-sam/example-pattern.json @@ -0,0 +1,93 @@ +{ + "title": "AWS Lambda function subscribed to an Amazon MQ - Apache ActiveMQ in private subnets (Java)", + "description": "Creates a Lambda function that uses a private Amazon MQ (Apache ActiveMQ) as an event source.", + "language": "Java", + "level": "200", + "framework": "AWS SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern provides a Lambda function along with an Event Source Mapping to an Amazon MQ (Apache ActiveMQ) queue.", + "The CloudFormation template provided in this pattern installs an Amazon MQ (Apache ActiveMQ) Cluster in private subnets in a VPC.", + "For detailed deployment instructions instructions see the README.md" + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/activemq-private-lambda-java-sam", + "templateURL": "serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam", + "projectFolder": "activemq-private-lambda-java-sam", + "templateFile": "template_original.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "Configuring Amazon MQ event source for Lambda", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/process-mq-messages-with-lambda.html" + }, + { + "text": "Using Lambda with Amazon MQ", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html" + }, + { + "text": "Amazon MQ resource type reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/AWS_AmazonMQ.html" + } + ] + }, + "deploy": { + "text": [ + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the template: sam delete." + ] + }, + "authors": [ + { + "name": "Indranil Banerjee", + "bio": "AWS - Senior Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C5603AQEL3BG6JZca6A/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1653972622784?e=1762992000&v=beta&t=a9gnmtxyWBhfEfqDF3HiPHWDoc4KZjG2sdNsIakcJXw", + "linkedin": "https://www.linkedin.com/in/indranil-banerjee-b00a261/" + }, + { + "name": "Arghya Banerjee", + "bio": "AWS - Senior Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C5603AQHFFKivT-1iKA/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1516305772138?e=1762992000&v=beta&t=dKgoxEfgZd3M5XW-GEJ9Ss4I5ka8-C7iEIy8Sb_PTOQ", + "linkedin": "https://www.linkedin.com/in/arghya-b-6130b57/" + }, + { + "name": "Kunal Ghosh", + "bio": "AWS - Sr SA, Strategic Accounts", + "image": "https://media.licdn.com/dms/image/v2/C5603AQHrj7mHd7Z1hg/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1516355158121?e=1762992000&v=beta&t=8h0cpHLR6v4-e3BJ7n9Wd_OHL2rRDa8F_74rTUnu8Js", + "linkedin": "https://www.linkedin.com/in/kunal-ghosh-6583058/" + }, + { + "name": "Angelo Spagnolo", + "bio": "AWS - Sr Technical Account Manager", + "image": "https://media.licdn.com/dms/image/v2/D5603AQFQj2a90KFFZQ/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1692659294509?e=1762992000&v=beta&t=gEfdRLVzNPXGZ9-5EZKA358NBf4F7VBcVthyWSrzjrs", + "linkedin": "https://www.linkedin.com/in/aspagnolo/" + }, + { + "name": "Vinayak Datar", + "bio": "AWS - Sr. Customer Solutions Manager", + "image": "https://media.licdn.com/dms/image/v2/C5103AQFAa6JcLNknkA/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1548189034877?e=1762992000&v=beta&t=o2lDqU3V4ivFjt00rEDYd2yjGr55TszcG0J9hGuRM_w", + "linkedin": "https://www.linkedin.com/in/vinayakdatar/" + }, + { + "name": "Greg Medard", + "bio": "AWS - Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C4E03AQGveSDnRH9aCg/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1565226836063?e=1762992000&v=beta&t=Jkir-cq-T1EU8MTqY7PPPxreVo2_zI4FXaXXrdTdpfQ", + "linkedin": "https://www.linkedin.com/in/gregorymedard/" + } + ] + } + \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml b/rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml similarity index 58% rename from rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml rename to rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml index eba751ca8..542c09a9a 100644 --- a/rabbitmq-private-lambda-java-sam/DocumentDBAndMongoClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml @@ -3,10 +3,10 @@ Parameters: LatestAmiId: Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' - DocumentDBEngineVersion: + ActiveMQEngineVersion: Type: String - Default: 5.0.0 - Description: DocumentDB engine version + Default: 5.18 + Description: ActiveMQ engine version JavaVersion: Type: String Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 @@ -15,27 +15,22 @@ Parameters: - java17 - java21 Default: java21 - DocumentDBDatabaseName: + ActiveMQBrokerName: Type: String - Default: DocumentDBJavaLambdaDB - Description: DocumentDB database name for Lambda function - DocumentDBCollectionName: + Default: ActiveMQJavaLambdaBroker + Description: ActiveMQ broker name for Lambda function + ActiveMQQueueName: Type: String - Default: DocumentDBJavaLambdaCollection - Description: DocumentDB collection name for Lambda function - DocumentDBClusterAdminUser: + Default: ActiveMQJavaLambdaQueue + Description: ActiveMQ queue name for Lambda function + ActiveMQBrokerAdminUser: Type: String - Description: Password for the DocumentDB Cluster - Default: docdbadmin - DocumentDBClusterPassword: + Description: Username for the ActiveMQ Broker + Default: activemqadmin + ActiveMQBrokerPassword: Type: String - Description: Password for the DocumentDB Cluster - Default: docdbPassword123 - NoEcho: true - DocumentDBTrustStorePassword: - Type: String - Description: Password for the DocumentDB Client TLS Truststore Password - Default: docdbTrustPass123 + Description: Password for the ActiveMQ Broker + Default: activemqPassword123 NoEcho: true ServerlessLandGithubLocation: Type: String @@ -45,42 +40,31 @@ Parameters: Mappings: SubnetConfig: VPC: - CIDR: '10.0.0.0/16' + CIDR: '10.1.0.0/16' PublicOne: - CIDR: '10.0.0.0/24' + CIDR: '10.1.0.0/24' PublicTwo: - CIDR: '10.0.1.0/24' + CIDR: '10.1.1.0/24' PublicThree: - CIDR: '10.0.2.0/24' - PrivateSubnetDocDBOne: - CIDR: '10.0.3.0/24' - PrivateSubnetDocDBTwo: - CIDR: '10.0.4.0/24' - PrivateSubnetDocDBThree: - CIDR: '10.0.5.0/24' + CIDR: '10.1.2.0/24' + PrivateSubnetActiveMQOne: + CIDR: '10.1.3.0/24' + PrivateSubnetActiveMQTwo: + CIDR: '10.1.4.0/24' + PrivateSubnetActiveMQThree: + CIDR: '10.1.5.0/24' Resources: - # Secrets Manager Secret for DocumentDB credentials - DocumentDBSecret: - Type: AWS::SecretsManager::Secret - Properties: - Name: 'AmazonDocumentDBCredentials' - Description: DocumentDB cluster master user credentials - SecretString: !Sub | - { - "username": "${DocumentDBClusterAdminUser}", - "password": "${DocumentDBClusterPassword}" - } - - DocumentDBTrustStoreSecret: + # Secrets Manager Secret for ActiveMQ credentials + ActiveMQSecret: Type: AWS::SecretsManager::Secret Properties: - Name: 'AmazonDocumentDBTruststore' - Description: DocumentDB secret for truststore for SSL client to connect + Name: 'AmazonActiveMQCredentials' + Description: ActiveMQ broker master user credentials SecretString: !Sub | { - "truststore": "/home/ec2-user/mongotruststore/rds-truststore.jks", - "truststorepassword": "${DocumentDBTrustStorePassword}" + "username": "${ActiveMQBrokerAdminUser}", + "password": "${ActiveMQBrokerPassword}" } VPC: @@ -91,7 +75,7 @@ Resources: CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] Tags: - Key: 'Name' - Value: 'DocumentDBVPC' + Value: 'ActiveMQVPC' PublicSubnetOne: Type: AWS::EC2::Subnet @@ -132,7 +116,7 @@ Resources: Tags: - Key: 'Name' Value: 'PublicSubnetThree' - PrivateSubnetDocDBOne: + PrivateSubnetActiveMQOne: Type: AWS::EC2::Subnet Properties: AvailabilityZone: @@ -140,12 +124,12 @@ Resources: - 0 - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBOne', 'CIDR'] + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] MapPublicIpOnLaunch: false Tags: - Key: 'Name' - Value: 'PrivateSubnetDocDBOne' - PrivateSubnetDocDBTwo: + Value: 'PrivateSubnetActiveMQOne' + PrivateSubnetActiveMQTwo: Type: AWS::EC2::Subnet Properties: AvailabilityZone: @@ -153,12 +137,12 @@ Resources: - 1 - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBTwo', 'CIDR'] + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] MapPublicIpOnLaunch: false Tags: - Key: 'Name' - Value: 'PrivateSubnetDocDBTwo' - PrivateSubnetDocDBThree: + Value: 'PrivateSubnetActiveMQTwo' + PrivateSubnetActiveMQThree: Type: AWS::EC2::Subnet Properties: AvailabilityZone: @@ -166,11 +150,11 @@ Resources: - 2 - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetDocDBThree', 'CIDR'] + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQThree', 'CIDR'] MapPublicIpOnLaunch: false Tags: - Key: 'Name' - Value: 'PrivateSubnetDocDBThree' + Value: 'PrivateSubnetActiveMQThree' InternetGateway: Type: AWS::EC2::InternetGateway @@ -193,7 +177,7 @@ Resources: SubnetId: !Ref 'PublicSubnetOne' Tags: - Key: 'Name' - Value: 'DocumentDBNATGateway1' + Value: 'ActiveMQNATGateway1' NATEIP2: Type: AWS::EC2::EIP @@ -208,7 +192,7 @@ Resources: SubnetId: !Ref 'PublicSubnetTwo' Tags: - Key: 'Name' - Value: 'DocumentDBNATGateway2' + Value: 'ActiveMQNATGateway2' NATEIP3: Type: AWS::EC2::EIP @@ -223,7 +207,7 @@ Resources: SubnetId: !Ref 'PublicSubnetThree' Tags: - Key: 'Name' - Value: 'DocumentDBNATGateway3' + Value: 'ActiveMQNATGateway3' PublicRouteTable: Type: AWS::EC2::RouteTable @@ -295,29 +279,29 @@ Resources: DestinationCidrBlock: '0.0.0.0/0' NatGatewayId: !Ref 'NATGateway3' - PrivateSubnetDocDBOneRouteTableAssociation: + PrivateSubnetActiveMQOneRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable1 - SubnetId: !Ref PrivateSubnetDocDBOne + SubnetId: !Ref PrivateSubnetActiveMQOne - PrivateSubnetDocDBTwoRouteTableAssociation: + PrivateSubnetActiveMQTwoRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable2 - SubnetId: !Ref PrivateSubnetDocDBTwo + SubnetId: !Ref PrivateSubnetActiveMQTwo - PrivateSubnetDocDBThreeRouteTableAssociation: + PrivateSubnetActiveMQThreeRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable3 - SubnetId: !Ref PrivateSubnetDocDBThree + SubnetId: !Ref PrivateSubnetActiveMQThree - DocumentDBClientInstanceSecurityGroup: + ActiveMQClientInstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup - GroupName: !Sub "${AWS::StackName} Security group attached to the DocumentDB client" + GroupName: !Sub "${AWS::StackName} Security group attached to the ActiveMQ client" VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp @@ -325,35 +309,78 @@ Resources: ToPort: 22 CidrIp: 10.0.0.0/16 - DocumentDBSecurityGroup: + ActiveMQSecurityGroup: Type: AWS::EC2::SecurityGroup - DependsOn: [VPC,DocumentDBClientInstanceSecurityGroup] + DependsOn: [VPC,ActiveMQClientInstanceSecurityGroup] Properties: - GroupDescription: DocumentDB Security Group - GroupName: !Sub "${AWS::StackName} Security group for the DocumentDB cluster" + GroupDescription: ActiveMQ Security Group + GroupName: !Sub "${AWS::StackName} Security group for the ActiveMQ broker" VpcId: !Ref 'VPC' SecurityGroupIngress: - IpProtocol: tcp - FromPort: 27017 - ToPort: 27017 - SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + FromPort: 61617 + ToPort: 61617 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 8162 + ToPort: 8162 + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - IpProtocol: tcp FromPort: 0 ToPort: 65535 - CidrIp: 10.0.0.0/16 + CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - DocumentDBClientSelfIngressAllowRule: + ActiveMQClientSelfIngressAllowRule: Type: AWS::EC2::SecurityGroupIngress - DependsOn: DocumentDBClientInstanceSecurityGroup + DependsOn: ActiveMQClientInstanceSecurityGroup Properties: - GroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + GroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId IpProtocol: tcp FromPort: 22 ToPort: 22 - SourceSecurityGroupId: !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + + # ActiveMQ Configuration + ActiveMQConfiguration: + Type: AWS::AmazonMQ::Configuration + Properties: + Name: !Sub "${AWS::StackName}-activemq-config" + Description: ActiveMQ configuration for the cluster + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + Data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8YnJva2VyIHhtbG5zPSJodHRwOi8vYWN0aXZlbXEuYXBhY2hlLm9yZy9zY2hlbWEvY29yZSI+CiAgPGRlc3RpbmF0aW9uUG9saWN5PgogICAgPHBvbGljeU1hcD4KICAgICAgPHBvbGljeUVudHJpZXM+CiAgICAgICAgPHBvbGljeUVudHJ5IHRvcGljPSI+IiBwcm9kdWNlckZsb3dDb250cm9sPSJ0cnVlIj4KICAgICAgICAgIDxwZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgICAgIDxzcG9vbGluZ1N1YnNjcmlwdGlvblBlbmRpbmdNZXNzYWdlTGltaXRTdHJhdGVneSBsaW1pdD0iMTAwMCIvPgogICAgICAgICAgPC9wZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgPC9wb2xpY3lFbnRyeT4KICAgICAgICA8cG9saWN5RW50cnkgcXVldWU9Ij4iIHByb2R1Y2VyRmxvd0NvbnRyb2w9InRydWUiIG1lbW9yeUxpbWl0PSIxbWIiPgogICAgICAgIDwvcG9saWN5RW50cnk+CiAgICAgIDwvcG9saWN5RW50cmllcz4KICAgIDwvcG9saWN5TWFwPgogIDwvZGVzdGluYXRpb25Qb2xpY3k+CiAgPHN5c3RlbVVzYWdlPgogICAgPHN5c3RlbVVzYWdlPgogICAgICA8bWVtb3J5VXNhZ2U+CiAgICAgICAgPG1lbW9yeVVzYWdlIGxpbWl0PSI2NCBtYiIvPgogICAgICA8L21lbW9yeVVzYWdlPgogICAgICA8c3RvcmVVc2FnZT4KICAgICAgICA8c3RvcmVVc2FnZSBsaW1pdD0iNTEyIG1iIi8+CiAgICAgIDwvc3RvcmVVc2FnZT4KICAgICAgPHRlbXBVc2FnZT4KICAgICAgICA8dGVtcFVzYWdlIGxpbWl0PSIxMjggbWIiLz4KICAgICAgPC90ZW1wVXNhZ2U+CiAgICA8L3N5c3RlbVVzYWdlPgogIDwvc3lzdGVtVXNhZ2U+CjwvYnJva2VyPgo= + + # ActiveMQ Broker + ActiveMQBroker: + Type: AWS::AmazonMQ::Broker + Properties: + BrokerName: !Ref ActiveMQBrokerName + DeploymentMode: ACTIVE_STANDBY_MULTI_AZ + EngineType: ACTIVEMQ + EngineVersion: !Ref ActiveMQEngineVersion + HostInstanceType: mq.t3.micro + PubliclyAccessible: false + AutoMinorVersionUpgrade: true + Configuration: + Id: !Ref ActiveMQConfiguration + Revision: 1 + Users: + - Username: !Ref ActiveMQBrokerAdminUser + Password: !Ref ActiveMQBrokerPassword + ConsoleAccess: true + Groups: + - admin + SubnetIds: + - !Ref PrivateSubnetActiveMQOne + - !Ref PrivateSubnetActiveMQTwo + SecurityGroups: + - !Ref ActiveMQSecurityGroup + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-activemq-broker" - DocumentDBClientEC2Instance: - DependsOn: DocumentDBCluster + ActiveMQClientEC2Instance: + DependsOn: ActiveMQBroker Type: AWS::EC2::Instance Properties: InstanceType: m5.large @@ -363,11 +390,11 @@ Resources: - 0 - Fn::GetAZs: {Ref: 'AWS::Region'} SubnetId: !Ref PublicSubnetOne - SecurityGroupIds: [!GetAtt DocumentDBClientInstanceSecurityGroup.GroupId] + SecurityGroupIds: [!GetAtt ActiveMQClientInstanceSecurityGroup.GroupId] ImageId: !Ref LatestAmiId Tags: - Key: 'Name' - Value: 'DocumentDBClientInstance' + Value: 'ActiveMQClientInstance' BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: @@ -388,11 +415,10 @@ Resources: while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do echo "Trying yum install" yum update -y - # yum install java-openjdk11-devel -y # install Java JAVA_VERSION=${java_version} - echo "JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile if [ "$JAVA_VERSION" == "java11" ]; then sudo yum install java-11-amazon-corretto-devel -y elif [ "$JAVA_VERSION" == "java17" ]; then @@ -447,7 +473,6 @@ Resources: fi done - max_attempts=5 attempt_num=1 success=false @@ -531,15 +556,7 @@ Resources: curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install - - - # Install MongoDB shell - cd /home/ec2-user - wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-amazon2-x86_64-100.9.4.tgz - tar -zxvf mongodb-database-tools-amazon2-x86_64-100.9.4.tgz - sudo cp mongodb-database-tools-amazon2-x86_64-100.9.4/bin/* /usr/local/bin/ - # Install AWS SAM CLI cd /home/ec2-user mkdir -p awssam @@ -549,116 +566,85 @@ Resources: sudo ./sam-installation/install # Set environment variables - DOCDB_CLUSTER_ENDPOINT=${docdb_cluster_endpoint} - DOCDB_CLUSTER_RESOURCE=${docdb_cluster_resource} - DOCDB_CLUSTER_IDENTIFIER=${docdb_cluster_identifier} - DOCDB_DATABASE=${docdb_database} - DOCDB_COLLECTION=${docdb_collection} - DOCDB_SECRET_ARN=${docdb_secret_arn} + ACTIVEMQ_BROKER_ID=${activemq_broker_id} + ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} + activemq_broker_endpoint="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" + ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} + ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} AWS_REGION=${aws_region} - DOCDB_SUBNET_ONE=${docdb_subnet_one} - DOCDB_SUBNET_TWO=${docdb_subnet_two} - DOCDB_SUBNET_THREE=${docdb_subnet_three} - DOCDB_SECURITY_GROUP=${docdb_security_group} - DOCDB_CLUSTER_ADMIN_USER=${docdb_cluster_admin_user} - DOCDB_CLUSTER_PASSWORD=${docdb_cluster_password} - DOCDB_TRUST_STORE_PASSWORD=${docdb_trust_store_password} + ACTIVEMQ_SUBNET_ONE=${activemq_subnet_one} + ACTIVEMQ_SUBNET_TWO=${activemq_subnet_two} + ACTIVEMQ_SUBNET_THREE=${activemq_subnet_three} + ACTIVEMQ_SECURITY_GROUP=${activemq_security_group} + ACTIVEMQ_BROKER_ADMIN_USER=${activemq_broker_admin_user} + ACTIVEMQ_BROKER_PASSWORD=${activemq_broker_password} SECURITY_GROUP=${security_group_id} - - echo "export DOCDB_CLUSTER_ENDPOINT=$DOCDB_CLUSTER_ENDPOINT" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_RESOURCE=$DOCDB_CLUSTER_RESOURCE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_IDENTIFIER=$DOCDB_CLUSTER_IDENTIFIER" >> /home/ec2-user/.bash_profile - echo "export DOCDB_DATABASE=$DOCDB_DATABASE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_COLLECTION=$DOCDB_COLLECTION" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SECRET_ARN=$DOCDB_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_ONE=$DOCDB_SUBNET_ONE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_TWO=$DOCDB_SUBNET_TWO" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SUBNET_THREE=$DOCDB_SUBNET_THREE" >> /home/ec2-user/.bash_profile - echo "export DOCDB_SECURITY_GROUP=$DOCDB_SECURITY_GROUP" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_ADMIN_USER=$DOCDB_CLUSTER_ADMIN_USER" >> /home/ec2-user/.bash_profile - echo "export DOCDB_CLUSTER_PASSWORD=$DOCDB_CLUSTER_PASSWORD" >> /home/ec2-user/.bash_profile - echo "export DOCDB_TRUST_STORE_PASSWORD=$DOCDB_TRUST_STORE_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_ONE=$ACTIVEMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_TWO=$ACTIVEMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SUBNET_THREE=$ACTIVEMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_SECURITY_GROUP=$ACTIVEMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_ADMIN_USER=$ACTIVEMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export ACTIVEMQ_BROKER_PASSWORD=$ACTIVEMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - # Clone serverless patterns cd /home/ec2-user SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION cd ./serverless-patterns - git sparse-checkout set --no-cone /documentdb-lambda-java-sam + git sparse-checkout set --no-cone /activemq-private-lambda-java-sam git checkout - cd documentdb-lambda-java-sam + cd activemq-private-lambda-java-sam sudo chown -R ec2-user . - #Install MongoShell - sudo cp ./mongodb-org-8.0.repo /etc/yum.repos.d - cd /home/ec2-user - mkdir mongoshell - cd mongoshell - sudo yum install -y mongodb-mongosh - - #Create Java Keystore to connect to DocumentDB - cd /home/ec2-user - mkdir mongotruststore - cd /home/ec2-user/mongotruststore - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/java_keystore_script.sh . - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/TRUSTSTORE_PASSWORD/$DOCDB_TRUST_STORE_PASSWORD/g" java_keystore_script.sh - chmod +x java_keystore_script.sh - sh ./java_keystore_script.sh - - #Create DocumentDB database and collection - cd /home/ec2-user/mongoshell - wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/docdb_db_collection.sh . - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/mongodbcolcreate.js . - cp /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/connect_to_mongo_shell.sh . - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" docdb_db_collection.sh - sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" docdb_db_collection.sh - sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" docdb_db_collection.sh - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" docdb_db_collection.sh - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" docdb_db_collection.sh - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" mongodbcolcreate.js - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" mongodbcolcreate.js - sed -i "s/DOCDB_CLUSTER_ENDPOINT/$DOCDB_CLUSTER_ENDPOINT/g" connect_to_mongo_shell.sh - sed -i "s/DOCDB_CLUSTER_ADMIN_USER/$DOCDB_CLUSTER_ADMIN_USER/g" connect_to_mongo_shell.sh - sed -i "s/DOCDB_CLUSTER_PASSWORD/$DOCDB_CLUSTER_PASSWORD/g" connect_to_mongo_shell.sh - chmod +x docdb_db_collection.sh - chmod +x connect_to_mongo_shell.sh - sh ./docdb_db_collection.sh - #Substitute SAM template variables - cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam - cd documentdb_streams_consumer_dynamo_sam + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + cd activemq_consumer_dynamo_sam cp template_original.yaml template.yaml sudo chown -R ec2-user . source /home/ec2-user/.bash_profile - sed -i "s/DOCDB_CLUSTER_IDENTIFIER/$DOCDB_CLUSTER_IDENTIFIER/g" template.yaml - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" template.yaml - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" template.yaml + sed -i "s/ACTIVEMQ_BROKER_ARN/$ACTIVEMQ_BROKER_ARN/g" template.yaml + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" template.yaml + sed -i "s/ACTIVEMQ_SECRET_ARN/$ACTIVEMQ_SECRET_ARN/g" template.yaml sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml - sed -i "s/DOCDB_SECRET_ARN/$DOCDB_SECRET_ARN/g" template.yaml - sed -i "s/DOCDB_SUBNET_ONE/$DOCDB_SUBNET_ONE/g" template.yaml - sed -i "s/DOCDB_SUBNET_TWO/$DOCDB_SUBNET_TWO/g" template.yaml - sed -i "s/DOCDB_SUBNET_THREE/$DOCDB_SUBNET_THREE/g" template.yaml - sed -i "s/DOCDB_SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_ONE/$ACTIVEMQ_SUBNET_ONE/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_TWO/$ACTIVEMQ_SUBNET_TWO/g" template.yaml + sed -i "s/ACTIVEMQ_SUBNET_THREE/$ACTIVEMQ_SUBNET_THREE/g" template.yaml + sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml - #Adding DocumentDB variables to DocumentDB secret as CloudFormation cannot create a secret of type DocumentDB like you manually can - aws secretsmanager put-secret-value --secret-id AmazonDocumentDBCredentials --secret-string "{\"host\":\"$DOCDB_CLUSTER_ENDPOINT\",\"port\":\"27017\",\"username\":\"$DOCDB_CLUSTER_ADMIN_USER\",\"password\":\"$DOCDB_CLUSTER_PASSWORD\",\"engine\":\"mongo\",\"ssl\":\"true\",\"dbClusterIdentifier\":\"$DOCDB_CLUSTER_IDENTIFIER\"}" - - #Compiling Sender Program and Updating Command File with DocumentDB Database and Collection names - cd /home/ec2-user/serverless-patterns/documentdb-lambda-java-sam/documentdb_streams_message_sender_json + #Install ActiveMQ (needed in case you want to use the CLI as a client to look at queues etc.) + mkdir /home/ec2-user/activemq_client + cd /home/ec2-user/activemq_client + wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz + tar zxvf apache-activemq-5.18.6-bin.tar.gz sudo chown -R ec2-user . - sed -i "s/DOCDB_DATABASE/$DOCDB_DATABASE/g" commands.sh - sed -i "s/DOCDB_COLLECTION/$DOCDB_COLLECTION/g" commands.sh + + #Update Shell script for sending ActiveMQ messages to Lambda function + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json + sudo chown ec2-user ./commands.sh + source /home/ec2-user/.bash_profile + echo "ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|$activemq_broker_endpoint|g" commands.sh + sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh mvn clean install + #Update Shell script for browsing messages in ActiveMQ queue + cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam + sudo chown ec2-user ./activemq_queue_browser.sh + source /home/ec2-user/.bash_profile + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh + sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh + # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user mkdir -p ip_prefix @@ -672,31 +658,29 @@ Resources: echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP - - docdb_cluster_endpoint: !GetAtt DocumentDBCluster.Endpoint - docdb_cluster_resource: !GetAtt DocumentDBCluster.ClusterResourceId - docdb_cluster_identifier: !Ref DocumentDBCluster - docdb_database: !Ref DocumentDBDatabaseName - docdb_collection: !Ref DocumentDBCollectionName - docdb_secret_arn: !Ref DocumentDBSecret + - activemq_broker_id: !Ref ActiveMQBroker + activemq_broker_arn: !GetAtt ActiveMQBroker.Arn + activemq_broker_endpoint1: !Select [ 0, !GetAtt ActiveMQBroker.OpenWireEndpoints ] + activemq_broker_endpoint2: !Select [ 1, !GetAtt ActiveMQBroker.OpenWireEndpoints ] + activemq_queue_name: !Ref ActiveMQQueueName + activemq_secret_arn: !Ref ActiveMQSecret serverless_land_github_location: !Ref ServerlessLandGithubLocation aws_region: !Ref 'AWS::Region' java_version: !Ref JavaVersion - security_group_id : !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId - docdb_subnet_one: !Ref PrivateSubnetDocDBOne - docdb_subnet_two: !Ref PrivateSubnetDocDBTwo - docdb_subnet_three: !Ref PrivateSubnetDocDBThree - docdb_security_group: !GetAtt DocumentDBSecurityGroup.GroupId - docdb_cluster_admin_user: !Ref DocumentDBClusterAdminUser - docdb_cluster_password: !Ref DocumentDBClusterPassword - docdb_trust_store_password: !Ref DocumentDBTrustStorePassword - + security_group_id : !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId + activemq_subnet_one: !Ref PrivateSubnetActiveMQOne + activemq_subnet_two: !Ref PrivateSubnetActiveMQTwo + activemq_subnet_three: !Ref PrivateSubnetActiveMQThree + activemq_security_group: !GetAtt ActiveMQSecurityGroup.GroupId + activemq_broker_admin_user: !Ref ActiveMQBrokerAdminUser + activemq_broker_password: !Ref ActiveMQBrokerPassword EC2InstanceEndpoint: Type: AWS::EC2::InstanceConnectEndpoint Properties: PreserveClientIp: true SecurityGroupIds: - - !GetAtt DocumentDBClientInstanceSecurityGroup.GroupId + - !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId SubnetId: !Ref PublicSubnetOne EC2Role: @@ -712,7 +696,7 @@ Resources: Action: 'sts:AssumeRole' Path: "/" ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonDocDBFullAccess + - arn:aws:iam::aws:policy/AmazonMQFullAccess - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - arn:aws:iam::aws:policy/CloudWatchFullAccess - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore @@ -721,16 +705,15 @@ Resources: - arn:aws:iam::aws:policy/AWSLambda_FullAccess - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 Policies: - - PolicyName: DocumentDBAccess + - PolicyName: ActiveMQAccess PolicyDocument: !Sub '{ "Version": "2012-10-17", "Statement": [ { - "Sid": "DocumentDBFullAccess", + "Sid": "ActiveMQFullAccess", "Effect": "Allow", "Action": [ - "docdb:*", - "docdb-elastic:*" + "mq:*" ], "Resource": "*" } @@ -747,15 +730,7 @@ Resources: "secretsmanager:PutSecretValue", "secretsmanager:DescribeSecret" ], - "Resource": "${DocumentDBSecret}" - }, - { - "Effect": "Allow", - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret" - ], - "Resource": "${DocumentDBTrustStoreSecret}" + "Resource": "${ActiveMQSecret}" } ] }' @@ -817,73 +792,10 @@ Resources: Properties: InstanceProfileName: !Join - '-' - - - 'EC2DocumentDBProfile' + - - 'EC2ActiveMQProfile' - !Ref 'AWS::StackName' Roles: - !Ref EC2Role - - - # DocumentDB Subnet Group - DocumentDBSubnetGroup: - Type: AWS::DocDB::DBSubnetGroup - Properties: - DBSubnetGroupDescription: Subnet group for DocumentDB cluster - SubnetIds: - - !Ref PrivateSubnetDocDBOne - - !Ref PrivateSubnetDocDBTwo - - !Ref PrivateSubnetDocDBThree - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-subnet-group" - - # DocumentDB Instance-Based Cluster - DocumentDBCluster: - Type: AWS::DocDB::DBCluster - Properties: - DBClusterIdentifier: !Sub "${AWS::StackName}-docdb-cluster" - MasterUsername: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:username}}" - MasterUserPassword: !Sub "{{resolve:secretsmanager:${DocumentDBSecret}:SecretString:password}}" - EngineVersion: !Ref DocumentDBEngineVersion - DBSubnetGroupName: !Ref DocumentDBSubnetGroup - VpcSecurityGroupIds: - - !Ref DocumentDBSecurityGroup - BackupRetentionPeriod: 7 - PreferredBackupWindow: "07:00-09:00" - PreferredMaintenanceWindow: "sun:09:00-sun:11:00" - StorageEncrypted: true - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-cluster" - - DocumentDBInstance1: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-1" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-1" - - DocumentDBInstance2: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-2" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-2" - - DocumentDBInstance3: - Type: AWS::DocDB::DBInstance - Properties: - DBClusterIdentifier: !Ref DocumentDBCluster - DBInstanceClass: db.t3.medium - DBInstanceIdentifier: !Sub "${AWS::StackName}-docdb-instance-3" - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-docdb-instance-31" Outputs: VPCId: @@ -896,51 +808,63 @@ Outputs: Value: !Ref 'PublicSubnetOne' Export: Name: !Sub "${AWS::StackName}-PublicSubnetOne" - PrivateSubnetDocDBOne: + PrivateSubnetActiveMQOne: Description: The ID of private subnet one created - Value: !Ref 'PrivateSubnetDocDBOne' + Value: !Ref 'PrivateSubnetActiveMQOne' Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBOne" - PrivateSubnetDocDBTwo: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQOne" + PrivateSubnetActiveMQTwo: Description: The ID of private subnet two created - Value: !Ref 'PrivateSubnetDocDBTwo' + Value: !Ref 'PrivateSubnetActiveMQTwo' Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBTwo" - PrivateSubnetDocDBThree: + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQTwo" + PrivateSubnetActiveMQThree: Description: The ID of private subnet three created - Value: !Ref 'PrivateSubnetDocDBThree' + Value: !Ref 'PrivateSubnetActiveMQThree' Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetDocDBThree" + Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQThree" VPCStackName: Description: The name of the VPC Stack Value: !Ref 'AWS::StackName' Export: Name: !Sub "${AWS::StackName}-VPCStackName" - DocumentDBClusterEndpoint: - Description: DocumentDB Instance-Based Cluster Endpoint - Value: !GetAtt DocumentDBCluster.Endpoint + ActiveMQBrokerEndpoint1: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint1" + ActiveMQBrokerEndpoint2: + Description: ActiveMQ Broker OpenWire Endpoint + Value: !Select [1, !GetAtt ActiveMQBroker.OpenWireEndpoints] + Export: + Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint2" + ActiveMQBrokerConsoleURL: + Description: ActiveMQ Broker Web Console URL + Value: !Sub + - "https://${endpoint}" + - endpoint: !Select [0, !GetAtt ActiveMQBroker.IpAddresses] Export: - Name: !Sub "${AWS::StackName}-DocumentDBClusterEndpoint" - DocumentDBSecretArn: - Description: ARN of the DocumentDB credentials secret - Value: !Ref DocumentDBSecret + Name: !Sub "${AWS::StackName}-ActiveMQBrokerConsoleURL" + ActiveMQSecretArn: + Description: ARN of the ActiveMQ credentials secret + Value: !Ref ActiveMQSecret Export: - Name: !Sub "${AWS::StackName}-DocumentDBSecretArn" + Name: !Sub "${AWS::StackName}-ActiveMQSecretArn" SecurityGroupId: - Description: ID of security group for DocumentDB clients - Value: !GetAtt DocumentDBSecurityGroup.GroupId + Description: ID of security group for ActiveMQ clients + Value: !GetAtt ActiveMQSecurityGroup.GroupId Export: Name: !Sub "${AWS::StackName}-SecurityGroupId" EC2InstanceEndpointID: Description: The ID of the EC2 Instance Endpoint Value: !Ref EC2InstanceEndpoint - DocumentDBDatabaseName: - Description: The Database name to use for the Java Lambda Function - Value: !Ref DocumentDBDatabaseName + ActiveMQBrokerName: + Description: The Broker name to use for the Java Lambda Function + Value: !Ref ActiveMQBrokerName Export: - Name: !Sub "${AWS::StackName}-DocumentDBDatabaseName" - DocumentDBCollectionName: - Description: The Collection name to use for the Java Lambda Function - Value: !Ref DocumentDBCollectionName + Name: !Sub "${AWS::StackName}-ActiveMQBrokerName" + ActiveMQQueueName: + Description: The Queue name to use for the Java Lambda Function + Value: !Ref ActiveMQQueueName Export: - Name: !Sub "${AWS::StackName}-DocumentDBCollectionName" + Name: !Sub "${AWS::StackName}-ActiveMQQueueName" diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml new file mode 100644 index 000000000..dde19f9fe --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -0,0 +1,841 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + LatestAmiId: + Type: 'AWS::SSM::Parameter::Value' + Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' + RabbitMQEngineVersion: + Type: String + Default: 3.13 + Description: RabbitMQ engine version + JavaVersion: + Type: String + Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 + AllowedValues: + - java11 + - java17 + - java21 + Default: java21 + RabbitMQBrokerName: + Type: String + Default: RabbitMQJavaLambdaBroker + Description: RabbitMQ broker name for Lambda function + RabbitMQQueueName: + Type: String + Default: RabbitMQJavaLambdaQueue + Description: RabbitMQ queue name for Lambda function + RabbitMQVirtualHost: + Type: String + Default: RabbitMQVirtualHost + Description: RabbitMQ virtual host name for Lambda function + RabbitMQExchange: + Type: String + Default: RabbitMQExchange + Description: RabbitMQ exchange for Lambda function + RabbitMQBrokerAdminUser: + Type: String + Description: Username for the RabbitMQ Broker + Default: rabbitmqadmin + RabbitMQBrokerPassword: + Type: String + Description: Password for the RabbitMQ Broker + Default: rabbitmqPassword123 + NoEcho: true + ServerlessLandGithubLocation: + Type: String + Default: https://github.com/aws-samples/serverless-patterns.git + Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork + +Mappings: + SubnetConfig: + VPC: + CIDR: '10.2.0.0/16' + PublicOne: + CIDR: '10.2.0.0/24' + PublicTwo: + CIDR: '10.2.1.0/24' + PublicThree: + CIDR: '10.2.2.0/24' + PrivateSubnetRabbitMQOne: + CIDR: '10.2.3.0/24' + PrivateSubnetRabbitMQTwo: + CIDR: '10.2.4.0/24' + PrivateSubnetRabbitMQThree: + CIDR: '10.2.5.0/24' + +Resources: + # Secrets Manager Secret for RabbitMQ credentials + RabbitMQSecret: + Type: AWS::SecretsManager::Secret + Properties: + Name: 'AmazonRabbitMQCredentials' + Description: RabbitMQ broker master user credentials + SecretString: !Sub | + { + "username": "${RabbitMQBrokerAdminUser}", + "password": "${RabbitMQBrokerPassword}" + } + + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + Tags: + - Key: 'Name' + Value: 'RabbitMQVPC' + + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetOne' + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetTwo' + PublicSubnetThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] + MapPublicIpOnLaunch: true + Tags: + - Key: 'Name' + Value: 'PublicSubnetThree' + PrivateSubnetRabbitMQOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetRabbitMQOne', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetRabbitMQOne' + PrivateSubnetRabbitMQTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetRabbitMQTwo', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetRabbitMQTwo' + PrivateSubnetRabbitMQThree: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 2 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetRabbitMQThree', 'CIDR'] + MapPublicIpOnLaunch: false + Tags: + - Key: 'Name' + Value: 'PrivateSubnetRabbitMQThree' + + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + NATEIP1: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP1.AllocationId + SubnetId: !Ref 'PublicSubnetOne' + Tags: + - Key: 'Name' + Value: 'RabbitMQNATGateway1' + + NATEIP2: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP2.AllocationId + SubnetId: !Ref 'PublicSubnetTwo' + Tags: + - Key: 'Name' + Value: 'RabbitMQNATGateway2' + + NATEIP3: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + + NATGateway3: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NATEIP3.AllocationId + SubnetId: !Ref 'PublicSubnetThree' + Tags: + - Key: 'Name' + Value: 'RabbitMQNATGateway3' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + PublicSubnetThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetThree + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute1: + Type: AWS::EC2::Route + DependsOn: NATGateway1 + Properties: + RouteTableId: !Ref 'PrivateRouteTable1' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway1' + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute2: + Type: AWS::EC2::Route + DependsOn: NATGateway2 + Properties: + RouteTableId: !Ref 'PrivateRouteTable2' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway2' + + PrivateRouteTable3: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PrivateRoute3: + Type: AWS::EC2::Route + DependsOn: NATGateway3 + Properties: + RouteTableId: !Ref 'PrivateRouteTable3' + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NATGateway3' + + PrivateSubnetRabbitMQOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnetRabbitMQOne + + PrivateSubnetRabbitMQTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnetRabbitMQTwo + + PrivateSubnetRabbitMQThreeRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable3 + SubnetId: !Ref PrivateSubnetRabbitMQThree + + RabbitMQClientInstanceSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup + GroupName: !Sub "${AWS::StackName} Security group attached to the RabbitMQ client" + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 10.0.0.0/16 + + RabbitMQSecurityGroup: + Type: AWS::EC2::SecurityGroup + DependsOn: [VPC,RabbitMQClientInstanceSecurityGroup] + Properties: + GroupDescription: RabbitMQ Security Group + GroupName: !Sub "${AWS::StackName} Security group for the RabbitMQ broker" + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 5671 + ToPort: 5671 + SourceSecurityGroupId: !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + SourceSecurityGroupId: !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + - IpProtocol: tcp + FromPort: 0 + ToPort: 65535 + CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + + RabbitMQClientSelfIngressAllowRule: + Type: AWS::EC2::SecurityGroupIngress + DependsOn: RabbitMQClientInstanceSecurityGroup + Properties: + GroupId: !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourceSecurityGroupId: !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + + # RabbitMQ Broker + RabbitMQBroker: + Type: AWS::AmazonMQ::Broker + Properties: + BrokerName: !Ref RabbitMQBrokerName + DeploymentMode: CLUSTER_MULTI_AZ + EngineType: RABBITMQ + EngineVersion: !Ref RabbitMQEngineVersion + HostInstanceType: mq.m5.large + PubliclyAccessible: false + AutoMinorVersionUpgrade: true + Users: + - Username: !Ref RabbitMQBrokerAdminUser + Password: !Ref RabbitMQBrokerPassword + ConsoleAccess: true + SubnetIds: + - !Ref PrivateSubnetRabbitMQOne + - !Ref PrivateSubnetRabbitMQTwo + - !Ref PrivateSubnetRabbitMQThree + SecurityGroups: + - !Ref RabbitMQSecurityGroup + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}-rabbitmq-broker" + + RabbitMQClientEC2Instance: + DependsOn: RabbitMQBroker + Type: AWS::EC2::Instance + Properties: + InstanceType: m5.large + IamInstanceProfile: !Ref EC2InstanceProfile + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + SubnetId: !Ref PublicSubnetOne + SecurityGroupIds: [!GetAtt RabbitMQClientInstanceSecurityGroup.GroupId] + ImageId: !Ref LatestAmiId + Tags: + - Key: 'Name' + Value: 'RabbitMQClientInstance' + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: 50 + VolumeType: gp2 + DeleteOnTermination: true + UserData: + Fn::Base64: + !Sub + - | + #!/bin/bash + yum update -y + + # install Java + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum update -y + + # install Java + JAVA_VERSION=${java_version} + echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile + if [ "$JAVA_VERSION" == "java11" ]; then + sudo yum install java-11-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java17" ]; then + sudo yum install java-17-amazon-corretto-devel -y + elif [ "$JAVA_VERSION" == "java21" ]; then + sudo yum install java-21-amazon-corretto-devel -y + else + sudo yum install java-21-amazon-corretto-devel -y + fi + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of Java succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install nmap-ncat -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of nmap succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install git -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of git succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum erase awscli -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum erase of awscli succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + yum install jq -y + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of jq succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y docker + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of docker succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + service docker start + usermod -a -G docker ec2-user + + max_attempts=5 + attempt_num=1 + success=false + while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do + echo "Trying yum install" + sudo yum install -y maven + # Check the exit code of the command + if [ $? -eq 0 ]; then + echo "Yum install of maven succeeded" + success=true + else + echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." + sleep 3 + ((attempt_num++)) + fi + done + + cd /home/ec2-user + su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user + su -c "pip3 install boto3 --user" -s /bin/sh ec2-user + + # install AWS CLI 2 - access with aws2 + cd /home/ec2-user + mkdir -p awscli + cd awscli + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + # Install AWS SAM CLI + cd /home/ec2-user + mkdir -p awssam + cd awssam + wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + unzip aws-sam-cli-linux-x86_64.zip -d sam-installation + sudo ./sam-installation/install + + # Set environment variables + RABBITMQ_BROKER_ID=${rabbitmq_broker_id} + RABBITMQ_BROKER_ARN=${rabbitmq_broker_arn} + RABBITMQ_BROKER_ENDPOINT="${rabbitmq_broker_endpoint}" + RABBITMQ_QUEUE_NAME=${rabbitmq_queue_name} + RABBITMQ_SECRET_ARN=${rabbitmq_secret_arn} + AWS_REGION=${aws_region} + RABBITMQ_SUBNET_ONE=${rabbitmq_subnet_one} + RABBITMQ_SUBNET_TWO=${rabbitmq_subnet_two} + RABBITMQ_SUBNET_THREE=${rabbitmq_subnet_three} + RABBITMQ_SECURITY_GROUP=${rabbitmq_security_group} + RABBITMQ_BROKER_ADMIN_USER=${rabbitmq_broker_admin_user} + RABBITMQ_BROKER_PASSWORD=${rabbitmq_broker_password} + SECURITY_GROUP=${security_group_id} + RABBITMQ_VIRTUAL_HOST=${rabbitmq_virtual_host} + RABBITMQ_EXCHANGE=${rabbitmq_exchange} + + echo "export RABBITMQ_BROKER_ID=$RABBITMQ_BROKER_ID" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_BROKER_ARN=$RABBITMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_BROKER_ENDPOINT=$RABBITMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_QUEUE_NAME=$RABBITMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_VIRTUAL_HOST=$RABBITMQ_VIRTUAL_HOST" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_EXCHANGE=$RABBITMQ_EXCHANGE" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_SECRET_ARN=$RABBITMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile + echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_SUBNET_ONE=$RABBITMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_SUBNET_TWO=$RABBITMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_SUBNET_THREE=$RABBITMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_SECURITY_GROUP=$RABBITMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_BROKER_ADMIN_USER=$RABBITMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile + echo "export RABBITMQ_BROKER_PASSWORD=$RABBITMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + + # Clone serverless patterns + cd /home/ec2-user + SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} + git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION + cd ./serverless-patterns + git sparse-checkout set --no-cone /rabbitmq-private-lambda-java-sam + git checkout + cd rabbitmq-private-lambda-java-sam + sudo chown -R ec2-user . + + #Substitute SAM template variables + cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam + cd rabbitmq_consumer_dynamo_sam + cp template_original.yaml template.yaml + sudo chown -R ec2-user . + source /home/ec2-user/.bash_profile + sed -i "s/RABBITMQ_BROKER_ARN/$RABBITMQ_BROKER_ARN/g" template.yaml + sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" template.yaml + sed -i "s/RABBITMQ_SECRET_ARN/$RABBITMQ_SECRET_ARN/g" template.yaml + sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml + sed -i "s/RABBITMQ_SUBNET_ONE/$RABBITMQ_SUBNET_ONE/g" template.yaml + sed -i "s/RABBITMQ_SUBNET_TWO/$RABBITMQ_SUBNET_TWO/g" template.yaml + sed -i "s/RABBITMQ_SUBNET_THREE/$RABBITMQ_SUBNET_TWO/g" template.yaml + sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + + #Update Shell script for sending RabbitMQ messages to Lambda function + cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json + sudo chown ec2-user ./commands.sh + source /home/ec2-user/.bash_profile + echo "RABBITMQ_BROKER_ENDPOINT=$rabbitmq_broker_endpoint" + sed -i "s|RABBITMQ_BROKER_ENDPOINT|$rabbitmq_broker_endpoint|g" commands.sh + sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" commands.sh + sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" commands.sh + sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" commands.sh + mvn clean install + + # Get IP CIDR range for EC2 Instance Connect + cd /home/ec2-user + mkdir -p ip_prefix + cd ip_prefix + git clone https://github.com/joetek/aws-ip-ranges-json.git + cd aws-ip-ranges-json + AWS_REGION=${aws_region} + EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') + echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile + SECURITY_GROUP=${security_group_id} + echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile + aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP + + - rabbitmq_broker_id: !Ref RabbitMQBroker + rabbitmq_broker_arn: !GetAtt RabbitMQBroker.Arn + rabbitmq_broker_endpoint: !GetAtt RabbitMQBroker.AmqpEndpoints + rabbitmq_virtual_host: !Ref RabbitMQVirtualHost + rabbitmq_exchange: !Ref RabbitMQExchange + rabbitmq_queue_name: !Ref RabbitMQQueueName + rabbitmq_secret_arn: !Ref RabbitMQSecret + serverless_land_github_location: !Ref ServerlessLandGithubLocation + aws_region: !Ref 'AWS::Region' + java_version: !Ref JavaVersion + security_group_id : !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + rabbitmq_subnet_one: !Ref PrivateSubnetRabbitMQOne + rabbitmq_subnet_two: !Ref PrivateSubnetRabbitMQTwo + rabbitmq_subnet_three: !Ref PrivateSubnetRabbitMQThree + rabbitmq_security_group: !GetAtt RabbitMQSecurityGroup.GroupId + rabbitmq_broker_admin_user: !Ref RabbitMQBrokerAdminUser + rabbitmq_broker_password: !Ref RabbitMQBrokerPassword + + EC2InstanceEndpoint: + Type: AWS::EC2::InstanceConnectEndpoint + Properties: + PreserveClientIp: true + SecurityGroupIds: + - !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + SubnetId: !Ref PublicSubnetOne + + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Action: 'sts:AssumeRole' + Path: "/" + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonMQFullAccess + - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore + - arn:aws:iam::aws:policy/AmazonS3FullAccess + - arn:aws:iam::aws:policy/IAMFullAccess + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 + Policies: + - PolicyName: RabbitMQAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "RabbitMQFullAccess", + "Effect": "Allow", + "Action": [ + "mq:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecretsManagerAccess + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:DescribeSecret" + ], + "Resource": "${RabbitMQSecret}" + } + ] + }' + - PolicyName: CloudformationDeploy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*" + ], + "Resource": "*" + } + ] + }' + - PolicyName: SecurityGroupsPolicy + PolicyDocument: !Sub '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupEgress", + "ec2:ModifySecurityGroupRules", + "ec2:UpdateSecurityGroupRuleDescriptionsIngress", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:ModifySecurityGroupRules" + ], + "Resource": [ + "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" + ] + } + ] + }' + + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Join + - '-' + - - 'EC2RabbitMQProfile' + - !Ref 'AWS::StackName' + Roles: + - !Ref EC2Role + +Outputs: + VPCId: + Description: The ID of the VPC created + Value: !Ref 'VPC' + Export: + Name: !Sub "${AWS::StackName}-VPCID" + PublicSubnetOne: + Description: The name of the public subnet created + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Sub "${AWS::StackName}-PublicSubnetOne" + PrivateSubnetRabbitMQOne: + Description: The ID of private subnet one created + Value: !Ref 'PrivateSubnetRabbitMQOne' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetRabbitMQOne" + PrivateSubnetRabbitMQTwo: + Description: The ID of private subnet two created + Value: !Ref 'PrivateSubnetRabbitMQTwo' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetRabbitMQTwo" + PrivateSubnetRabbitMQThree: + Description: The ID of private subnet three created + Value: !Ref 'PrivateSubnetRabbitMQThree' + Export: + Name: !Sub "${AWS::StackName}-PrivateSubnetRabbitMQThree" + VPCStackName: + Description: The name of the VPC Stack + Value: !Ref 'AWS::StackName' + Export: + Name: !Sub "${AWS::StackName}-VPCStackName" + RabbitMQBrokerEndpoint: + Description: RabbitMQ Broker AMQP Endpoint + Value: !GetAtt RabbitMQBroker.AmqpEndpoints + Export: + Name: !Sub "${AWS::StackName}-RabbitMQBrokerEndpoint" + RabbitMQSecretArn: + Description: ARN of the RabbitMQ credentials secret + Value: !Ref RabbitMQSecret + Export: + Name: !Sub "${AWS::StackName}-RabbitMQSecretArn" + SecurityGroupId: + Description: ID of security group for RabbitMQ clients + Value: !GetAtt RabbitMQSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-SecurityGroupId" + EC2InstanceEndpointID: + Description: The ID of the EC2 Instance Endpoint + Value: !Ref EC2InstanceEndpoint + RabbitMQBrokerName: + Description: The Broker name to use for the Java Lambda Function + Value: !Ref RabbitMQBrokerName + Export: + Name: !Sub "${AWS::StackName}-RabbitMQBrokerName" + RabbitMQQueueName: + Description: The Queue name to use for the Java Lambda Function + Value: !Ref RabbitMQQueueName + Export: + Name: !Sub "${AWS::StackName}-RabbitMQQueueName" diff --git a/rabbitmq-private-lambda-java-sam/example-pattern.json b/rabbitmq-private-lambda-java-sam/example-pattern.json new file mode 100644 index 000000000..5eb3fb455 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/example-pattern.json @@ -0,0 +1,93 @@ +{ + "title": "AWS Lambda function subscribed to an Amazon MQ - Apache ActiveMQ in private subnets (Java)", + "description": "Creates a Lambda function that uses a private Amazon MQ (Apache ActiveMQ) as an event source.", + "language": "Java", + "level": "200", + "framework": "AWS SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern provides a Lambda function along with an Event Source Mapping to an Amazon MQ (Apache ActiveMQ) queue.", + "The CloudFormation template provided in this pattern installs an Amazon MQ (Apache ActiveMQ) Cluster in private subnets in a VPC.", + "For detailed deployment instructions instructions see the README.md" + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/activemq-private-lambda-java-sam", + "templateURL": "serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam", + "projectFolder": "activemq-private-lambda-java-sam", + "templateFile": "template_original.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "Configuring Amazon MQ event source for Lambda", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/process-mq-messages-with-lambda.html" + }, + { + "text": "Using Lambda with Amazon MQ", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html" + }, + { + "text": "Amazon MQ resource type reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/AWS_AmazonMQ.html" + } + ] + }, + "deploy": { + "text": [ + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the template: sam delete." + ] + }, + "authors": [ + { + "name": "Indranil Banerjee", + "bio": "AWS - Senior Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C5603AQEL3BG6JZca6A/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1653972622784?e=1762992000&v=beta&t=a9gnmtxyWBhfEfqDF3HiPHWDoc4KZjG2sdNsIakcJXw", + "linkedin": "https://www.linkedin.com/in/indranil-banerjee-b00a261/" + }, + { + "name": "Arghya Banerjee", + "bio": "AWS - Senior Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C5603AQHFFKivT-1iKA/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1516305772138?e=1762992000&v=beta&t=dKgoxEfgZd3M5XW-GEJ9Ss4I5ka8-C7iEIy8Sb_PTOQ", + "linkedin": "https://www.linkedin.com/in/arghya-b-6130b57/" + }, + { + "name": "Kunal Ghosh", + "bio": "AWS - Sr SA, Strategic Accounts", + "image": "https://media.licdn.com/dms/image/v2/C5603AQHrj7mHd7Z1hg/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1516355158121?e=1762992000&v=beta&t=8h0cpHLR6v4-e3BJ7n9Wd_OHL2rRDa8F_74rTUnu8Js", + "linkedin": "https://www.linkedin.com/in/kunal-ghosh-6583058/" + }, + { + "name": "Angelo Spagnolo", + "bio": "AWS - Sr Technical Account Manager", + "image": "https://media.licdn.com/dms/image/v2/D5603AQFQj2a90KFFZQ/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1692659294509?e=1762992000&v=beta&t=gEfdRLVzNPXGZ9-5EZKA358NBf4F7VBcVthyWSrzjrs", + "linkedin": "https://www.linkedin.com/in/aspagnolo/" + }, + { + "name": "Vinayak Datar", + "bio": "AWS - Sr. Customer Solutions Manager", + "image": "https://media.licdn.com/dms/image/v2/C5103AQFAa6JcLNknkA/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1548189034877?e=1762992000&v=beta&t=o2lDqU3V4ivFjt00rEDYd2yjGr55TszcG0J9hGuRM_w", + "linkedin": "https://www.linkedin.com/in/vinayakdatar/" + }, + { + "name": "Greg Medard", + "bio": "AWS - Solutions Architect", + "image": "https://media.licdn.com/dms/image/v2/C4E03AQGveSDnRH9aCg/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1565226836063?e=1762992000&v=beta&t=Jkir-cq-T1EU8MTqY7PPPxreVo2_zI4FXaXXrdTdpfQ", + "linkedin": "https://www.linkedin.com/in/gregorymedard/" + } + ] + } + \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml similarity index 81% rename from rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml rename to rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml index aaf29d21d..fe049c359 100755 --- a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template.yaml +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml @@ -38,14 +38,12 @@ Resources: Properties: BatchSize: 10 MaximumBatchingWindowInSeconds: 5 - Broker: - !Join ['', ["arn:", "aws:", "mq:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "broker:", !Ref RabbitMQBrokerName, ":", !Ref RabbitMQBrokerUniqueString]] + Broker: !Ref RabbitMQBrokerArn Queues: - !Ref RabbitMQQueue SourceAccessConfigurations: - Type: BASIC_AUTH - URI: - !Join ['', ["arn:", "aws:", "secretsmanager:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "secret:", !Ref SecretsManagerSecretForMQName, "-", !Ref SecretsManagerSecretForMQUniqueString]] + URI: !Ref SecretsManagerSecretForMQ - Type: VIRTUAL_HOST URI: !Ref RabbitMQVirtualHost @@ -92,36 +90,38 @@ Resources: Name: MessageID Type: String Parameters: - RabbitMQBrokerName: + RabbitMQBrokerArn: Type: String - Description: Enter the name of the RabbitMQBroker that is part of the ARN - RabbitMQBrokerUniqueString: - Type: String - Description: Enter the unique string of the RabbitMQBroker after the broker name in the ARN + Description: Enter the ARN of the ActiveMQBroker + Default: RABBITMQ_BROKER_ARN RabbitMQVirtualHost: Type: String Description: Enter the name of the RabbitMQ virtualhost from which the lambda function will consume messages + Default: RABBITMQ_VIRTUAL_HOST RabbitMQQueue: Type: String Description: Enter the name of the RabbitMQ queue from which the lambda function will consume messages - SecretsManagerSecretForMQName: - Type: String - Description: Enter the name of the secret that has username/password for Rabbit MQ - SecretsManagerSecretForMQUniqueString: + Default: RABBITMQ_QUEUE_NAME + SecretsManagerSecretForMQ: Type: String - Description: Enter the unique string of the secret that has username/password for Rabbit MQ + Description: Enter the ARN of the secret that has username/password for Rabbit MQ + Default: RABBITMQ_SECRET_ARN Subnet1: Type: String Description: The first of the three private subnets in the RabbitMQ broker's VPC + Default: RABBITMQ_SUBNET_ONE Subnet2: Type: String Description: The second of the three private subnets in the RabbitMQ broker's VPC + Default: RABBITMQ_SUBNET_TWO Subnet3: Type: String Description: The third of the three private subnets in the RabbitMQ broker's VPC + Default: Default: RABBITMQ_SUBNET_THREE SecurityGroup: Type: String Description: The security group associated with this function (use same RabbitMQ) + Default: RABBITMQ_SECURITY_GROUP Outputs: LambdaRabbitMQConsumerJavaFunction: Description: "Queue Consumer Lambda Function ARN" diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh new file mode 100755 index 000000000..7d854c3f8 --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Pass a random string as the first command-line argument to this shell script. It will be used to uniquely identify a batch of messages +# Pass an integer as the second command-line argument to this shell script < 500. For example if you want to send 100 messages, pass 100 +# Example sh commands.sh firstbatch 100 + +java -classpath /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/target/json-rabbitmq-producer-0.0.1-SNAPSHOT.jar rabbitmq.producer.JsonRabbitMQProducer RABBITMQ_BROKER_ENDPOINT RABBITMQ_VIRTUAL_HOST RABBITMQ_EXCHANGE RABBITMQ_QUEUE_NAME $1 $2 \ No newline at end of file From f38ba2d2a08a4150d57fef89d916bc079dceb535 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Mon, 20 Oct 2025 23:52:35 -0700 Subject: [PATCH 11/18] Fixed RabbitMQ Private Lambda Java SAM Project CFT --- rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml index dde19f9fe..66933749f 100644 --- a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -642,7 +642,7 @@ Resources: - rabbitmq_broker_id: !Ref RabbitMQBroker rabbitmq_broker_arn: !GetAtt RabbitMQBroker.Arn - rabbitmq_broker_endpoint: !GetAtt RabbitMQBroker.AmqpEndpoints + rabbitmq_broker_endpoint: !Select [ 0, !GetAtt RabbitMQBroker.AmqpEndpoints ] rabbitmq_virtual_host: !Ref RabbitMQVirtualHost rabbitmq_exchange: !Ref RabbitMQExchange rabbitmq_queue_name: !Ref RabbitMQQueueName @@ -813,7 +813,7 @@ Outputs: Name: !Sub "${AWS::StackName}-VPCStackName" RabbitMQBrokerEndpoint: Description: RabbitMQ Broker AMQP Endpoint - Value: !GetAtt RabbitMQBroker.AmqpEndpoints + Value: !Select [ 0, !GetAtt RabbitMQBroker.AmqpEndpoints ] Export: Name: !Sub "${AWS::StackName}-RabbitMQBrokerEndpoint" RabbitMQSecretArn: From fc844341014c881852c5fed003973a811b850ef8 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Tue, 21 Oct 2025 23:30:53 -0700 Subject: [PATCH 12/18] Fixed RabbitMQ Private Lambda Java SAM Project --- .../create_rabbit_queue.sh | 9 ++++ .../RabbitMQAndClientEC2.yaml | 42 ++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 rabbitmq-lambda-sam-java/create_rabbit_queue.sh diff --git a/rabbitmq-lambda-sam-java/create_rabbit_queue.sh b/rabbitmq-lambda-sam-java/create_rabbit_queue.sh new file mode 100644 index 000000000..63a5508a5 --- /dev/null +++ b/rabbitmq-lambda-sam-java/create_rabbit_queue.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT RABBITMQ_HTTPS_BROKER_ENDPOINT/api/vhosts/RABBITMQ_VIRTUAL_HOST + +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"type": "fanout", "durable": true, "auto_delete": false, "internal": false}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/exchanges/RABBITMQ_VIRTUAL_HOST/RABBITMQ_EXCHANGE + +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"durable": true, "auto_delete": false}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/queues/RABBITMQ_VIRTUAL_HOST/RABBITMQ_QUEUE_NAME + +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X POST -H "Content-type: application/json" -d '{"routing_key": "RABBITMQ_EXCHANGE-RABBITMQ_QUEUE_NAME"}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/bindings/RABBITMQ_VIRTUAL_HOST/e/RABBITMQ_EXCHANGE/q/RABBITMQ_QUEUE_NAME \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml index 66933749f..a2706e430 100644 --- a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -561,7 +561,6 @@ Resources: # Set environment variables RABBITMQ_BROKER_ID=${rabbitmq_broker_id} RABBITMQ_BROKER_ARN=${rabbitmq_broker_arn} - RABBITMQ_BROKER_ENDPOINT="${rabbitmq_broker_endpoint}" RABBITMQ_QUEUE_NAME=${rabbitmq_queue_name} RABBITMQ_SECRET_ARN=${rabbitmq_secret_arn} AWS_REGION=${aws_region} @@ -577,7 +576,6 @@ Resources: echo "export RABBITMQ_BROKER_ID=$RABBITMQ_BROKER_ID" >> /home/ec2-user/.bash_profile echo "export RABBITMQ_BROKER_ARN=$RABBITMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - echo "export RABBITMQ_BROKER_ENDPOINT=$RABBITMQ_BROKER_ENDPOINT" >> /home/ec2-user/.bash_profile echo "export RABBITMQ_QUEUE_NAME=$RABBITMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile echo "export RABBITMQ_VIRTUAL_HOST=$RABBITMQ_VIRTUAL_HOST" >> /home/ec2-user/.bash_profile echo "export RABBITMQ_EXCHANGE=$RABBITMQ_EXCHANGE" >> /home/ec2-user/.bash_profile @@ -609,24 +607,56 @@ Resources: source /home/ec2-user/.bash_profile sed -i "s/RABBITMQ_BROKER_ARN/$RABBITMQ_BROKER_ARN/g" template.yaml sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" template.yaml + sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" template.yaml sed -i "s/RABBITMQ_SECRET_ARN/$RABBITMQ_SECRET_ARN/g" template.yaml sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml sed -i "s/RABBITMQ_SUBNET_ONE/$RABBITMQ_SUBNET_ONE/g" template.yaml sed -i "s/RABBITMQ_SUBNET_TWO/$RABBITMQ_SUBNET_TWO/g" template.yaml - sed -i "s/RABBITMQ_SUBNET_THREE/$RABBITMQ_SUBNET_TWO/g" template.yaml + sed -i "s/RABBITMQ_SUBNET_THREE/$RABBITMQ_SUBNET_THREE/g" template.yaml sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml + original_broker_endpoint="${rabbitmq_broker_endpoint}" + + amqps_prefix="amqps://" + + # Remove the prefix from the beginning of the string + broker_endpoint_without_amqps="${original_broker_endpoint#$amqps_prefix}" + + # Print the result + echo "original_broker_endpoint: $original_broker_endpoint" + echo "broker_endpoint_without_amqps: $broker_endpoint_without_amqps" + + suffix=":5671" + broker_endpoint_without_port="${broker_endpoint_without_amqps%${suffix}}" + echo "broker_endpoint_without_port: $broker_endpoint_without_port" + + https_prefix="https://" + + rabbitmq_https_broker_endpoint="$https_prefix$broker_endpoint_without_port" + echo "rabbitmq_https_broker_endpoint=$rabbitmq_https_broker_endpoint" + #Update Shell script for sending RabbitMQ messages to Lambda function cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json sudo chown ec2-user ./commands.sh source /home/ec2-user/.bash_profile - echo "RABBITMQ_BROKER_ENDPOINT=$rabbitmq_broker_endpoint" - sed -i "s|RABBITMQ_BROKER_ENDPOINT|$rabbitmq_broker_endpoint|g" commands.sh + echo "RABBITMQ_BROKER_ENDPOINT=${rabbitmq_broker_endpoint}" + sed -i "s|RABBITMQ_BROKER_ENDPOINT|$broker_endpoint_without_port|g" commands.sh sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" commands.sh sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" commands.sh sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" commands.sh mvn clean install - + + #Create RabbitMQ Exchange and Queue and link queue to exchange + cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam + sudo chown ec2-user ./create_rabbit_queue.sh + source /home/ec2-user/.bash_profile + sed -i "s|RABBITMQ_HTTPS_BROKER_ENDPOINT|$rabbitmq_https_broker_endpoint|g" create_rabbit_queue.sh + sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" create_rabbit_queue.sh + sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" create_rabbit_queue.sh + sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" create_rabbit_queue.sh + sed -i "s/RABBITMQ_BROKER_ADMIN_USER/$RABBITMQ_BROKER_ADMIN_USER/g" create_rabbit_queue.sh + sed -i "s/RABBITMQ_BROKER_PASSWORD/$RABBITMQ_BROKER_PASSWORD/g" create_rabbit_queue.sh + # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user mkdir -p ip_prefix From cd173365002cc6d4a3f3a9465ddd4066baf09e53 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Wed, 22 Oct 2025 07:58:02 -0700 Subject: [PATCH 13/18] Fixed RabbitMQ Private Lambda Java SAM Project CFT --- .../create_rabbit_queue.sh | 28 ++++++++++++++++--- .../RabbitMQAndClientEC2.yaml | 26 ++--------------- .../rabbitmq_message_sender_json/commands.sh | 18 +++++++++++- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/rabbitmq-lambda-sam-java/create_rabbit_queue.sh b/rabbitmq-lambda-sam-java/create_rabbit_queue.sh index 63a5508a5..dfe49b0b4 100644 --- a/rabbitmq-lambda-sam-java/create_rabbit_queue.sh +++ b/rabbitmq-lambda-sam-java/create_rabbit_queue.sh @@ -1,9 +1,29 @@ #!/bin/bash -curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT RABBITMQ_HTTPS_BROKER_ENDPOINT/api/vhosts/RABBITMQ_VIRTUAL_HOST +original_broker_endpoint="RABBITMQ_BROKER_ENDPOINT" + +amqps_prefix="amqps://" + +# Remove the prefix from the beginning of the string +broker_endpoint_without_amqps="${original_broker_endpoint#$amqps_prefix}" + +# Print the result +echo "original_broker_endpoint: $original_broker_endpoint" +echo "broker_endpoint_without_amqps: $broker_endpoint_without_amqps" + +port_suffix=":5671" +broker_endpoint_without_port="${broker_endpoint_without_amqps%${port_suffix}}" +echo "broker_endpoint_without_port: $broker_endpoint_without_port" + +https_prefix="https://" + +rabbitmq_https_broker_endpoint="$https_prefix$broker_endpoint_without_port" +echo "rabbitmq_https_broker_endpoint=$rabbitmq_https_broker_endpoint" + +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT $rabbitmq_https_broker_endpoint/api/vhosts/RABBITMQ_VIRTUAL_HOST -curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"type": "fanout", "durable": true, "auto_delete": false, "internal": false}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/exchanges/RABBITMQ_VIRTUAL_HOST/RABBITMQ_EXCHANGE +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"type": "fanout", "durable": true, "auto_delete": false, "internal": false}' $rabbitmq_https_broker_endpoint/api/exchanges/RABBITMQ_VIRTUAL_HOST/RABBITMQ_EXCHANGE -curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"durable": true, "auto_delete": false}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/queues/RABBITMQ_VIRTUAL_HOST/RABBITMQ_QUEUE_NAME +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X PUT -H "Content-type: application/json" -d '{"durable": true, "auto_delete": false}' $rabbitmq_https_broker_endpoint/api/queues/RABBITMQ_VIRTUAL_HOST/RABBITMQ_QUEUE_NAME -curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X POST -H "Content-type: application/json" -d '{"routing_key": "RABBITMQ_EXCHANGE-RABBITMQ_QUEUE_NAME"}' RABBITMQ_HTTPS_BROKER_ENDPOINT/api/bindings/RABBITMQ_VIRTUAL_HOST/e/RABBITMQ_EXCHANGE/q/RABBITMQ_QUEUE_NAME \ No newline at end of file +curl -i -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -X POST -H "Content-type: application/json" -d '{"routing_key": "RABBITMQ_EXCHANGE-RABBITMQ_QUEUE_NAME"}' $rabbitmq_https_broker_endpoint/api/bindings/RABBITMQ_VIRTUAL_HOST/e/RABBITMQ_EXCHANGE/q/RABBITMQ_QUEUE_NAME \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml index a2706e430..43a900e1e 100644 --- a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -614,33 +614,13 @@ Resources: sed -i "s/RABBITMQ_SUBNET_TWO/$RABBITMQ_SUBNET_TWO/g" template.yaml sed -i "s/RABBITMQ_SUBNET_THREE/$RABBITMQ_SUBNET_THREE/g" template.yaml sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml - - original_broker_endpoint="${rabbitmq_broker_endpoint}" - - amqps_prefix="amqps://" - - # Remove the prefix from the beginning of the string - broker_endpoint_without_amqps="${original_broker_endpoint#$amqps_prefix}" - - # Print the result - echo "original_broker_endpoint: $original_broker_endpoint" - echo "broker_endpoint_without_amqps: $broker_endpoint_without_amqps" - - suffix=":5671" - broker_endpoint_without_port="${broker_endpoint_without_amqps%${suffix}}" - echo "broker_endpoint_without_port: $broker_endpoint_without_port" - - https_prefix="https://" - - rabbitmq_https_broker_endpoint="$https_prefix$broker_endpoint_without_port" - echo "rabbitmq_https_broker_endpoint=$rabbitmq_https_broker_endpoint" - + #Update Shell script for sending RabbitMQ messages to Lambda function cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json sudo chown ec2-user ./commands.sh source /home/ec2-user/.bash_profile echo "RABBITMQ_BROKER_ENDPOINT=${rabbitmq_broker_endpoint}" - sed -i "s|RABBITMQ_BROKER_ENDPOINT|$broker_endpoint_without_port|g" commands.sh + sed -i "s|RABBITMQ_BROKER_ENDPOINT|${rabbitmq_broker_endpoint}|g" commands.sh sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" commands.sh sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" commands.sh sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" commands.sh @@ -650,7 +630,7 @@ Resources: cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam sudo chown ec2-user ./create_rabbit_queue.sh source /home/ec2-user/.bash_profile - sed -i "s|RABBITMQ_HTTPS_BROKER_ENDPOINT|$rabbitmq_https_broker_endpoint|g" create_rabbit_queue.sh + sed -i "s|RABBITMQ_BROKER_ENDPOINT|${rabbitmq_broker_endpoint}|g" create_rabbit_queue.sh sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" create_rabbit_queue.sh sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" create_rabbit_queue.sh sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" create_rabbit_queue.sh diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh index 7d854c3f8..a40e46864 100755 --- a/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/commands.sh @@ -4,4 +4,20 @@ # Pass an integer as the second command-line argument to this shell script < 500. For example if you want to send 100 messages, pass 100 # Example sh commands.sh firstbatch 100 -java -classpath /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/target/json-rabbitmq-producer-0.0.1-SNAPSHOT.jar rabbitmq.producer.JsonRabbitMQProducer RABBITMQ_BROKER_ENDPOINT RABBITMQ_VIRTUAL_HOST RABBITMQ_EXCHANGE RABBITMQ_QUEUE_NAME $1 $2 \ No newline at end of file +original_broker_endpoint="RABBITMQ_BROKER_ENDPOINT" + +amqps_prefix="amqps://" + +# Remove the prefix from the beginning of the string +broker_endpoint_without_amqps="${original_broker_endpoint#$amqps_prefix}" + +# Print the result +echo "original_broker_endpoint: $original_broker_endpoint" +echo "broker_endpoint_without_amqps: $broker_endpoint_without_amqps" + +port_suffix=":5671" +broker_endpoint_without_port="${broker_endpoint_without_amqps%${port_suffix}}" +echo "broker_endpoint_without_port: $broker_endpoint_without_port" + + +java -classpath /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_message_sender_json/target/json-rabbitmq-producer-0.0.1-SNAPSHOT.jar rabbitmq.producer.JsonRabbitMQProducer $broker_endpoint_without_port RABBITMQ_VIRTUAL_HOST RABBITMQ_EXCHANGE RABBITMQ_QUEUE_NAME $1 $2 \ No newline at end of file From 7c5328ae4921a746cc82db4adc9442050d4dd6c0 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Wed, 22 Oct 2025 09:37:18 -0700 Subject: [PATCH 14/18] Fixed RabbitMQ Private Lambda Java SAM Project CFT --- .../create_rabbit_queue.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {rabbitmq-lambda-sam-java => rabbitmq-private-lambda-java-sam}/create_rabbit_queue.sh (100%) diff --git a/rabbitmq-lambda-sam-java/create_rabbit_queue.sh b/rabbitmq-private-lambda-java-sam/create_rabbit_queue.sh similarity index 100% rename from rabbitmq-lambda-sam-java/create_rabbit_queue.sh rename to rabbitmq-private-lambda-java-sam/create_rabbit_queue.sh From 7442d2d3fd5179b874b15e4b030d0ba03a3c8912 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Wed, 22 Oct 2025 13:13:00 -0700 Subject: [PATCH 15/18] Fixed CloudFormation template for RabbitMQ Private Lambda Java SAM Project --- rabbitmq-private-lambda-java-sam/README.md | 182 +++++++++++++++++- .../RabbitMQAndClientEC2.yaml | 7 + .../template_original.yaml | 4 +- 3 files changed, 189 insertions(+), 4 deletions(-) diff --git a/rabbitmq-private-lambda-java-sam/README.md b/rabbitmq-private-lambda-java-sam/README.md index 09aa4d870..15cb877ec 100755 --- a/rabbitmq-private-lambda-java-sam/README.md +++ b/rabbitmq-private-lambda-java-sam/README.md @@ -1,2 +1,180 @@ -# javaRabbitMQLambdaDynamoDB -Java samples for RabbitMQ --> Lambda --> DynamoDB +# rabbitmq-private-lambda-java-sam +# Java AWS Lambda DocumentDB Streams consumer, using AWS SAM + +This pattern is an example of a Lambda function written in Java that consumes messages from Amazon MQ (Apache ActiveMQ) + +This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. + +- activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java - Code for the application's Lambda function that will listen for Amazon MQ (Apache ActiveMQ) messages and write them to a DynamoDB table +- activemq_message_sender_json/src/main/java - Code for publishing messages with JSON payload into an Amazon MQ (ActiveMQ cluster), that will in turn be consumed by the Lambda function +- activemq_consumer_dynamo_sam/template_original.yaml - A template that defines the application's Lambda function to be used by SAM to deploy the lambda function +- ActiveMQAndClientEC2.yaml - A Cloudformation template file that can be used to deploy an Amazon MQ (Apache ActiveMQ) cluster and also deploy an EC2 machine with all pre-requisities already installed, so you can directly build and deploy the lambda function and test it out. +- activemq_queue_browser.sh - A shell script that can be used to connect to the Amazon MQ (Apache ActiveMQ) brokers using the activemq command-line tool + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. + +## Run the Cloudformation template to create the Amazon MQ (Apache ActiveMQ) Cluster and Client EC2 machine + +* [Run the Cloudformation template using the file ActiveMQAndClientEC2.yaml] - You can go to the AWS Cloudformation console, create a new stack by specifying the template file. You can keep the defaults for input parameters or modify them as necessary. Wait for the Cloudformation stack to be created. This Cloudformation template will create an Amazon MQ (Apache ActiveMQ) cluster. It will also create an EC2 machine that you can use as a client. + +* [Connect to the EC2 machine] - Once the CloudFormation stack is created, you can go to the EC2 console and log into the machine using either "Connect using EC2 Instance Connect" or "Connect using EC2 Instance Connect Endpoint" option under the "EC2 Instance Connect" tab. +Note: You may need to wait for some time after the CloudFormation stack is created, as some UserData scripts continue running after the Cloudformation stack shows Created. + +## Pre-requisites to Deploy the sample Lambda function + +The EC2 machine that was created by running the CloudFormation template has all the software that will be needed to deploy the Lambda function. + +The AWS SAM CLI is a serverless tool for building and testing Lambda applications. + +* Java - On the EC2 machine, we have installed the version of Java that you selected. We have installed Amazon Corrretto JDK of the version that you had selected at the time of specifying the input parameters in the Cloudformation template. At the time of publishing this pattern, only Java versions 11, 17 and 21 are supported by AWS SAM +* Maven - On the EC2 machine, we have installed Maven (https://maven.apache.org/install.html) +* AWS SAM CLI - We have installed the AWS SAM CLI (https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) + +We have also cloned the Github repository for serverless-patterns on the EC2 machine already by running the below command + ``` + git clone https://github.com/aws-samples/serverless-patterns.git + ``` +Change directory to the pattern directory: + ``` + cd serverless-patterns/activemq-private-lambda-java-sam + ``` + +## Use the SAM CLI to build and deploy the lambda function + +Build your application with the `sam build` command. + +```bash +cd activemq_consumer_dynamo_sam +sam build +``` + +The SAM CLI installs dependencies defined in `documentdb_streams_consumer_dynamo_sam/documentdb_streams_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. + +``` + +## Test the build locally + +Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project. + +Run functions locally and invoke them with the `sam local invoke` command. + +```bash +sam local invoke --event events/event.json +``` + +You should see a response such as the below: + +``` +***** Begin sam local invoke response ***** + +Invoking com.amazonaws.services.lambda.samples.events.rabbitmq.HandlerRabbitMQ::handleRequest (java21) +Local image is up-to-date +Using local image: public.ecr.aws/lambda/java:21-rapid-x86_64. + +Mounting +/home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/.aws-sam/build/LambdaRabbitMQConsumerJavaFunction as +/var/task:ro,delegated, inside runtime container +SAM_CONTAINER_ID: 17589682ce0fd9b8172a1cd21fc5bccabb75ba4b27a0be58996c78e4ae7d3341 +Picked up JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 +Begin Event *************{"eventSource":"aws:rmq","eventSourceArn":"arn:aws:mq:us-west-2:664251831272:broker:ib-rabbitmq-broker:b-22450561-3f76-4004-813d-392346f054fe","rmqMessagesByQueue":{"LambdaRabbitMQQueue::/":[{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":1,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-1","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:1","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":321},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9"},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":2,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-2","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:2","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":297},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJBcnQiLCJsYXN0bmFtZSI6IlZlbmVyZSIsImNvbXBhbnkiOiJcIkNoZW1lbCwgSmFtZXMgTCBDcGFcIiIsInN0cmVldCI6IjggVyBDZXJyaXRvcyBBdmUgIzU0IiwiY2l0eSI6IkJyaWRnZXBvcnQiLCJjb3VudHkiOiJHbG91Y2VzdGVyIiwic3RhdGUiOiJOSiIsInppcCI6IjgwMTQiLCJob21lUGhvbmUiOiI4NTYtNjM2LTg3NDkiLCJjZWxsUGhvbmUiOiI4NTYtMjY0LTQxMzAiLCJlbWFpbCI6ImFydEB2ZW5lcmUub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuY2hlbWVsamFtZXNsY3BhLmNvbSJ9"},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":3,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-3","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:3","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":302},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0="},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":4,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-4","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:4","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":295},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJEb25ldHRlIiwibGFzdG5hbWUiOiJGb2xsZXIiLCJjb21wYW55IjoiUHJpbnRpbmcgRGltZW5zaW9ucyIsInN0cmVldCI6IjM0IENlbnRlciBTdCIsImNpdHkiOiJIYW1pbHRvbiIsImNvdW50eSI6IkJ1dGxlciIsInN0YXRlIjoiT0giLCJ6aXAiOiI0NTAxMSIsImhvbWVQaG9uZSI6IjUxMy01NzAtMTg5MyIsImNlbGxQaG9uZSI6IjUxMy01NDktNDU2MSIsImVtYWlsIjoiZG9uZXR0ZS5mb2xsZXJAY294Lm5ldCIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnByaW50aW5nZGltZW5zaW9ucy5jb20ifQ=="},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":5,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-5","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:5","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":292},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJTaW1vbmEiLCJsYXN0bmFtZSI6Ik1vcmFzY2EiLCJjb21wYW55IjoiXCJDaGFwbWFuLCBSb3NzIEUgRXNxXCIiLCJzdHJlZXQiOiIzIE1jYXVsZXkgRHIiLCJjaXR5IjoiQXNobGFuZCIsImNvdW50eSI6IkFzaGxhbmQiLCJzdGF0ZSI6Ik9IIiwiemlwIjoiNDQ4MDUiLCJob21lUGhvbmUiOiI0MTktNTAzLTI0ODQiLCJjZWxsUGhvbmUiOiI0MTktODAwLTY3NTkiLCJlbWFpbCI6InNpbW9uYUBtb3Jhc2NhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYXBtYW5yb3NzZWVzcS5jb20ifQ=="},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":6,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-6","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:6","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":289},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJNaXRzdWUiLCJsYXN0bmFtZSI6IlRvbGxuZXIiLCJjb21wYW55IjoiTW9ybG9uZyBBc3NvY2lhdGVzIiwic3RyZWV0IjoiNyBFYWRzIFN0IiwiY2l0eSI6IkNoaWNhZ28iLCJjb3VudHkiOiJDb29rIiwic3RhdGUiOiJJTCIsInppcCI6IjYwNjMyIiwiaG9tZVBob25lIjoiNzczLTU3My02OTE0IiwiY2VsbFBob25lIjoiNzczLTkyNC04NTY1IiwiZW1haWwiOiJtaXRzdWVfdG9sbG5lckB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tb3Jsb25nYXNzb2NpYXRlcy5jb20ifQ=="},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":7,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-7","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:7","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":293},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJMZW90YSIsImxhc3RuYW1lIjoiRGlsbGlhcmQiLCJjb21wYW55IjoiQ29tbWVyY2lhbCBQcmVzcyIsInN0cmVldCI6IjcgVyBKYWNrc29uIEJsdmQiLCJjaXR5IjoiU2FuIEpvc2UiLCJjb3VudHkiOiJTYW50YSBDbGFyYSIsInN0YXRlIjoiQ0EiLCJ6aXAiOiI5NTExMSIsImhvbWVQaG9uZSI6IjQwOC03NTItMzUwMCIsImNlbGxQaG9uZSI6IjQwOC04MTMtMTEwNSIsImVtYWlsIjoibGVvdGFAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5jb21tZXJjaWFscHJlc3MuY29tIn0="},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":8,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-8","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:8","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":309},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJTYWdlIiwibGFzdG5hbWUiOiJXaWVzZXIiLCJjb21wYW55IjoiVHJ1aGxhciBBbmQgVHJ1aGxhciBBdHR5cyIsInN0cmVldCI6IjUgQm9zdG9uIEF2ZSAjODgiLCJjaXR5IjoiU2lvdXggRmFsbHMiLCJjb3VudHkiOiJNaW5uZWhhaGEiLCJzdGF0ZSI6IlNEIiwiemlwIjoiNTcxMDUiLCJob21lUGhvbmUiOiI2MDUtNDE0LTIxNDciLCJjZWxsUGhvbmUiOiI2MDUtNzk0LTQ4OTUiLCJlbWFpbCI6InNhZ2Vfd2llc2VyQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy50cnVobGFyYW5kdHJ1aGxhcmF0dHlzLmNvbSJ9"},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":9,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-9","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:9","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":312},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJLcmlzIiwibGFzdG5hbWUiOiJNYXJyaWVyIiwiY29tcGFueSI6IlwiS2luZywgQ2hyaXN0b3BoZXIgQSBFc3FcIiIsInN0cmVldCI6IjIyOCBSdW5hbXVjayBQbCAjMjgwOCIsImNpdHkiOiJCYWx0aW1vcmUiLCJjb3VudHkiOiJCYWx0aW1vcmUgQ2l0eSIsInN0YXRlIjoiTUQiLCJ6aXAiOiIyMTIyNCIsImhvbWVQaG9uZSI6IjQxMC02NTUtODcyMyIsImNlbGxQaG9uZSI6IjQxMC04MDQtNDY5NCIsImVtYWlsIjoia3Jpc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5raW5nY2hyaXN0b3BoZXJhZXNxLmNvbSJ9"},{"basicProperties":{"contentType":"text/plain","contentEncoding":"UTF-8","headers":{"MessageNumberInBatch":10,"MessageBatchIdentifier":{"bytes":[84,101,115,116,77,101,115,115,97,103,101,48,51,45,48,55,45,48,50,45,50,48,50,51,45,48,49,45,48,55,45,50,48]}},"deliveryMode":2,"priority":1,"correlationId":"TestMessage03-07-02-2023-01-07-20-10","replyTo":null,"expiration":60000,"messageId":"TestMessage03-07-02-2023-01-07-20:10","timestamp":"Jul 2, 2023, 1:30:34 AM","type":"JsonRabbitMQProducer","userId":"admin","appId":"rabbitmq.producer.JsonRabbitMQProducer","clusterId":"b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.com","bodySize":300},"redelivered":false,"data":"eyJmaXJzdG5hbWUiOiJNaW5uYSIsImxhc3RuYW1lIjoiQW1pZ29uIiwiY29tcGFueSI6IlwiRG9ybCwgSmFtZXMgSiBFc3FcIiIsInN0cmVldCI6IjIzNzEgSmVycm9sZCBBdmUiLCJjaXR5IjoiS3VscHN2aWxsZSIsImNvdW50eSI6Ik1vbnRnb21lcnkiLCJzdGF0ZSI6IlBBIiwiemlwIjoiMTk0NDMiLCJob21lUGhvbmUiOiIyMTUtODc0LTEyMjkiLCJjZWxsUGhvbmUiOiIyMTUtNDIyLTg2OTQiLCJlbWFpbCI6Im1pbm5hX2FtaWdvbkB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5kb3JsamFtZXNqZXNxLmNvbSJ9"}]}}End Event ***************EventSource = aws:rmqEventSourceARN = arn:aws:mq:us-west-2:664251831272:broker:ib-rabbitmq-broker:b-22450561-3f76-4004-813d-392346f054feNow iterating through Map of all queuesCurrent Queue Name = LambdaRabbitMQQueueNow iterating through each message in this queue - LambdaRabbitMQQueueNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJKb3NlcGhpbmUiLCJsYXN0bmFtZSI6IkRhcmFrankiLCJjb21wYW55IjoiXCJDaGFuYXksIEplZmZyZXkgQSBFc3FcIiIsInN0cmVldCI6IjQgQiBCbHVlIFJpZGdlIEJsdmQiLCJjaXR5IjoiQnJpZ2h0b24iLCJjb3VudHkiOiJMaXZpbmdzdG9uIiwic3RhdGUiOiJNSSIsInppcCI6IjQ4MTE2IiwiaG9tZVBob25lIjoiODEwLTI5Mi05Mzg4IiwiY2VsbFBob25lIjoiODEwLTM3NC05ODQwIiwiZW1haWwiOiJqb3NlcGhpbmVfZGFyYWtqeUBkYXJha2p5Lm9yZyIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYW5heWplZmZyZXlhZXNxLmNvbSJ9DecodedData = {"firstname":"Josephine","lastname":"Darakjy","company":"\"Chanay, Jeffrey A Esq\"","street":"4 B Blue Ridge Blvd","city":"Brighton","county":"Livingston","state":"MI","zip":"48116","homePhone":"810-292-9388","cellPhone":"810-374-9840","email":"josephine_darakjy@darakjy.org","website":"http://www.chanayjeffreyaesq.com"}This person = Person [firstname=Josephine, lastname=Darakjy, company="Chanay, Jeffrey A Esq", street=4 B Blue Ridge Blvd, city=Brighton, county=Livingston, state=MI, zip=48116, homePhone=810-292-9388, cellPhone=810-374-9840, email=josephine_darakjy@darakjy.org, website=http://www.chanayjeffreyaesq.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 321ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-1DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:1Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 1Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJBcnQiLCJsYXN0bmFtZSI6IlZlbmVyZSIsImNvbXBhbnkiOiJcIkNoZW1lbCwgSmFtZXMgTCBDcGFcIiIsInN0cmVldCI6IjggVyBDZXJyaXRvcyBBdmUgIzU0IiwiY2l0eSI6IkJyaWRnZXBvcnQiLCJjb3VudHkiOiJHbG91Y2VzdGVyIiwic3RhdGUiOiJOSiIsInppcCI6IjgwMTQiLCJob21lUGhvbmUiOiI4NTYtNjM2LTg3NDkiLCJjZWxsUGhvbmUiOiI4NTYtMjY0LTQxMzAiLCJlbWFpbCI6ImFydEB2ZW5lcmUub3JnIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuY2hlbWVsamFtZXNsY3BhLmNvbSJ9DecodedData = {"firstname":"Art","lastname":"Venere","company":"\"Chemel, James L Cpa\"","street":"8 W Cerritos Ave #54","city":"Bridgeport","county":"Gloucester","state":"NJ","zip":"8014","homePhone":"856-636-8749","cellPhone":"856-264-4130","email":"art@venere.org","website":"http://www.chemeljameslcpa.com"}This person = Person [firstname=Art, lastname=Venere, company="Chemel, James L Cpa", street=8 W Cerritos Ave #54, city=Bridgeport, county=Gloucester, state=NJ, zip=8014, homePhone=856-636-8749, cellPhone=856-264-4130, email=art@venere.org, website=http://www.chemeljameslcpa.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 297ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-2DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:2Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 2Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJMZW5uYSIsImxhc3RuYW1lIjoiUGFwcm9ja2kiLCJjb21wYW55IjoiRmVsdHogUHJpbnRpbmcgU2VydmljZSIsInN0cmVldCI6IjYzOSBNYWluIFN0IiwiY2l0eSI6IkFuY2hvcmFnZSIsImNvdW50eSI6IkFuY2hvcmFnZSIsInN0YXRlIjoiQUsiLCJ6aXAiOiI5OTUwMSIsImhvbWVQaG9uZSI6IjkwNy0zODUtNDQxMiIsImNlbGxQaG9uZSI6IjkwNy05MjEtMjAxMCIsImVtYWlsIjoibHBhcHJvY2tpQGhvdG1haWwuY29tIiwid2Vic2l0ZSI6Imh0dHA6Ly93d3cuZmVsdHpwcmludGluZ3NlcnZpY2UuY29tIn0=DecodedData = {"firstname":"Lenna","lastname":"Paprocki","company":"Feltz Printing Service","street":"639 Main St","city":"Anchorage","county":"Anchorage","state":"AK","zip":"99501","homePhone":"907-385-4412","cellPhone":"907-921-2010","email":"lpaprocki@hotmail.com","website":"http://www.feltzprintingservice.com"}This person = Person [firstname=Lenna, lastname=Paprocki, company=Feltz Printing Service, street=639 Main St, city=Anchorage, county=Anchorage, state=AK, zip=99501, homePhone=907-385-4412, cellPhone=907-921-2010, email=lpaprocki@hotmail.com, website=http://www.feltzprintingservice.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 302ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-3DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:3Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 3Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJEb25ldHRlIiwibGFzdG5hbWUiOiJGb2xsZXIiLCJjb21wYW55IjoiUHJpbnRpbmcgRGltZW5zaW9ucyIsInN0cmVldCI6IjM0IENlbnRlciBTdCIsImNpdHkiOiJIYW1pbHRvbiIsImNvdW50eSI6IkJ1dGxlciIsInN0YXRlIjoiT0giLCJ6aXAiOiI0NTAxMSIsImhvbWVQaG9uZSI6IjUxMy01NzAtMTg5MyIsImNlbGxQaG9uZSI6IjUxMy01NDktNDU2MSIsImVtYWlsIjoiZG9uZXR0ZS5mb2xsZXJAY294Lm5ldCIsIndlYnNpdGUiOiJodHRwOi8vd3d3LnByaW50aW5nZGltZW5zaW9ucy5jb20ifQ==DecodedData = {"firstname":"Donette","lastname":"Foller","company":"Printing Dimensions","street":"34 Center St","city":"Hamilton","county":"Butler","state":"OH","zip":"45011","homePhone":"513-570-1893","cellPhone":"513-549-4561","email":"donette.foller@cox.net","website":"http://www.printingdimensions.com"}This person = Person [firstname=Donette, lastname=Foller, company=Printing Dimensions, street=34 Center St, city=Hamilton, county=Butler, state=OH, zip=45011, homePhone=513-570-1893, cellPhone=513-549-4561, email=donette.foller@cox.net, website=http://www.printingdimensions.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 295ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-4DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:4Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 4Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJTaW1vbmEiLCJsYXN0bmFtZSI6Ik1vcmFzY2EiLCJjb21wYW55IjoiXCJDaGFwbWFuLCBSb3NzIEUgRXNxXCIiLCJzdHJlZXQiOiIzIE1jYXVsZXkgRHIiLCJjaXR5IjoiQXNobGFuZCIsImNvdW50eSI6IkFzaGxhbmQiLCJzdGF0ZSI6Ik9IIiwiemlwIjoiNDQ4MDUiLCJob21lUGhvbmUiOiI0MTktNTAzLTI0ODQiLCJjZWxsUGhvbmUiOiI0MTktODAwLTY3NTkiLCJlbWFpbCI6InNpbW9uYUBtb3Jhc2NhLmNvbSIsIndlYnNpdGUiOiJodHRwOi8vd3d3LmNoYXBtYW5yb3NzZWVzcS5jb20ifQ==DecodedData = {"firstname":"Simona","lastname":"Morasca","company":"\"Chapman, Ross E Esq\"","street":"3 Mcauley Dr","city":"Ashland","county":"Ashland","state":"OH","zip":"44805","homePhone":"419-503-2484","cellPhone":"419-800-6759","email":"simona@morasca.com","website":"http://www.chapmanrosseesq.com"}This person = Person [firstname=Simona, lastname=Morasca, company="Chapman, Ross E Esq", street=3 Mcauley Dr, city=Ashland, county=Ashland, state=OH, zip=44805, homePhone=419-503-2484, cellPhone=419-800-6759, email=simona@morasca.com, website=http://www.chapmanrosseesq.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 292ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-5DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:5Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 5Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJNaXRzdWUiLCJsYXN0bmFtZSI6IlRvbGxuZXIiLCJjb21wYW55IjoiTW9ybG9uZyBBc3NvY2lhdGVzIiwic3RyZWV0IjoiNyBFYWRzIFN0IiwiY2l0eSI6IkNoaWNhZ28iLCJjb3VudHkiOiJDb29rIiwic3RhdGUiOiJJTCIsInppcCI6IjYwNjMyIiwiaG9tZVBob25lIjoiNzczLTU3My02OTE0IiwiY2VsbFBob25lIjoiNzczLTkyNC04NTY1IiwiZW1haWwiOiJtaXRzdWVfdG9sbG5lckB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5tb3Jsb25nYXNzb2NpYXRlcy5jb20ifQ==DecodedData = {"firstname":"Mitsue","lastname":"Tollner","company":"Morlong Associates","street":"7 Eads St","city":"Chicago","county":"Cook","state":"IL","zip":"60632","homePhone":"773-573-6914","cellPhone":"773-924-8565","email":"mitsue_tollner@yahoo.com","website":"http://www.morlongassociates.com"}This person = Person [firstname=Mitsue, lastname=Tollner, company=Morlong Associates, street=7 Eads St, city=Chicago, county=Cook, state=IL, zip=60632, homePhone=773-573-6914, cellPhone=773-924-8565, email=mitsue_tollner@yahoo.com, website=http://www.morlongassociates.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 289ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-6DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:6Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 6Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJMZW90YSIsImxhc3RuYW1lIjoiRGlsbGlhcmQiLCJjb21wYW55IjoiQ29tbWVyY2lhbCBQcmVzcyIsInN0cmVldCI6IjcgVyBKYWNrc29uIEJsdmQiLCJjaXR5IjoiU2FuIEpvc2UiLCJjb3VudHkiOiJTYW50YSBDbGFyYSIsInN0YXRlIjoiQ0EiLCJ6aXAiOiI5NTExMSIsImhvbWVQaG9uZSI6IjQwOC03NTItMzUwMCIsImNlbGxQaG9uZSI6IjQwOC04MTMtMTEwNSIsImVtYWlsIjoibGVvdGFAaG90bWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5jb21tZXJjaWFscHJlc3MuY29tIn0=DecodedData = {"firstname":"Leota","lastname":"Dilliard","company":"Commercial Press","street":"7 W Jackson Blvd","city":"San Jose","county":"Santa Clara","state":"CA","zip":"95111","homePhone":"408-752-3500","cellPhone":"408-813-1105","email":"leota@hotmail.com","website":"http://www.commercialpress.com"}This person = Person [firstname=Leota, lastname=Dilliard, company=Commercial Press, street=7 W Jackson Blvd, city=San Jose, county=Santa Clara, state=CA, zip=95111, homePhone=408-752-3500, cellPhone=408-813-1105, email=leota@hotmail.com, website=http://www.commercialpress.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 293ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-7DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:7Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 7Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJTYWdlIiwibGFzdG5hbWUiOiJXaWVzZXIiLCJjb21wYW55IjoiVHJ1aGxhciBBbmQgVHJ1aGxhciBBdHR5cyIsInN0cmVldCI6IjUgQm9zdG9uIEF2ZSAjODgiLCJjaXR5IjoiU2lvdXggRmFsbHMiLCJjb3VudHkiOiJNaW5uZWhhaGEiLCJzdGF0ZSI6IlNEIiwiemlwIjoiNTcxMDUiLCJob21lUGhvbmUiOiI2MDUtNDE0LTIxNDciLCJjZWxsUGhvbmUiOiI2MDUtNzk0LTQ4OTUiLCJlbWFpbCI6InNhZ2Vfd2llc2VyQGNveC5uZXQiLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy50cnVobGFyYW5kdHJ1aGxhcmF0dHlzLmNvbSJ9DecodedData = {"firstname":"Sage","lastname":"Wieser","company":"Truhlar And Truhlar Attys","street":"5 Boston Ave #88","city":"Sioux Falls","county":"Minnehaha","state":"SD","zip":"57105","homePhone":"605-414-2147","cellPhone":"605-794-4895","email":"sage_wieser@cox.net","website":"http://www.truhlarandtruhlarattys.com"}This person = Person [firstname=Sage, lastname=Wieser, company=Truhlar And Truhlar Attys, street=5 Boston Ave #88, city=Sioux Falls, county=Minnehaha, state=SD, zip=57105, homePhone=605-414-2147, cellPhone=605-794-4895, email=sage_wieser@cox.net, website=http://www.truhlarandtruhlarattys.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 309ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-8DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:8Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 8Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJLcmlzIiwibGFzdG5hbWUiOiJNYXJyaWVyIiwiY29tcGFueSI6IlwiS2luZywgQ2hyaXN0b3BoZXIgQSBFc3FcIiIsInN0cmVldCI6IjIyOCBSdW5hbXVjayBQbCAjMjgwOCIsImNpdHkiOiJCYWx0aW1vcmUiLCJjb3VudHkiOiJCYWx0aW1vcmUgQ2l0eSIsInN0YXRlIjoiTUQiLCJ6aXAiOiIyMTIyNCIsImhvbWVQaG9uZSI6IjQxMC02NTUtODcyMyIsImNlbGxQaG9uZSI6IjQxMC04MDQtNDY5NCIsImVtYWlsIjoia3Jpc0BnbWFpbC5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5raW5nY2hyaXN0b3BoZXJhZXNxLmNvbSJ9DecodedData = {"firstname":"Kris","lastname":"Marrier","company":"\"King, Christopher A Esq\"","street":"228 Runamuck Pl #2808","city":"Baltimore","county":"Baltimore City","state":"MD","zip":"21224","homePhone":"410-655-8723","cellPhone":"410-804-4694","email":"kris@gmail.com","website":"http://www.kingchristopheraesq.com"}This person = Person [firstname=Kris, lastname=Marrier, company="King, Christopher A Esq", street=228 Runamuck Pl #2808, city=Baltimore, county=Baltimore City, state=MD, zip=21224, homePhone=410-655-8723, cellPhone=410-804-4694, email=kris@gmail.com, website=http://www.kingchristopheraesq.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 312ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-9DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:9Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 9Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow logging a new messageEncodedData = eyJmaXJzdG5hbWUiOiJNaW5uYSIsImxhc3RuYW1lIjoiQW1pZ29uIiwiY29tcGFueSI6IlwiRG9ybCwgSmFtZXMgSiBFc3FcIiIsInN0cmVldCI6IjIzNzEgSmVycm9sZCBBdmUiLCJjaXR5IjoiS3VscHN2aWxsZSIsImNvdW50eSI6Ik1vbnRnb21lcnkiLCJzdGF0ZSI6IlBBIiwiemlwIjoiMTk0NDMiLCJob21lUGhvbmUiOiIyMTUtODc0LTEyMjkiLCJjZWxsUGhvbmUiOiIyMTUtNDIyLTg2OTQiLCJlbWFpbCI6Im1pbm5hX2FtaWdvbkB5YWhvby5jb20iLCJ3ZWJzaXRlIjoiaHR0cDovL3d3dy5kb3JsamFtZXNqZXNxLmNvbSJ9DecodedData = {"firstname":"Minna","lastname":"Amigon","company":"\"Dorl, James J Esq\"","street":"2371 Jerrold Ave","city":"Kulpsville","county":"Montgomery","state":"PA","zip":"19443","homePhone":"215-874-1229","cellPhone":"215-422-8694","email":"minna_amigon@yahoo.com","website":"http://www.dorljamesjesq.com"}This person = Person [firstname=Minna, lastname=Amigon, company="Dorl, James J Esq", street=2371 Jerrold Ave, city=Kulpsville, county=Montgomery, state=PA, zip=19443, homePhone=215-874-1229, cellPhone=215-422-8694, email=minna_amigon@yahoo.com, website=http://www.dorljamesjesq.com]Whether Redelivered = falseAppID = rabbitmq.producer.JsonRabbitMQProducerBodySize = 300ClusterId = b-22450561-3f76-4004-813d-392346f054fe.mq.us-west-2.amazonaws.comContentEncoding = UTF-8ContentType = text/plainCorrelationId = TestMessage03-07-02-2023-01-07-20-10DeliveryMode = 2Expiration = 60000MessageId = TestMessage03-07-02-2023-01-07-20:10Priority = 1ReplyTo = nullTimestamp = Jul 2, 2023, 1:30:34 AMType = JsonRabbitMQProducerUserId = adminNow iterating through the headers in this messageHeader Name = MessageNumberInBatch and Header Value = 10Header Name = MessageBatchIdentifier and Header Value = TestMessage03-07-02-2023-01-07-20Now done iterating through the headers in this messageNow done logging a new messageNow done iterating through each message in this queueDone iterating through Map of all queuesEND RequestId: 92cccff5-2663-4725-af9a-4a301bcbf777 +REPORT RequestId: 92cccff5-2663-4725-af9a-4a301bcbf777 Init Duration: 0.05 ms Duration: 1155.75 ms Billed Duration: 1156 ms Memory Size: 512 MB Max Memory Used: 512 MB +"200" + +***** End sam local invoke response ***** +``` + + +## Deploy the sample application + + +To deploy your application for the first time, run the following in your shell: + +```bash +sam deploy --capabilities CAPABILITY_IAM --no-confirm-changeset --no-disable-rollback --region $AWS_REGION --stack-name activemq-lambda-java-sam --guided +``` + +The sam deploy command will package and deploy your application to AWS, with a series of prompts. You can accept all the defaults by hitting Enter: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Parameter ActiveMQBrokerArn**: The ARN of the ActiveMQBroker that was created by the CloudFormation template +* **Parameter ActiveMQQueue**: The name of the ActiveMQ queue from which the lambda function will consume messages +* **Parameter SecretsManagerSecretForMQ**: The ARN of the secret that has username/password for Active MQ +* **Parameter Subnet1**: The first of the three private subnets where the DocumentDB cluster is deployed +* **Parameter Subnet2**: The second of the three private subnets where the DocumentDB cluster is deployed +* **Parameter Subnet3**: The third of the three private subnets where the DocumentDB cluster is deployed +* **Parameter SecurityGroup**: The security group of the lambda function. This can be the same as the security group of the EC2 machine that was created by the CloudFormation template +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails +* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. +* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally +* **SAM configuration environment [default]**: Environment for storing deployment information locally + +You should get a message "Successfully created/updated stack - in " if all goes well + +**Note: In case you want to deploy the Lambda function by pointing to an existing Amazon MQ (Apache ActiveMQ) Cluster and not the one created by running the CloudFormation template provided in this pattern, you will need to modify the values of the above parameters accordingly** + + +## Test the application + +Once the lambda function is deployed, send some messages to the Amazon MQ (Apache ActiveMQ) cluster on the queue that have been configured on the lambda function's event listener. + +For your convenience, a Java program and a shell script has been created on the EC2 machine that was provisioned using Cloudformation. + +cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json + +You should see a script called commands.sh. Run that script by passing a random string and a number between 1 and 500 + +``` +[ec2-user@ip-10-0-0-126 ~]$ sh ./commands.sh firstBatch 10 +Sent out one message - Number 1 at time = 1760937987906 +Sent out one message - Number 2 at time = 1760937987909 +Sent out one message - Number 3 at time = 1760937987910 +Sent out one message - Number 4 at time = 1760937987911 +Sent out one message - Number 5 at time = 1760937987913 +Sent out one message - Number 6 at time = 1760937987914 +Sent out one message - Number 7 at time = 1760937987915 +Sent out one message - Number 8 at time = 1760937987916 +Sent out one message - Number 9 at time = 1760937987918 +Sent out one message - Number 10 at time = 1760937987919 +``` + +Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) + +Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. + +When you run the above script, it sends messages with JSON records to the Amazon MQ (Apache ActiveMQ) cluster on the queue on which the lambda function is listening on. The lambda function listens on the published ActiveMQ messages on the queue. + +The lambda code parses the ActiveMQ messages and outputs the fields in the messages to Cloudwatch logs + +The lambda function also inputs each record into a DynamoDB table called ActiveMQDynamoDBTableJava (if you did not modify the default name in the sam template.yaml file) + +You can go to the DynamoDB console and view the records. + +You can also use the aws cli command below to view the count of records inserted into DynamoDB + +``` +aws dynamodb scan --table-name ActiveMQDynamoDBTableJava --select "COUNT" + +``` + + + +## Cleanup + +You can first clean-up the Lambda function by running the sam delete command + +``` +cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam +sam delete + +``` +confirm by pressing y for both the questions +You should see the lambda function getting deleted and a final confirmation "Deleted successfully" on the command-line + +Next you need to delete the Cloudformation template that created the Amazon MQ (Apache ActiveMQ) cluster and the EC2 machine by going to the Cloudformation console and selecting the stack and then hitting the "Delete" button. It will run for sometime but eventually you should see the stack getting cleaned up. If you get an error message that says the stack could not be deleted, please retry again and do a Force Delete. The reason this may happen is because ENIs created by the deplayed Lambda function in your VPC may prevent the VPC from being deleted even after deleting the lambda function. \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml index 43a900e1e..22bf4fd68 100644 --- a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -636,6 +636,8 @@ Resources: sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" create_rabbit_queue.sh sed -i "s/RABBITMQ_BROKER_ADMIN_USER/$RABBITMQ_BROKER_ADMIN_USER/g" create_rabbit_queue.sh sed -i "s/RABBITMQ_BROKER_PASSWORD/$RABBITMQ_BROKER_PASSWORD/g" create_rabbit_queue.sh + + sh ./create_rabbit_queue.sh # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user @@ -836,6 +838,11 @@ Outputs: Value: !GetAtt RabbitMQSecurityGroup.GroupId Export: Name: !Sub "${AWS::StackName}-SecurityGroupId" + ClientSecurityGroupId: + Description: ID of security group for RabbitMQ clients + Value: !GetAtt RabbitMQClientInstanceSecurityGroup.GroupId + Export: + Name: !Sub "${AWS::StackName}-ClientSecurityGroupId" EC2InstanceEndpointID: Description: The ID of the EC2 Instance Endpoint Value: !Ref EC2InstanceEndpoint diff --git a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml index fe049c359..5f298aae6 100755 --- a/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml +++ b/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam/template_original.yaml @@ -117,11 +117,11 @@ Parameters: Subnet3: Type: String Description: The third of the three private subnets in the RabbitMQ broker's VPC - Default: Default: RABBITMQ_SUBNET_THREE + Default: RABBITMQ_SUBNET_THREE SecurityGroup: Type: String Description: The security group associated with this function (use same RabbitMQ) - Default: RABBITMQ_SECURITY_GROUP + Default: SECURITY_GROUP Outputs: LambdaRabbitMQConsumerJavaFunction: Description: "Queue Consumer Lambda Function ARN" From b37e665852d819c6b3611af632639ba760095a8c Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Fri, 24 Oct 2025 17:28:40 -0700 Subject: [PATCH 16/18] Fixed Readme files --- activemq-private-lambda-java-sam/README.md | 10 +- .../ActiveMQAndClientEC2.yaml | 870 ------------------ rabbitmq-private-lambda-java-sam/README.md | 70 +- .../RabbitMQAndClientEC2.yaml | 11 + .../query_rabbit_queue.sh | 29 + 5 files changed, 87 insertions(+), 903 deletions(-) delete mode 100644 rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml create mode 100644 rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh diff --git a/activemq-private-lambda-java-sam/README.md b/activemq-private-lambda-java-sam/README.md index 55f2b791a..5477c32a6 100755 --- a/activemq-private-lambda-java-sam/README.md +++ b/activemq-private-lambda-java-sam/README.md @@ -1,5 +1,5 @@ # activemq-private-lambda-java-sam -# Java AWS Lambda DocumentDB Streams consumer, using AWS SAM +# Java AWS Lambda ActiveMQ (in private subnets) consumer, using AWS SAM This pattern is an example of a Lambda function written in Java that consumes messages from Amazon MQ (Apache ActiveMQ) @@ -52,7 +52,7 @@ cd activemq_consumer_dynamo_sam sam build ``` -The SAM CLI installs dependencies defined in `documentdb_streams_consumer_dynamo_sam/documentdb_streams_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. +The SAM CLI installs dependencies defined in `activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. ``` @@ -94,9 +94,9 @@ The sam deploy command will package and deploy your application to AWS, with a s * **Parameter ActiveMQBrokerArn**: The ARN of the ActiveMQBroker that was created by the CloudFormation template * **Parameter ActiveMQQueue**: The name of the ActiveMQ queue from which the lambda function will consume messages * **Parameter SecretsManagerSecretForMQ**: The ARN of the secret that has username/password for Active MQ -* **Parameter Subnet1**: The first of the three private subnets where the DocumentDB cluster is deployed -* **Parameter Subnet2**: The second of the three private subnets where the DocumentDB cluster is deployed -* **Parameter Subnet3**: The third of the three private subnets where the DocumentDB cluster is deployed +* **Parameter Subnet1**: The first of the three private subnets where the ActiveMQ cluster is deployed +* **Parameter Subnet2**: The second of the three private subnets where the ActiveMQ cluster is deployed +* **Parameter Subnet3**: The third of the three private subnets where the ActiveMQ cluster is deployed * **Parameter SecurityGroup**: The security group of the lambda function. This can be the same as the security group of the EC2 machine that was created by the CloudFormation template * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. diff --git a/rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml deleted file mode 100644 index 542c09a9a..000000000 --- a/rabbitmq-private-lambda-java-sam/ActiveMQAndClientEC2.yaml +++ /dev/null @@ -1,870 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Parameters: - LatestAmiId: - Type: 'AWS::SSM::Parameter::Value' - Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64' - ActiveMQEngineVersion: - Type: String - Default: 5.18 - Description: ActiveMQ engine version - JavaVersion: - Type: String - Description: Choose the version of Java. Lambda currently supports Java 11, 17 and 21 - AllowedValues: - - java11 - - java17 - - java21 - Default: java21 - ActiveMQBrokerName: - Type: String - Default: ActiveMQJavaLambdaBroker - Description: ActiveMQ broker name for Lambda function - ActiveMQQueueName: - Type: String - Default: ActiveMQJavaLambdaQueue - Description: ActiveMQ queue name for Lambda function - ActiveMQBrokerAdminUser: - Type: String - Description: Username for the ActiveMQ Broker - Default: activemqadmin - ActiveMQBrokerPassword: - Type: String - Description: Password for the ActiveMQ Broker - Default: activemqPassword123 - NoEcho: true - ServerlessLandGithubLocation: - Type: String - Default: https://github.com/aws-samples/serverless-patterns.git - Description: Github location of the code. Make sure to leave the .git at the end even if you are using a fork - -Mappings: - SubnetConfig: - VPC: - CIDR: '10.1.0.0/16' - PublicOne: - CIDR: '10.1.0.0/24' - PublicTwo: - CIDR: '10.1.1.0/24' - PublicThree: - CIDR: '10.1.2.0/24' - PrivateSubnetActiveMQOne: - CIDR: '10.1.3.0/24' - PrivateSubnetActiveMQTwo: - CIDR: '10.1.4.0/24' - PrivateSubnetActiveMQThree: - CIDR: '10.1.5.0/24' - -Resources: - # Secrets Manager Secret for ActiveMQ credentials - ActiveMQSecret: - Type: AWS::SecretsManager::Secret - Properties: - Name: 'AmazonActiveMQCredentials' - Description: ActiveMQ broker master user credentials - SecretString: !Sub | - { - "username": "${ActiveMQBrokerAdminUser}", - "password": "${ActiveMQBrokerPassword}" - } - - VPC: - Type: AWS::EC2::VPC - Properties: - EnableDnsSupport: true - EnableDnsHostnames: true - CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - Tags: - - Key: 'Name' - Value: 'ActiveMQVPC' - - PublicSubnetOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetOne' - PublicSubnetTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetTwo' - PublicSubnetThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PublicThree', 'CIDR'] - MapPublicIpOnLaunch: true - Tags: - - Key: 'Name' - Value: 'PublicSubnetThree' - PrivateSubnetActiveMQOne: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQOne', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQOne' - PrivateSubnetActiveMQTwo: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQTwo', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQTwo' - PrivateSubnetActiveMQThree: - Type: AWS::EC2::Subnet - Properties: - AvailabilityZone: - Fn::Select: - - 2 - - Fn::GetAZs: {Ref: 'AWS::Region'} - VpcId: !Ref 'VPC' - CidrBlock: !FindInMap ['SubnetConfig', 'PrivateSubnetActiveMQThree', 'CIDR'] - MapPublicIpOnLaunch: false - Tags: - - Key: 'Name' - Value: 'PrivateSubnetActiveMQThree' - - InternetGateway: - Type: AWS::EC2::InternetGateway - GatewayAttachement: - Type: AWS::EC2::VPCGatewayAttachment - Properties: - VpcId: !Ref 'VPC' - InternetGatewayId: !Ref 'InternetGateway' - - NATEIP1: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway1: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP1.AllocationId - SubnetId: !Ref 'PublicSubnetOne' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway1' - - NATEIP2: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway2: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP2.AllocationId - SubnetId: !Ref 'PublicSubnetTwo' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway2' - - NATEIP3: - Type: AWS::EC2::EIP - DependsOn: GatewayAttachement - Properties: - Domain: vpc - - NATGateway3: - Type: AWS::EC2::NatGateway - Properties: - AllocationId: !GetAtt NATEIP3.AllocationId - SubnetId: !Ref 'PublicSubnetThree' - Tags: - - Key: 'Name' - Value: 'ActiveMQNATGateway3' - - PublicRouteTable: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PublicRoute: - Type: AWS::EC2::Route - DependsOn: GatewayAttachement - Properties: - RouteTableId: !Ref 'PublicRouteTable' - DestinationCidrBlock: '0.0.0.0/0' - GatewayId: !Ref 'InternetGateway' - - PublicSubnetOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetOne - RouteTableId: !Ref PublicRouteTable - - PublicSubnetTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetTwo - RouteTableId: !Ref PublicRouteTable - - PublicSubnetThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref PublicSubnetThree - RouteTableId: !Ref PublicRouteTable - - PrivateRouteTable1: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute1: - Type: AWS::EC2::Route - DependsOn: NATGateway1 - Properties: - RouteTableId: !Ref 'PrivateRouteTable1' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway1' - - PrivateRouteTable2: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute2: - Type: AWS::EC2::Route - DependsOn: NATGateway2 - Properties: - RouteTableId: !Ref 'PrivateRouteTable2' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway2' - - PrivateRouteTable3: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref 'VPC' - - PrivateRoute3: - Type: AWS::EC2::Route - DependsOn: NATGateway3 - Properties: - RouteTableId: !Ref 'PrivateRouteTable3' - DestinationCidrBlock: '0.0.0.0/0' - NatGatewayId: !Ref 'NATGateway3' - - PrivateSubnetActiveMQOneRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable1 - SubnetId: !Ref PrivateSubnetActiveMQOne - - PrivateSubnetActiveMQTwoRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable2 - SubnetId: !Ref PrivateSubnetActiveMQTwo - - PrivateSubnetActiveMQThreeRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - RouteTableId: !Ref PrivateRouteTable3 - SubnetId: !Ref PrivateSubnetActiveMQThree - - ActiveMQClientInstanceSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Enable SSH access via port 22 from BastionHostSecurityGroup - GroupName: !Sub "${AWS::StackName} Security group attached to the ActiveMQ client" - VpcId: !Ref VPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 10.0.0.0/16 - - ActiveMQSecurityGroup: - Type: AWS::EC2::SecurityGroup - DependsOn: [VPC,ActiveMQClientInstanceSecurityGroup] - Properties: - GroupDescription: ActiveMQ Security Group - GroupName: !Sub "${AWS::StackName} Security group for the ActiveMQ broker" - VpcId: !Ref 'VPC' - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 61617 - ToPort: 61617 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: 8162 - ToPort: 8162 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: 0 - ToPort: 65535 - CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] - - ActiveMQClientSelfIngressAllowRule: - Type: AWS::EC2::SecurityGroupIngress - DependsOn: ActiveMQClientInstanceSecurityGroup - Properties: - GroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - SourceSecurityGroupId: !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - - # ActiveMQ Configuration - ActiveMQConfiguration: - Type: AWS::AmazonMQ::Configuration - Properties: - Name: !Sub "${AWS::StackName}-activemq-config" - Description: ActiveMQ configuration for the cluster - EngineType: ACTIVEMQ - EngineVersion: !Ref ActiveMQEngineVersion - Data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8YnJva2VyIHhtbG5zPSJodHRwOi8vYWN0aXZlbXEuYXBhY2hlLm9yZy9zY2hlbWEvY29yZSI+CiAgPGRlc3RpbmF0aW9uUG9saWN5PgogICAgPHBvbGljeU1hcD4KICAgICAgPHBvbGljeUVudHJpZXM+CiAgICAgICAgPHBvbGljeUVudHJ5IHRvcGljPSI+IiBwcm9kdWNlckZsb3dDb250cm9sPSJ0cnVlIj4KICAgICAgICAgIDxwZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgICAgIDxzcG9vbGluZ1N1YnNjcmlwdGlvblBlbmRpbmdNZXNzYWdlTGltaXRTdHJhdGVneSBsaW1pdD0iMTAwMCIvPgogICAgICAgICAgPC9wZW5kaW5nTWVzc2FnZUxpbWl0U3RyYXRlZ3k+CiAgICAgICAgPC9wb2xpY3lFbnRyeT4KICAgICAgICA8cG9saWN5RW50cnkgcXVldWU9Ij4iIHByb2R1Y2VyRmxvd0NvbnRyb2w9InRydWUiIG1lbW9yeUxpbWl0PSIxbWIiPgogICAgICAgIDwvcG9saWN5RW50cnk+CiAgICAgIDwvcG9saWN5RW50cmllcz4KICAgIDwvcG9saWN5TWFwPgogIDwvZGVzdGluYXRpb25Qb2xpY3k+CiAgPHN5c3RlbVVzYWdlPgogICAgPHN5c3RlbVVzYWdlPgogICAgICA8bWVtb3J5VXNhZ2U+CiAgICAgICAgPG1lbW9yeVVzYWdlIGxpbWl0PSI2NCBtYiIvPgogICAgICA8L21lbW9yeVVzYWdlPgogICAgICA8c3RvcmVVc2FnZT4KICAgICAgICA8c3RvcmVVc2FnZSBsaW1pdD0iNTEyIG1iIi8+CiAgICAgIDwvc3RvcmVVc2FnZT4KICAgICAgPHRlbXBVc2FnZT4KICAgICAgICA8dGVtcFVzYWdlIGxpbWl0PSIxMjggbWIiLz4KICAgICAgPC90ZW1wVXNhZ2U+CiAgICA8L3N5c3RlbVVzYWdlPgogIDwvc3lzdGVtVXNhZ2U+CjwvYnJva2VyPgo= - - # ActiveMQ Broker - ActiveMQBroker: - Type: AWS::AmazonMQ::Broker - Properties: - BrokerName: !Ref ActiveMQBrokerName - DeploymentMode: ACTIVE_STANDBY_MULTI_AZ - EngineType: ACTIVEMQ - EngineVersion: !Ref ActiveMQEngineVersion - HostInstanceType: mq.t3.micro - PubliclyAccessible: false - AutoMinorVersionUpgrade: true - Configuration: - Id: !Ref ActiveMQConfiguration - Revision: 1 - Users: - - Username: !Ref ActiveMQBrokerAdminUser - Password: !Ref ActiveMQBrokerPassword - ConsoleAccess: true - Groups: - - admin - SubnetIds: - - !Ref PrivateSubnetActiveMQOne - - !Ref PrivateSubnetActiveMQTwo - SecurityGroups: - - !Ref ActiveMQSecurityGroup - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}-activemq-broker" - - ActiveMQClientEC2Instance: - DependsOn: ActiveMQBroker - Type: AWS::EC2::Instance - Properties: - InstanceType: m5.large - IamInstanceProfile: !Ref EC2InstanceProfile - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: {Ref: 'AWS::Region'} - SubnetId: !Ref PublicSubnetOne - SecurityGroupIds: [!GetAtt ActiveMQClientInstanceSecurityGroup.GroupId] - ImageId: !Ref LatestAmiId - Tags: - - Key: 'Name' - Value: 'ActiveMQClientInstance' - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: 50 - VolumeType: gp2 - DeleteOnTermination: true - UserData: - Fn::Base64: - !Sub - - | - #!/bin/bash - yum update -y - - # install Java - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum update -y - - # install Java - JAVA_VERSION=${java_version} - echo "export JAVA_VERSION=$JAVA_VERSION" >> /home/ec2-user/.bash_profile - if [ "$JAVA_VERSION" == "java11" ]; then - sudo yum install java-11-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java17" ]; then - sudo yum install java-17-amazon-corretto-devel -y - elif [ "$JAVA_VERSION" == "java21" ]; then - sudo yum install java-21-amazon-corretto-devel -y - else - sudo yum install java-21-amazon-corretto-devel -y - fi - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of Java succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install nmap-ncat -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of nmap succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install git -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of git succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum erase awscli -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum erase of awscli succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - yum install jq -y - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of jq succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y docker - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of docker succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - service docker start - usermod -a -G docker ec2-user - - max_attempts=5 - attempt_num=1 - success=false - while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do - echo "Trying yum install" - sudo yum install -y maven - # Check the exit code of the command - if [ $? -eq 0 ]; then - echo "Yum install of maven succeeded" - success=true - else - echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..." - sleep 3 - ((attempt_num++)) - fi - done - - cd /home/ec2-user - su -c "ln -s /usr/bin/python3.8 /usr/bin/python3" -s /bin/sh ec2-user - su -c "pip3 install boto3 --user" -s /bin/sh ec2-user - su -c "pip3 install kafka-python --user" -s /bin/sh ec2-user - - # install AWS CLI 2 - access with aws2 - cd /home/ec2-user - mkdir -p awscli - cd awscli - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install - - # Install AWS SAM CLI - cd /home/ec2-user - mkdir -p awssam - cd awssam - wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip - unzip aws-sam-cli-linux-x86_64.zip -d sam-installation - sudo ./sam-installation/install - - # Set environment variables - ACTIVEMQ_BROKER_ID=${activemq_broker_id} - ACTIVEMQ_BROKER_ARN=${activemq_broker_arn} - activemq_broker_endpoint="\"failover:(${activemq_broker_endpoint1},${activemq_broker_endpoint2})\"" - ACTIVEMQ_QUEUE_NAME=${activemq_queue_name} - ACTIVEMQ_SECRET_ARN=${activemq_secret_arn} - AWS_REGION=${aws_region} - ACTIVEMQ_SUBNET_ONE=${activemq_subnet_one} - ACTIVEMQ_SUBNET_TWO=${activemq_subnet_two} - ACTIVEMQ_SUBNET_THREE=${activemq_subnet_three} - ACTIVEMQ_SECURITY_GROUP=${activemq_security_group} - ACTIVEMQ_BROKER_ADMIN_USER=${activemq_broker_admin_user} - ACTIVEMQ_BROKER_PASSWORD=${activemq_broker_password} - SECURITY_GROUP=${security_group_id} - - echo "export ACTIVEMQ_BROKER_ID=$ACTIVEMQ_BROKER_ID" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ARN=$ACTIVEMQ_BROKER_ARN" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_QUEUE_NAME=$ACTIVEMQ_QUEUE_NAME" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SECRET_ARN=$ACTIVEMQ_SECRET_ARN" >> /home/ec2-user/.bash_profile - echo "export AWS_REGION=$AWS_REGION" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_ONE=$ACTIVEMQ_SUBNET_ONE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_TWO=$ACTIVEMQ_SUBNET_TWO" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SUBNET_THREE=$ACTIVEMQ_SUBNET_THREE" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_SECURITY_GROUP=$ACTIVEMQ_SECURITY_GROUP" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_ADMIN_USER=$ACTIVEMQ_BROKER_ADMIN_USER" >> /home/ec2-user/.bash_profile - echo "export ACTIVEMQ_BROKER_PASSWORD=$ACTIVEMQ_BROKER_PASSWORD" >> /home/ec2-user/.bash_profile - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - - # Clone serverless patterns - cd /home/ec2-user - SERVERLESS_LAND_GITHUB_LOCATION=${serverless_land_github_location} - git clone -n --depth=1 --filter=tree:0 $SERVERLESS_LAND_GITHUB_LOCATION - cd ./serverless-patterns - git sparse-checkout set --no-cone /activemq-private-lambda-java-sam - git checkout - cd activemq-private-lambda-java-sam - sudo chown -R ec2-user . - - #Substitute SAM template variables - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam - cd activemq_consumer_dynamo_sam - cp template_original.yaml template.yaml - sudo chown -R ec2-user . - source /home/ec2-user/.bash_profile - sed -i "s/ACTIVEMQ_BROKER_ARN/$ACTIVEMQ_BROKER_ARN/g" template.yaml - sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" template.yaml - sed -i "s/ACTIVEMQ_SECRET_ARN/$ACTIVEMQ_SECRET_ARN/g" template.yaml - sed -i "s/JAVA_VERSION/$JAVA_VERSION/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_ONE/$ACTIVEMQ_SUBNET_ONE/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_TWO/$ACTIVEMQ_SUBNET_TWO/g" template.yaml - sed -i "s/ACTIVEMQ_SUBNET_THREE/$ACTIVEMQ_SUBNET_THREE/g" template.yaml - sed -i "s/SECURITY_GROUP/$SECURITY_GROUP/g" template.yaml - - #Install ActiveMQ (needed in case you want to use the CLI as a client to look at queues etc.) - mkdir /home/ec2-user/activemq_client - cd /home/ec2-user/activemq_client - wget https://archive.apache.org/dist/activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz - tar zxvf apache-activemq-5.18.6-bin.tar.gz - sudo chown -R ec2-user . - - #Update Shell script for sending ActiveMQ messages to Lambda function - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json - sudo chown ec2-user ./commands.sh - source /home/ec2-user/.bash_profile - echo "ACTIVEMQ_BROKER_ENDPOINT=$activemq_broker_endpoint" - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT|$activemq_broker_endpoint|g" commands.sh - sed -i "s/ACTIVEMQ_QUEUE_NAME/$ACTIVEMQ_QUEUE_NAME/g" commands.sh - mvn clean install - - #Update Shell script for browsing messages in ActiveMQ queue - cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam - sudo chown ec2-user ./activemq_queue_browser.sh - source /home/ec2-user/.bash_profile - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_ONE|${activemq_broker_endpoint1}|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ENDPOINT_TWO|${activemq_broker_endpoint2}|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_ADMIN_USER|$ACTIVEMQ_BROKER_ADMIN_USER|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_BROKER_PASSWORD|$ACTIVEMQ_BROKER_PASSWORD|g" activemq_queue_browser.sh - sed -i "s|ACTIVEMQ_QUEUE_NAME|$ACTIVEMQ_QUEUE_NAME|g" activemq_queue_browser.sh - - # Get IP CIDR range for EC2 Instance Connect - cd /home/ec2-user - mkdir -p ip_prefix - cd ip_prefix - git clone https://github.com/joetek/aws-ip-ranges-json.git - cd aws-ip-ranges-json - AWS_REGION=${aws_region} - EC2_CONNECT_IP=$(cat ip-ranges-ec2-instance-connect.json | jq -r --arg AWS_REGION "$AWS_REGION" '.prefixes[] | select(.region==$AWS_REGION).ip_prefix') - echo "export EC2_CONNECT_IP=$EC2_CONNECT_IP" >> /home/ec2-user/.bash_profile - SECURITY_GROUP=${security_group_id} - echo "export SECURITY_GROUP=$SECURITY_GROUP" >> /home/ec2-user/.bash_profile - aws ec2 authorize-security-group-ingress --region $AWS_REGION --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr $EC2_CONNECT_IP - - - activemq_broker_id: !Ref ActiveMQBroker - activemq_broker_arn: !GetAtt ActiveMQBroker.Arn - activemq_broker_endpoint1: !Select [ 0, !GetAtt ActiveMQBroker.OpenWireEndpoints ] - activemq_broker_endpoint2: !Select [ 1, !GetAtt ActiveMQBroker.OpenWireEndpoints ] - activemq_queue_name: !Ref ActiveMQQueueName - activemq_secret_arn: !Ref ActiveMQSecret - serverless_land_github_location: !Ref ServerlessLandGithubLocation - aws_region: !Ref 'AWS::Region' - java_version: !Ref JavaVersion - security_group_id : !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - activemq_subnet_one: !Ref PrivateSubnetActiveMQOne - activemq_subnet_two: !Ref PrivateSubnetActiveMQTwo - activemq_subnet_three: !Ref PrivateSubnetActiveMQThree - activemq_security_group: !GetAtt ActiveMQSecurityGroup.GroupId - activemq_broker_admin_user: !Ref ActiveMQBrokerAdminUser - activemq_broker_password: !Ref ActiveMQBrokerPassword - - EC2InstanceEndpoint: - Type: AWS::EC2::InstanceConnectEndpoint - Properties: - PreserveClientIp: true - SecurityGroupIds: - - !GetAtt ActiveMQClientInstanceSecurityGroup.GroupId - SubnetId: !Ref PublicSubnetOne - - EC2Role: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: '' - Effect: Allow - Principal: - Service: ec2.amazonaws.com - Action: 'sts:AssumeRole' - Path: "/" - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonMQFullAccess - - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - - arn:aws:iam::aws:policy/CloudWatchFullAccess - - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - - arn:aws:iam::aws:policy/AmazonS3FullAccess - - arn:aws:iam::aws:policy/IAMFullAccess - - arn:aws:iam::aws:policy/AWSLambda_FullAccess - - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess_v2 - Policies: - - PolicyName: ActiveMQAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ActiveMQFullAccess", - "Effect": "Allow", - "Action": [ - "mq:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecretsManagerAccess - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:PutSecretValue", - "secretsmanager:DescribeSecret" - ], - "Resource": "${ActiveMQSecret}" - } - ] - }' - - PolicyName: CloudformationDeploy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "iam:*" - ], - "Resource": "*" - } - ] - }' - - PolicyName: SecurityGroupsPolicy - PolicyDocument: !Sub '{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeSecurityGroups", - "ec2:DescribeSecurityGroupRules", - "ec2:DescribeTags" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:RevokeSecurityGroupIngress", - "ec2:AuthorizeSecurityGroupEgress", - "ec2:RevokeSecurityGroupEgress", - "ec2:ModifySecurityGroupRules", - "ec2:UpdateSecurityGroupRuleDescriptionsIngress", - "ec2:UpdateSecurityGroupRuleDescriptionsEgress" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "ec2:ModifySecurityGroupRules" - ], - "Resource": [ - "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group-rule/*" - ] - } - ] - }' - - EC2InstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - InstanceProfileName: !Join - - '-' - - - 'EC2ActiveMQProfile' - - !Ref 'AWS::StackName' - Roles: - - !Ref EC2Role - -Outputs: - VPCId: - Description: The ID of the VPC created - Value: !Ref 'VPC' - Export: - Name: !Sub "${AWS::StackName}-VPCID" - PublicSubnetOne: - Description: The name of the public subnet created - Value: !Ref 'PublicSubnetOne' - Export: - Name: !Sub "${AWS::StackName}-PublicSubnetOne" - PrivateSubnetActiveMQOne: - Description: The ID of private subnet one created - Value: !Ref 'PrivateSubnetActiveMQOne' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQOne" - PrivateSubnetActiveMQTwo: - Description: The ID of private subnet two created - Value: !Ref 'PrivateSubnetActiveMQTwo' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQTwo" - PrivateSubnetActiveMQThree: - Description: The ID of private subnet three created - Value: !Ref 'PrivateSubnetActiveMQThree' - Export: - Name: !Sub "${AWS::StackName}-PrivateSubnetActiveMQThree" - VPCStackName: - Description: The name of the VPC Stack - Value: !Ref 'AWS::StackName' - Export: - Name: !Sub "${AWS::StackName}-VPCStackName" - ActiveMQBrokerEndpoint1: - Description: ActiveMQ Broker OpenWire Endpoint - Value: !Select [0, !GetAtt ActiveMQBroker.OpenWireEndpoints] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint1" - ActiveMQBrokerEndpoint2: - Description: ActiveMQ Broker OpenWire Endpoint - Value: !Select [1, !GetAtt ActiveMQBroker.OpenWireEndpoints] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerEndpoint2" - ActiveMQBrokerConsoleURL: - Description: ActiveMQ Broker Web Console URL - Value: !Sub - - "https://${endpoint}" - - endpoint: !Select [0, !GetAtt ActiveMQBroker.IpAddresses] - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerConsoleURL" - ActiveMQSecretArn: - Description: ARN of the ActiveMQ credentials secret - Value: !Ref ActiveMQSecret - Export: - Name: !Sub "${AWS::StackName}-ActiveMQSecretArn" - SecurityGroupId: - Description: ID of security group for ActiveMQ clients - Value: !GetAtt ActiveMQSecurityGroup.GroupId - Export: - Name: !Sub "${AWS::StackName}-SecurityGroupId" - EC2InstanceEndpointID: - Description: The ID of the EC2 Instance Endpoint - Value: !Ref EC2InstanceEndpoint - ActiveMQBrokerName: - Description: The Broker name to use for the Java Lambda Function - Value: !Ref ActiveMQBrokerName - Export: - Name: !Sub "${AWS::StackName}-ActiveMQBrokerName" - ActiveMQQueueName: - Description: The Queue name to use for the Java Lambda Function - Value: !Ref ActiveMQQueueName - Export: - Name: !Sub "${AWS::StackName}-ActiveMQQueueName" diff --git a/rabbitmq-private-lambda-java-sam/README.md b/rabbitmq-private-lambda-java-sam/README.md index 15cb877ec..584531d2f 100755 --- a/rabbitmq-private-lambda-java-sam/README.md +++ b/rabbitmq-private-lambda-java-sam/README.md @@ -1,15 +1,15 @@ # rabbitmq-private-lambda-java-sam -# Java AWS Lambda DocumentDB Streams consumer, using AWS SAM +# Java AWS Lambda RabbitMQ (in private subnets) consumer, using AWS SAM -This pattern is an example of a Lambda function written in Java that consumes messages from Amazon MQ (Apache ActiveMQ) +This pattern is an example of a Lambda function written in Java that consumes messages from Amazon MQ (RabbitMQ) This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders. -- activemq_consumer_dynamo_sam/activemq_event_consumer_function/src/main/java - Code for the application's Lambda function that will listen for Amazon MQ (Apache ActiveMQ) messages and write them to a DynamoDB table -- activemq_message_sender_json/src/main/java - Code for publishing messages with JSON payload into an Amazon MQ (ActiveMQ cluster), that will in turn be consumed by the Lambda function -- activemq_consumer_dynamo_sam/template_original.yaml - A template that defines the application's Lambda function to be used by SAM to deploy the lambda function -- ActiveMQAndClientEC2.yaml - A Cloudformation template file that can be used to deploy an Amazon MQ (Apache ActiveMQ) cluster and also deploy an EC2 machine with all pre-requisities already installed, so you can directly build and deploy the lambda function and test it out. -- activemq_queue_browser.sh - A shell script that can be used to connect to the Amazon MQ (Apache ActiveMQ) brokers using the activemq command-line tool +- rabbitmq_consumer_dynamo_sam/rabbit_event_consumer_function/src/main/java - Code for the application's Lambda function that will listen for Amazon MQ (RabbitMQ) messages and write them to a DynamoDB table +- rabbit_message_sender_json/src/main/java - Code for publishing messages with JSON payload into an Amazon MQ (RabbitMQ cluster), that will in turn be consumed by the Lambda function +- rabbit_consumer_dynamo_sam/template_original.yaml - A template that defines the application's Lambda function to be used by SAM to deploy the lambda function +- RabbitMQAndClientEC2.yaml - A Cloudformation template file that can be used to deploy an Amazon MQ (RabbitMQ) cluster and also deploy an EC2 machine with all pre-requisities already installed, so you can directly build and deploy the lambda function and test it out. +- create_rabbit_queue.sh - A shell script that can be used to connect to the Amazon MQ (RabbitMQ) brokers to create virtualhosts, exchanges and queues, required for the lambda functions event listener Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. @@ -17,9 +17,9 @@ Important: this application uses various AWS services and there are costs associ * [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. -## Run the Cloudformation template to create the Amazon MQ (Apache ActiveMQ) Cluster and Client EC2 machine +## Run the Cloudformation template to create the Amazon MQ (RabbitMQ) Cluster and Client EC2 machine -* [Run the Cloudformation template using the file ActiveMQAndClientEC2.yaml] - You can go to the AWS Cloudformation console, create a new stack by specifying the template file. You can keep the defaults for input parameters or modify them as necessary. Wait for the Cloudformation stack to be created. This Cloudformation template will create an Amazon MQ (Apache ActiveMQ) cluster. It will also create an EC2 machine that you can use as a client. +* [Run the Cloudformation template using the file RabbitMQAndClientEC2.yaml] - You can go to the AWS Cloudformation console, create a new stack by specifying the template file. You can keep the defaults for input parameters or modify them as necessary. Wait for the Cloudformation stack to be created. This Cloudformation template will create an Amazon MQ (RabbitMQ) cluster. It will also create an EC2 machine that you can use as a client. * [Connect to the EC2 machine] - Once the CloudFormation stack is created, you can go to the EC2 console and log into the machine using either "Connect using EC2 Instance Connect" or "Connect using EC2 Instance Connect Endpoint" option under the "EC2 Instance Connect" tab. Note: You may need to wait for some time after the CloudFormation stack is created, as some UserData scripts continue running after the Cloudformation stack shows Created. @@ -40,7 +40,7 @@ We have also cloned the Github repository for serverless-patterns on the EC2 mac ``` Change directory to the pattern directory: ``` - cd serverless-patterns/activemq-private-lambda-java-sam + cd serverless-patterns/rabbit-private-lambda-java-sam ``` ## Use the SAM CLI to build and deploy the lambda function @@ -48,11 +48,11 @@ Change directory to the pattern directory: Build your application with the `sam build` command. ```bash -cd activemq_consumer_dynamo_sam +cd rabbit_consumer_dynamo_sam sam build ``` -The SAM CLI installs dependencies defined in `documentdb_streams_consumer_dynamo_sam/documentdb_streams_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. +The SAM CLI installs dependencies defined in `rabbitmq_consumer_dynamo_sam/rabbit_event_consumer_function/pom.xml`, creates a deployment package, and saves it in the `.aws-sam/build` folder. ``` @@ -87,6 +87,19 @@ REPORT RequestId: 92cccff5-2663-4725-af9a-4a301bcbf777 Init Duration: 0.05 ms ***** End sam local invoke response ***** ``` +## Check RabbitMQ Queue Creation + +We have included a shell script file called create_rabbit_queue.sh. This shell script creates a VirtualHost, an Exchange and a Queue in the RabbitMQ cluster. It also binds the queue to the exchange. This step is necessary before the Lambda function can be deployed. + +The create_rabbit_queue.sh script is run automatically as part of the CloudFormation script. + +There is another shell script file called query_rabbit_queue.sh that has been included. You should find it in the /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam folder. You can run this script as below to ensure the virtualhost, exhange and queue have been created in the RabbitMQ cluster + +```bash +cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam +sh ./query_rabbit_queue.sh +``` + ## Deploy the sample application @@ -94,19 +107,20 @@ REPORT RequestId: 92cccff5-2663-4725-af9a-4a301bcbf777 Init Duration: 0.05 ms To deploy your application for the first time, run the following in your shell: ```bash -sam deploy --capabilities CAPABILITY_IAM --no-confirm-changeset --no-disable-rollback --region $AWS_REGION --stack-name activemq-lambda-java-sam --guided +sam deploy --capabilities CAPABILITY_IAM --no-confirm-changeset --no-disable-rollback --region $AWS_REGION --stack-name rabbit-lambda-java-sam --guided ``` The sam deploy command will package and deploy your application to AWS, with a series of prompts. You can accept all the defaults by hitting Enter: * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. * **AWS Region**: The AWS region you want to deploy your app to. -* **Parameter ActiveMQBrokerArn**: The ARN of the ActiveMQBroker that was created by the CloudFormation template -* **Parameter ActiveMQQueue**: The name of the ActiveMQ queue from which the lambda function will consume messages -* **Parameter SecretsManagerSecretForMQ**: The ARN of the secret that has username/password for Active MQ -* **Parameter Subnet1**: The first of the three private subnets where the DocumentDB cluster is deployed -* **Parameter Subnet2**: The second of the three private subnets where the DocumentDB cluster is deployed -* **Parameter Subnet3**: The third of the three private subnets where the DocumentDB cluster is deployed +* **Parameter RabbitMQBrokerArn**: The ARN of the RabbitMQBroker that was created by the CloudFormation template +* **Parameter RabbitMQVirtualHost**: The name of the RabbitMQ virtual host from which the lambda function will consume messages +* **Parameter RabbitMQQueue**: The name of the RabbitMQ queue from which the lambda function will consume messages +* **Parameter SecretsManagerSecretForMQ**: The ARN of the secret that has username/password for Rabbit MQ +* **Parameter Subnet1**: The first of the three private subnets where the RabbitMQ cluster is deployed +* **Parameter Subnet2**: The second of the three private subnets where the RabbitMQ cluster is deployed +* **Parameter Subnet3**: The third of the three private subnets where the RabbitMQ cluster is deployed * **Parameter SecurityGroup**: The security group of the lambda function. This can be the same as the security group of the EC2 machine that was created by the CloudFormation template * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. @@ -117,16 +131,16 @@ The sam deploy command will package and deploy your application to AWS, with a s You should get a message "Successfully created/updated stack - in " if all goes well -**Note: In case you want to deploy the Lambda function by pointing to an existing Amazon MQ (Apache ActiveMQ) Cluster and not the one created by running the CloudFormation template provided in this pattern, you will need to modify the values of the above parameters accordingly** +**Note: In case you want to deploy the Lambda function by pointing to an existing Amazon MQ (RabbitMQ) Cluster and not the one created by running the CloudFormation template provided in this pattern, you will need to modify the values of the above parameters accordingly** ## Test the application -Once the lambda function is deployed, send some messages to the Amazon MQ (Apache ActiveMQ) cluster on the queue that have been configured on the lambda function's event listener. +Once the lambda function is deployed, send some messages to the Amazon MQ (RabbitMQ) cluster on the queue that have been configured on the lambda function's event listener. For your convenience, a Java program and a shell script has been created on the EC2 machine that was provisioned using Cloudformation. -cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_message_sender_json +cd /home/ec2-user/serverless-patterns/rabbit-private-lambda-java-sam/rabbit_message_sender_json You should see a script called commands.sh. Run that script by passing a random string and a number between 1 and 500 @@ -148,18 +162,18 @@ Either send at least 10 messages or wait for 300 seconds (check the values of Ba Then check Cloudwatch logs and you should see messages for the Cloudwatch Log Group with the name of the deployed Lambda function. -When you run the above script, it sends messages with JSON records to the Amazon MQ (Apache ActiveMQ) cluster on the queue on which the lambda function is listening on. The lambda function listens on the published ActiveMQ messages on the queue. +When you run the above script, it sends messages with JSON records to the Amazon MQ (RabbitMQ) cluster on the queue on which the lambda function is listening on. The lambda function listens on the published RabbitMQ messages on the queue. -The lambda code parses the ActiveMQ messages and outputs the fields in the messages to Cloudwatch logs +The lambda code parses the RabbitMQ messages and outputs the fields in the messages to Cloudwatch logs -The lambda function also inputs each record into a DynamoDB table called ActiveMQDynamoDBTableJava (if you did not modify the default name in the sam template.yaml file) +The lambda function also inputs each record into a DynamoDB table called RabbitMQDynamoDBTableJava (if you did not modify the default name in the sam template.yaml file) You can go to the DynamoDB console and view the records. You can also use the aws cli command below to view the count of records inserted into DynamoDB ``` -aws dynamodb scan --table-name ActiveMQDynamoDBTableJava --select "COUNT" +aws dynamodb scan --table-name RabbitMQDynamoDBTableJava --select "COUNT" ``` @@ -170,11 +184,11 @@ aws dynamodb scan --table-name ActiveMQDynamoDBTableJava --select "COUNT" You can first clean-up the Lambda function by running the sam delete command ``` -cd /home/ec2-user/serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam +cd /home/ec2-user/serverless-patterns/rabbit-private-lambda-java-sam/rabbit_consumer_dynamo_sam sam delete ``` confirm by pressing y for both the questions You should see the lambda function getting deleted and a final confirmation "Deleted successfully" on the command-line -Next you need to delete the Cloudformation template that created the Amazon MQ (Apache ActiveMQ) cluster and the EC2 machine by going to the Cloudformation console and selecting the stack and then hitting the "Delete" button. It will run for sometime but eventually you should see the stack getting cleaned up. If you get an error message that says the stack could not be deleted, please retry again and do a Force Delete. The reason this may happen is because ENIs created by the deplayed Lambda function in your VPC may prevent the VPC from being deleted even after deleting the lambda function. \ No newline at end of file +Next you need to delete the Cloudformation template that created the Amazon MQ (RabbitMQ) cluster and the EC2 machine by going to the Cloudformation console and selecting the stack and then hitting the "Delete" button. It will run for sometime but eventually you should see the stack getting cleaned up. If you get an error message that says the stack could not be deleted, please retry again and do a Force Delete. The reason this may happen is because ENIs created by the deplayed Lambda function in your VPC may prevent the VPC from being deleted even after deleting the lambda function. \ No newline at end of file diff --git a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml index 22bf4fd68..7635ef2ae 100644 --- a/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml +++ b/rabbitmq-private-lambda-java-sam/RabbitMQAndClientEC2.yaml @@ -638,6 +638,17 @@ Resources: sed -i "s/RABBITMQ_BROKER_PASSWORD/$RABBITMQ_BROKER_PASSWORD/g" create_rabbit_queue.sh sh ./create_rabbit_queue.sh + + #Script to check if RabbitMQ Virtual Host, Exchange and Queue have been created properly + cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam + sudo chown ec2-user ./query_rabbit_queue.sh + source /home/ec2-user/.bash_profile + sed -i "s|RABBITMQ_BROKER_ENDPOINT|${rabbitmq_broker_endpoint}|g" query_rabbit_queue.sh + sed -i "s/RABBITMQ_QUEUE_NAME/$RABBITMQ_QUEUE_NAME/g" query_rabbit_queue.sh + sed -i "s/RABBITMQ_VIRTUAL_HOST/$RABBITMQ_VIRTUAL_HOST/g" query_rabbit_queue.sh + sed -i "s/RABBITMQ_EXCHANGE/$RABBITMQ_EXCHANGE/g" query_rabbit_queue.sh + sed -i "s/RABBITMQ_BROKER_ADMIN_USER/$RABBITMQ_BROKER_ADMIN_USER/g" query_rabbit_queue.sh + sed -i "s/RABBITMQ_BROKER_PASSWORD/$RABBITMQ_BROKER_PASSWORD/g" query_rabbit_queue.sh # Get IP CIDR range for EC2 Instance Connect cd /home/ec2-user diff --git a/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh b/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh new file mode 100644 index 000000000..bcabc467f --- /dev/null +++ b/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +original_broker_endpoint="RABBITMQ_BROKER_ENDPOINT" + +amqps_prefix="amqps://" + +# Remove the prefix from the beginning of the string +broker_endpoint_without_amqps="${original_broker_endpoint#$amqps_prefix}" + +# Print the result +echo "original_broker_endpoint: $original_broker_endpoint" +echo "broker_endpoint_without_amqps: $broker_endpoint_without_amqps" + +port_suffix=":5671" +broker_endpoint_without_port="${broker_endpoint_without_amqps%${port_suffix}}" +echo "broker_endpoint_without_port: $broker_endpoint_without_port" + +https_prefix="https://" + +rabbitmq_https_broker_endpoint="$https_prefix$broker_endpoint_without_port" +echo "rabbitmq_https_broker_endpoint=$rabbitmq_https_broker_endpoint" + +curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/vhosts/RABBITMQ_VIRTUAL_HOST + +curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/exchanges/RABBITMQ_VIRTUAL_HOST/RABBITMQ_EXCHANGE + +curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/queues/RABBITMQ_VIRTUAL_HOST/RABBITMQ_QUEUE_NAME + +curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/bindings/RABBITMQ_VIRTUAL_HOST/e/RABBITMQ_EXCHANGE/q/RABBITMQ_QUEUE_NAME \ No newline at end of file From fbb33b9cc63b641849fca788f31c400fc9fc4134 Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Sat, 25 Oct 2025 01:21:41 -0700 Subject: [PATCH 17/18] Fixed Readme files --- rabbitmq-private-lambda-java-sam/README.md | 152 ++++++++++++++++++ .../query_rabbit_queue.sh | 24 ++- 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/rabbitmq-private-lambda-java-sam/README.md b/rabbitmq-private-lambda-java-sam/README.md index 584531d2f..23d0c8935 100755 --- a/rabbitmq-private-lambda-java-sam/README.md +++ b/rabbitmq-private-lambda-java-sam/README.md @@ -100,6 +100,158 @@ cd /home/ec2-user/serverless-patterns/rabbitmq-private-lambda-java-sam sh ./query_rabbit_queue.sh ``` +The response from running this script will be something like this if all the commands from the create_rabbit_queue.sh ran properly + +``` +original_broker_endpoint: amqps://b-55617af0-19ff-4939-8702-e5a508977c0b.mq.us-west-2.on.aws:5671 +broker_endpoint_without_amqps: b-55617af0-19ff-4939-8702-e5a508977c0b.mq.us-west-2.on.aws:5671 +broker_endpoint_without_port: b-55617af0-19ff-4939-8702-e5a508977c0b.mq.us-west-2.on.aws +rabbitmq_https_broker_endpoint=https://b-55617af0-19ff-4939-8702-e5a508977c0b.mq.us-west-2.on.aws +########## Begin verifying if Virtual Host has been created ########## +{ + "name": "RabbitMQVirtualHost", + "description": "", + "tags": [], + "default_queue_type": "undefined", + "metadata": { + "description": "", + "tags": [] + }, + "tracing": false, + "cluster_state": { + "rabbit@ip-10-0-12-186.us-west-2.compute.internal": "running", + "rabbit@ip-10-0-28-241.us-west-2.compute.internal": "running", + "rabbit@ip-10-0-20-83.us-west-2.compute.internal": "running" + }, + "messages_ready": 0, + "messages_ready_details": { + "rate": 0.0 + }, + "messages_unacknowledged": 0, + "messages_unacknowledged_details": { + "rate": 0.0 + }, + "messages": 0, + "messages_details": { + "rate": 0.0 + } +} +########## End verifying if Virtual Host has been created ########## +########## Begin verifying if Exchange has been created ########## +{ + "arguments": {}, + "auto_delete": false, + "durable": true, + "incoming": [], + "internal": false, + "name": "RabbitMQExchange", + "outgoing": [], + "type": "fanout", + "user_who_performed_action": "rabbitmqadmin", + "vhost": "RabbitMQVirtualHost" +} +########## End verifying if Exchange has been created ########## +########## Begin verifying if Queue has been created ########## +{ + "consumer_details": [], + "arguments": {}, + "auto_delete": false, + "consumer_capacity": 0, + "consumer_utilisation": 0, + "consumers": 0, + "deliveries": [], + "durable": true, + "effective_policy_definition": { + "ha-mode": "all", + "ha-sync-mode": "automatic", + "queue-version": 2 + }, + "exclusive": false, + "exclusive_consumer_tag": null, + "garbage_collection": { + "fullsweep_after": 65535, + "max_heap_size": 0, + "min_bin_vheap_size": 46422, + "min_heap_size": 233, + "minor_gcs": 6 + }, + "head_message_timestamp": null, + "idle_since": "2025-10-25T01:46:54.843+00:00", + "incoming": [], + "memory": 6768, + "message_bytes": 0, + "message_bytes_paged_out": 0, + "message_bytes_persistent": 0, + "message_bytes_ram": 0, + "message_bytes_ready": 0, + "message_bytes_unacknowledged": 0, + "messages": 0, + "messages_details": { + "rate": 0.0 + }, + "messages_paged_out": 0, + "messages_persistent": 0, + "messages_ram": 0, + "messages_ready": 0, + "messages_ready_details": { + "rate": 0.0 + }, + "messages_ready_ram": 0, + "messages_unacknowledged": 0, + "messages_unacknowledged_details": { + "rate": 0.0 + }, + "messages_unacknowledged_ram": 0, + "name": "RabbitMQJavaLambdaQueue", + "node": "rabbit@ip-10-0-12-186.us-west-2.compute.internal", + "operator_policy": "default_operator_policy_AWS_managed", + "policy": "ha-all-AWS-OWNED-DO-NOT-DELETE", + "recoverable_slaves": [ + "rabbit@ip-10-0-28-241.us-west-2.compute.internal", + "rabbit@ip-10-0-20-83.us-west-2.compute.internal" + ], + "reductions": 46934, + "reductions_details": { + "rate": 0.0 + }, + "single_active_consumer_tag": null, + "slave_nodes": [ + "rabbit@ip-10-0-28-241.us-west-2.compute.internal", + "rabbit@ip-10-0-20-83.us-west-2.compute.internal" + ], + "state": "running", + "storage_version": 2, + "synchronised_slave_nodes": [ + "rabbit@ip-10-0-28-241.us-west-2.compute.internal", + "rabbit@ip-10-0-20-83.us-west-2.compute.internal" + ], + "type": "classic", + "vhost": "RabbitMQVirtualHost" +} +########## End verifying if Queue has been created ########## +########## Begin verifying if Queue has been bound to exchange ########## +[ + { + "source": "RabbitMQExchange", + "vhost": "RabbitMQVirtualHost", + "destination": "RabbitMQJavaLambdaQueue", + "destination_type": "queue", + "routing_key": "RabbitMQExchange-RabbitMQJavaLambdaQueue", + "arguments": {}, + "properties_key": "RabbitMQExchange-RabbitMQJavaLambdaQueue" + } +] +########## End verifying if Queue has been bound to exchange ########## + +``` + +If you see any exceptions when running the above script, please run the below command + +``` +sh ./create_rabbit_queue.sh + +``` + ## Deploy the sample application diff --git a/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh b/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh index bcabc467f..69e76d05a 100644 --- a/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh +++ b/rabbitmq-private-lambda-java-sam/query_rabbit_queue.sh @@ -20,10 +20,26 @@ https_prefix="https://" rabbitmq_https_broker_endpoint="$https_prefix$broker_endpoint_without_port" echo "rabbitmq_https_broker_endpoint=$rabbitmq_https_broker_endpoint" -curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/vhosts/RABBITMQ_VIRTUAL_HOST +echo "########## Begin verifying if Virtual Host has been created ##########" -curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/exchanges/RABBITMQ_VIRTUAL_HOST/RABBITMQ_EXCHANGE +curl -sL -u rabbitmqadmin:rabbitmqPassword123 -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/vhosts/RabbitMQVirtualHost | jq . -curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/queues/RABBITMQ_VIRTUAL_HOST/RABBITMQ_QUEUE_NAME +echo "########## End verifying if Virtual Host has been created ##########" -curl -sL -u RABBITMQ_BROKER_ADMIN_USER:RABBITMQ_BROKER_PASSWORD -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/bindings/RABBITMQ_VIRTUAL_HOST/e/RABBITMQ_EXCHANGE/q/RABBITMQ_QUEUE_NAME \ No newline at end of file +echo "########## Begin verifying if Exchange has been created ##########" + +curl -sL -u rabbitmqadmin:rabbitmqPassword123 -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/exchanges/RabbitMQVirtualHost/RabbitMQExchange | jq . + +echo "########## End verifying if Exchange has been created ##########" + +echo "########## Begin verifying if Queue has been created ##########" + +curl -sL -u rabbitmqadmin:rabbitmqPassword123 -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/queues/RabbitMQVirtualHost/RabbitMQJavaLambdaQueue | jq . + +echo "########## End verifying if Queue has been created ##########" + +echo "########## Begin verifying if Queue has been bound to exchange ##########" + +curl -sL -u rabbitmqadmin:rabbitmqPassword123 -H "Accept: application/json" $rabbitmq_https_broker_endpoint/api/bindings/RabbitMQVirtualHost/e/RabbitMQExchange/q/RabbitMQJavaLambdaQueue | jq . + +echo "########## End verifying if Queue has been bound to exchange ##########" \ No newline at end of file From 224fbf01fe13382de07ddcf85036c4318aa73daf Mon Sep 17 00:00:00 2001 From: Indranil Banerjee Date: Mon, 27 Oct 2025 10:40:41 -0700 Subject: [PATCH 18/18] Fixed Readme files --- .../example-pattern.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/rabbitmq-private-lambda-java-sam/example-pattern.json b/rabbitmq-private-lambda-java-sam/example-pattern.json index 5eb3fb455..e41617c50 100644 --- a/rabbitmq-private-lambda-java-sam/example-pattern.json +++ b/rabbitmq-private-lambda-java-sam/example-pattern.json @@ -1,22 +1,22 @@ { - "title": "AWS Lambda function subscribed to an Amazon MQ - Apache ActiveMQ in private subnets (Java)", - "description": "Creates a Lambda function that uses a private Amazon MQ (Apache ActiveMQ) as an event source.", + "title": "AWS Lambda function subscribed to an Amazon MQ - RabbitMQ in private subnets (Java)", + "description": "Creates a Lambda function that uses a private Amazon MQ (RabbitMQ) as an event source.", "language": "Java", "level": "200", "framework": "AWS SAM", "introBox": { "headline": "How it works", "text": [ - "This pattern provides a Lambda function along with an Event Source Mapping to an Amazon MQ (Apache ActiveMQ) queue.", - "The CloudFormation template provided in this pattern installs an Amazon MQ (Apache ActiveMQ) Cluster in private subnets in a VPC.", + "This pattern provides a Lambda function along with an Event Source Mapping to an Amazon MQ (RabbitMQ) queue.", + "The CloudFormation template provided in this pattern installs an Amazon MQ (RabbitMQ) Cluster in private subnets in a VPC.", "For detailed deployment instructions instructions see the README.md" ] }, "gitHub": { "template": { - "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/activemq-private-lambda-java-sam", - "templateURL": "serverless-patterns/activemq-private-lambda-java-sam/activemq_consumer_dynamo_sam", - "projectFolder": "activemq-private-lambda-java-sam", + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/rabbitmq-private-lambda-java-sam", + "templateURL": "serverless-patterns/rabbitmq-private-lambda-java-sam/rabbitmq_consumer_dynamo_sam", + "projectFolder": "rabbitmq-private-lambda-java-sam", "templateFile": "template_original.yaml" } }, @@ -33,6 +33,10 @@ { "text": "Amazon MQ resource type reference", "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/AWS_AmazonMQ.html" + }, + { + "text": "HTTP API Reference", + "link": "https://www.rabbitmq.com/docs/http-api-reference" } ] },