Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Boot On Amazon Web services with Sprin...

Spring Boot On Amazon Web services with Spring Cloud AWS

Spring Cloud AWS is a community project that helps developers use the rich ecosystem of AWS-managed services within a Spring Boot application in a familiar, idiomatic way.

In this talk, you'll learn how to speed up the development process using Spring Cloud AWS features, latest additions to the framework, and plans for the future.

Maciej Walkowiak

September 02, 2021
Tweet

More Decks by Maciej Walkowiak

Other Decks in Programming

Transcript

  1. @maciejwalkowiak @matejnedic1 SPRING CLOUD AWS •Created by Agim Emruli and

    Alain Shall •First commit in February 2011 •Community project •April 2020 - not a part of Spring Cloud release train •May 2020 - new maintainers
  2. @maciejwalkowiak @matejnedic1 EC2 •! Updates •! Backups •! Security •!

    Scaling •! High Availability RDS •✅ Updates •✅ Backups •✅ Security •✅ Scaling •✅ High Availability
  3. @maciejwalkowiak @matejnedic1 EC2 •! Updates •! Backups •! Security •!

    Scaling •! High Availability RDS •✅ Updates •✅ Backups •✅ Security •✅ Scaling •✅ High Availability #
  4. @maciejwalkowiak @matejnedic1 Application RDS - Primary RDS - Read Replica

    #1 Asynchronous Replication Write Read RDS - Read Replica #2 RDS - Read Replica #3 Read Read
  5. @maciejwalkowiak @matejnedic1 cloud: aws: rds: instances: - db-instance-identifier: springone database-name:

    postgres username: postgres password: postgres read-replica-support: true
  6. @maciejwalkowiak @matejnedic1 @Service class UserService { @Transactional void registerUser(User user)

    { ... } @Transactional(readOnly=true) User findUser(Long id) { ... } }
  7. @maciejwalkowiak @matejnedic1 •Only Tomcat connection pool supported (will change in

    3.0) •No Aurora support (will change in 3.0) WHAT IS MISSING?
  8. @maciejwalkowiak @matejnedic1 @Service public class RegistrationService { private final QueueMessagingTemplate

    queueMessagingTemplate; public RegistrationService(QueueMessagingTemplate queueMessagingTemplate) this.queueMessagingTemplate = queueMessagingTemplate; } void register(Attendee attendee) { // persist attendee, send confirmation email queueMessagingTemplate.convertAndSend("springone-queue", attendee); } }
  9. @maciejwalkowiak @matejnedic1 @Component public class AttendeeListener { private AttendeeRepository attendeeRepository;

    public AttendeeListener(AttendeeRepository attendeeRepository) { this.attendeeRepository = attendeeRepository; } @SqsListener("springone-queue") void handle(Attendee attendee) { attendeeRepository.save(attendee); } }
  10. @maciejwalkowiak @matejnedic1 @Component public class AttendeeListener { private AttendeeRepository attendeeRepository;

    public AttendeeListener(AttendeeRepository attendeeRepository) { this.attendeeRepository = attendeeRepository; } @SqsListener("springone-queue") void handle(Attendee attendee, @Header("header-name") String header) { attendeeRepository.save(attendee); } }
  11. @maciejwalkowiak @matejnedic1 @Component public class AttendeeListener { private AttendeeRepository attendeeRepository;

    public AttendeeListener(AttendeeRepository attendeeRepository) { this.attendeeRepository = attendeeRepository; } @SqsListener("springone-queue") void handle(Attendee attendee, Acknowledgment acknowledgment) { if (...) { acknowledgment.acknowledge(); } } }
  12. @maciejwalkowiak @matejnedic1 @Component public class AttendeeListener { private AttendeeRepository attendeeRepository;

    public AttendeeListener(AttendeeRepository attendeeRepository) { this.attendeeRepository = attendeeRepository; } @SqsListener("springone-queue") void handle(Attendee attendee, Visibility visibility) { if (...) { visibility.extend(2); } } }
  13. @maciejwalkowiak @matejnedic1 @Component public class AttendeeListener { private AttendeeRepository attendeeRepository;

    public AttendeeListener(AttendeeRepository attendeeRepository) { this.attendeeRepository = attendeeRepository; } @SqsListener("springone-queue") @SendTo("tickets-queue") Ticket handle(Attendee attendee) { attendeeRepository.save(attendee); // return ticket } }
  14. @maciejwalkowiak @matejnedic1 @Component public class SnsNotificationSender { private final NotificationMessagingTemplate

    notificationMessagingTemplate; public SnsNotificationSender( NotificationMessagingTemplate notificationMessagingTemplate) { this.notificationMessagingTemplate = notificationMessagingTemplate; } public void send(String subject, String message) { this.notificationMessagingTemplate.sendNotification( "physicalTopicName", message, subject); } }
  15. @maciejwalkowiak @matejnedic1 @Controller @RequestMapping("/springone-topic") public class NotificationController { @NotificationSubscriptionMapping public

    void handleSubscriptionMessage(NotificationStatus status) { //We subscribe to start receive the message status.confirmSubscription(); } @NotificationMessageMapping public void handleNotificationMessage(@NotificationSubject String subject, @NotificationMessage String message) { // ... } @NotificationUnsubscribeConfirmationMapping public void handleUnsubscribeMessage(NotificationStatus status) { //e.g. the client has been unsubscribed and we want to "re-subscribe" status.confirmSubscription(); } }
  16. @maciejwalkowiak @matejnedic1 Parameter Store • Type: Supports StringList,String, SecureString. •

    4KB char max • Can’t be referenced cross account • Can’t rotate secrets • Cheaper Secret manager • Can be referenced cross account • Automatic Secret rotation • More expensive • Can store more characters 10kb • Built in password generator • Supports secret cross region replication
  17. @maciejwalkowiak @matejnedic1 OTHER SUPPORTED SERVICES •S3 •EC2 metadata •Cloud Watch

    •ElastiCache (Redis & Memcached) •SES (Simple Email Service) •Cloud Formation
  18. @maciejwalkowiak @matejnedic1 WHEN SPRING CLOUD AWS IS NOT ENOUGH •Spring

    Cloud Stream Kinesis Binder https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis •Spring Integration AWS https://github.com/spring-projects/spring-integration-aws •Spring Cloud Config Server https://github.com/spring-cloud/spring-cloud-config •Spring Data DynamoDB https://github.com/boostchicken/spring-data-dynamodb
  19. @maciejwalkowiak @matejnedic1 •AWS SDK v2 •$ GraalVM Native Image compatible

    •$ Non Blocking - Spring WebFlux friendly! •$ Pluggable HTTP client •$ Does not conflict with SDK v1 •% Still no feature parity with 1.x WHEN SPRING CLOUD AWS IS NOT ENOUGH
  20. @maciejwalkowiak @matejnedic1 version: '3.1' services: localstack: image: localstack/localstack:latest environment: -

    SERVICES=sqs,s3 ports: - ‘4566:4566' - ‘4571:4571’ volumes: - "${TEMPDIR:-/tmp/localstack}:/tmp/localstack" - "/var/run/docker.sock:/var/run/docker.sock" LOCALSTACK
  21. @maciejwalkowiak @matejnedic1 $ docker-compose up localstack_1 | localstack_1 | __

    _______ __ __ localstack_1 | / / ____ _________ _/ / ___// /_____ ______/ /__ localstack_1 | / / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/ localstack_1 | / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,< localstack_1 | /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_| localstack_1 | localstack_1 | & LocalStack CLI 0.12.17.3 localstack_1 | localstack_1 | [16:23:49] starting LocalStack in host mode & localstack.py:101 localstack_1 | ──────────────── LocalStack Runtime Log (press CTRL-C to quit) ───────────────── localstack_1 | 2021-09-01 16:23:50,722 INFO success: infra entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) localstack_1 | localstack_1 | LocalStack version: 0.12.17.3 localstack_1 | LocalStack Docker container id: 67fb82278492 localstack_1 | LocalStack build date: 2021-09-01 localstack_1 | LocalStack build git hash: 637d9bfa localstack_1 | localstack_1 | Starting edge router (https port 4566)... localstack_1 | Starting mock S3 service on http port 4566 ... localstack_1 | 2021-09-01T16:23:54:INFO:localstack.multiserver: Starting multi API server process on port 44089 localstack_1 | [2021-09-01 16:23:54 +0000] [21] [INFO] Running on https://0.0.0.0:4566 (CTRL + C to quit) localstack_1 | 2021-09-01T16:23:54:INFO:hypercorn.error: Running on https://0.0.0.0:4566 (CTRL + C to quit) localstack_1 | [2021-09-01 16:23:54 +0000] [21] [INFO] Running on http://0.0.0.0:44089 (CTRL + C to quit) localstack_1 | 2021-09-01T16:23:54:INFO:hypercorn.error: Running on http://0.0.0.0:44089 (CTRL + C to quit) localstack_1 | Waiting for all LocalStack services to be ready localstack_1 | Starting mock SQS service on http port 4566 ... localstack_1 | Ready. LOCALSTACK
  22. @maciejwalkowiak @matejnedic1 $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566

    LOCALSTACK { "QueueUrl": "http://localhost:4566/000000000000/hello-springone" }
  23. @maciejwalkowiak @matejnedic1 $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566

    LOCALSTACK { "QueueUrl": "http://localhost:4566/000000000000/hello-springone" } $ aws sqs list-queues --endpoint-url http://localhost:4566
  24. @maciejwalkowiak @matejnedic1 $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566

    LOCALSTACK { "QueueUrl": "http://localhost:4566/000000000000/hello-springone" } $ aws sqs list-queues --endpoint-url http://localhost:4566 { "QueueUrls": [ "http://localhost:4566/000000000000/testqueue", "http://localhost:4566/000000000000/hello-springone" ] }
  25. @maciejwalkowiak @matejnedic1 @SpringBootTest @Testcontainers class DemoApplicationTests { @Container static LocalStackContainer

    localstack = new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.12.17")) .withServices(LocalStackContainer.Service.SQS); @DynamicPropertySource static void localstackProperties(DynamicPropertyRegistry registry) { registry.add("clous.aws.sqs.endpoint", () -> localstack.getEndpointOverride(LocalStackContainer.Service.SQS)); } // .. } LOCALSTACK
  26. @maciejwalkowiak @matejnedic1 LOCALSTACK • ACM • API Gateway • CloudFormation

    • CloudWatch • CloudWatch Logs • DynamoDB • DynamoDB Streams • EC2 • Elasticsearch Service • EventBridge (CloudWatch Events) • Firehose • IAM • Kinesis • KMS • Lambda • Redshift • STS • Route53 • S3 • SecretsManager • SES • SNS • SQS • SSM • StepFunctions
  27. @maciejwalkowiak @matejnedic1 LOCALSTACK • Amplify • API Gateway V2 (WebSockets

    support) • AppConfig • Application AutoScaling • AppSync • Athena • Backup • Batch • CloudFront • CloudTrail • CodeCommit • Cognito • CostExplorer • DocumentDB • ECR/ECS/EKS • ElastiCache • ElasticBeanstalk • ELB/ELBv2 • EMR • Glacier / S3 Select • Glue • IAM Security Policy Enforcement • IoT • Kinesis Data Analytics • Lambda Layers & Container Images
  28. @maciejwalkowiak @matejnedic1 •Migrate from AWS SDK v1 to AWS SDK

    v2 •CloudMap integration (PR ready) •Spring Data Dynamo DB (?) •Drop support for: ElastiCache, CloudFormation •Improve startup times •GraalVM Native Image compatibility FUTURE  SPRING CLOUD AWS 3.X