Example application on how to use Java in a event driver fashion.
This codebase contains some simple examples how of to engage an event driven architecture in Java.
The EventProducer<T>
interface provide a way to define a generic notification producer.
The implementation used in this codebase are three:
EndpointEventProducer
: though which the notification is sent to a REST endpoint;SnsEventProducer
: through which the event is notified onAWS SNS
service, by creating a newtopic
for that specific event;RabbitMqEventProducer
: though which the event is notified onRabbitMQ
by creating a newexchange
.ActiveMqEventProducer
: though which the event is notified onApache ActiveMQ
by creating a newtopic
.KafkaEventProducer
: though which the event is notified onApache Kafka
by creating a newtopic
.
The codebase provides a way to consume these three events with their respective consumer:
- an endpoint in the
RestController
class which consumes the events sent viaEndpointEventProducer
; - a
SqsConsumer
class which creates anAWS SQS queue
and automatically suscribes it to the givenAWS SNS topic
; - a
RabbitMqConsumer
class which creates aqueue
and registers it to the givenexchange
to consume the messages. - an
ActiveMqConsumer
class which subscribe directly to theActiveMqEventProducer
topic
to consume the messages. - a
KafkaEventConsumer
class which reads the records coming from theKafkaEventProducer
producertopic
.
To start the application locally you must have localstack
(which emulates AWS services locally) and rabitMQ
started locally in Docker containers.
To automatize this phase an init
script has been provided:
your/project/folder/ $ ./init.sh
Then you can start your application though your IDE or by exporting the jar artifact:
your/project/folder/ $ mvn clean install
your/project/folder/ $ java -jar ./target/notificationdemo-0.0.1.jar
The process will start an HTTP server on port 8080, so pay attention to let it free before starting the process.
To stop the processes you can take advantage of the quit.sh
script:
your/project/folder/ $ ./quit.sh
Localstack is a useful way to have your AWS services running locally without having to link your app to your AWS cloud account.
# Run docker image of localstack
docker run -it --rm -d -p 8081:8081 -p 4566-4599:4566-4599 --name lk localstack/localstack
# Health check
curl http://localhost:4566/health | jq
{
"features": {
"initScripts": "initialized"
},
"services": {
"acm": "available",
"apigateway": "available",
"cloudformation": "available",
"cloudwatch": "available",
"config": "available",
"dynamodb": "available",
"dynamodbstreams": "available",
"ec2": "available",
"es": "available",
"events": "available",
"firehose": "available",
"iam": "available",
"kinesis": "available",
"kms": "available",
"lambda": "available",
"logs": "available",
"opensearch": "available",
"redshift": "available",
"resource-groups": "available",
"resourcegroupstaggingapi": "available",
"route53": "available",
"route53resolver": "available",
"s3": "running",
"secretsmanager": "available",
"ses": "available",
"sns": "running",
"sqs": "running",
"ssm": "available",
"stepfunctions": "available",
"sts": "available",
"support": "available",
"swf": "available"
},
"version": "0.13.3"
}
# s3 service
# create s3 bucket
aws --endpoint-url=http://localhost:4566 s3 mb s3://mybucket
# list s3 files
aws --endpoint-url=http://localhost:4566 s3 ls
# upload file into s3 bucket
echo 'hello world!' > text-test.txt
aws --endpoint-url=http://localhost:4566 s3 cp text-test.txt s3://mybucket
# list s3 files
aws --endpoint-url=http://localhost:4566 s3 ls s3://mybucket
# SNS and SQS
# create topic
aws --endpoint-url=http://localhost:4566 sns create-topic --name mytopic
{"TopicArn": "arn:aws:sns:eu-west-1:000000000000:mytopic"}
# create queue
aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name myqueue001
{"QueueUrl": "http://localhost:4566/000000000000/myqueue001"}
# subscribe queue to topic
aws --endpoint-url=http://localhost:4566 sns subscribe --topic-arn arn:aws:sns:eu-west-1:000000000000:mytopic --protocol sqs --notification-endpoint http://localhost:4566/queue/myqueue001
{"SubscriptionArn": "arn:aws:sns:eu-west-1:000000000000:mytopic:20ed1612-26cb-4297-882d-e33158ab6130"}
# list topics
aws --endpoint-url=http://localhost:4566 sns list-topics
# list queues
aws --endpoint-url=http://localhost:4566 sqs list-queues
# list subscriptions
aws --endpoint-url=http://localhost:4566 sns list-subscriptions
# send notifications to topic
aws --endpoint-url=http://localhost:4566 sns publish --topic-arn arn:aws:sns:eu-west-1:000000000000:mytopic --message "Hi"
aws --endpoint-url=http://localhost:4566 sns publish --topic-arn arn:aws:sns:eu-west-1:000000000000:mytopic --message file://file.json
# read message on queue
aws --endpoint-url=http://localhost:4566 sqs receive-message --queue-url http://localhost:4566/000000000000/myqueue001
### send message on queue
aws --endpoint-url=http://localhost:4566 sqs send-message --queue-url http://localhost:4566/000000000000/myqueue001 --message-body 'Welcome to SQS queue myqueue001'
### read message from queue
aws --endpoint-url=http://localhost:4566 sqs receive-message --queue-url http://localhost:4566/000000000000/myqueue001
### delete queue
aws --endpoint-url=http://localhost:4566 sqs delete-queue --queue-url http://localhost:4566/000000000000/myqueue001
# AWS Secrets Manager
# list all secrets
aws --endpoint-url=http://localhost:4566 secretsmanager list-secrets
# create new secret
aws --endpoint-url=http://localhost:4566 secretsmanager create-secret --name jason \
--description "This is the password for dev-db admin user1" \
--secret-string "MySecretSecureString$123" \
--tags "Key=Environment,Value=Development"
# add tags to an existing secret
aws --endpoint-url=http://localhost:4566 secretsmanager tag-resource --secret-id jason \
--tags '[{"Key": "Name", "Value": "Jason"}, {"Key": "Role", "Value": "Admin"}]'
# untag a specific secret
aws --endpoint-url=http://localhost:4566 secretsmanager untag-resource --secret-id jason \
--tag-keys '[ "Environment", "Name"]'
# get the secret value given its name
aws --endpoint-url=http://localhost:4566 secretsmanager get-secret-value --secret-id jason
# describe a secret given its name
aws --endpoint-url=http://localhost:4566 secretsmanager describe-secret --secret-id jason
# delete a secret by its name (you can recover it within 30 days)
aws --endpoint-url=http://localhost:4566 secretsmanager delete-secret --secret-id jason
# delete a secret by its name specifying the recovery window
aws --endpoint-url=http://localhost:4566 secretsmanager delete-secret --secret-id jason --recovery-window-in-days 21
# recover a deleted secret given its name
aws --endpoint-url=http://localhost:4566 secretsmanager restore-secret --secret-id jason
# update a secret description by its name
aws --endpoint-url=http://localhost:4566 secretsmanager update-secret --secret-id jason \
--description "This is the password for dev-db admin user"
# update a secret value by its name
aws --endpoint-url=http://localhost:4566 secretsmanager update-secret --secret-id jason \
--secret-string "NewlyUpdatedSecret#"
# list of all temporal versions of a given secret
aws --endpoint-url=http://localhost:4566 secretsmanager list-secret-version-ids --secret-id jason
# get a secret value given its name and a specific temporal version
aws --endpoint-url=http://localhost:4566 secretsmanager get-secret-value --secret-id jason --version-stage AWSPREVIOUS
# get a secret value given its name and a specific version-id
aws --endpoint-url=http://localhost:4566 secretsmanager get-secret-value --secret-id jason --version-id 22222222-8888-51cc-d55e-jk222222222f