Pro Java Microservices with Quarkus and A Hands-on Guide

Nebrass Lamouchi Pro Java Microservices with Quarkus and Kubernetes: A Hands-on Guide Nebrass Lamouchi Paris, France

ISBN-13 (pbk): 978-1-4842-7169-8 ISBN-13 (electronic): 978-1-4842-7170-4 https://doi.org/10.1007/978-1-4842-7170-4 Copyright © 2021 by Nebrass Lamouchi This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer , or by similar or dissimilar methodology now known or hereafter developed. Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Managing Director, Apress Media LLC: Welmoed Spahr Acquisitions Editor: Steve Anglin Development Editor: Matthew Moodie Coordinating Editor: Mark Powers Cover designed by eStudioCalamar Cover image by Robert Shunev on Unsplash (www.unsplash.com) Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004, U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or visit www. springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please e-mail [email protected]; for reprint, paperback, or audio rights, please e-mail [email protected]. Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at http://www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub via the book’s product page, located at www.apress.com/9781484271698. For more detailed information, please visit http://www.apress.com/source-code. Printed on acid-free paper To Mom, it’s impossible to thank you adequately for everything you’ve done. To the soul of Dad, I miss you every day… To Firass, you are the best, may God bless you… To my sweetheart, since you’ve come into my life, there are so many new emotions and feelings begging to come out… Table of Contents

About the Author ����������������������������������������������������������������������������������������������������� xi About the Technical Reviewer ������������������������������������������������������������������������������� xiii Acknowledgments ���������������������������������������������������������������������������������������������������xv Preface ������������������������������������������������������������������������������������������������������������������xvii Introduction ������������������������������������������������������������������������������������������������������������xxi

Chapter 1: Getting Started with Containerization ����������������������������������������������������� 1 Introducing Containerization ��������������������������������������������������������������������������������������������������������� 1 Introducing ������������������������������������������������������������������������������������������������������������������������ 2 The Dockerfile ������������������������������������������������������������������������������������������������������������������������� 3 Images and Containers ������������������������������������������������������������������������������������������������������������ 3 Installing Docker ��������������������������������������������������������������������������������������������������������������������������� 3 Running Your First Container �������������������������������������������������������������������������������������������������������� 4 Understanding the Docker Architecture ���������������������������������������������������������������������������������������� 6 Docker Objects ������������������������������������������������������������������������������������������������������������������������ 7 Docker Machine ����������������������������������������������������������������������������������������������������������������������� 7 Diving Into Docker Containers ������������������������������������������������������������������������������������������������������� 8 Docker Containers in Development Environments ������������������������������������������������������������������ 8 Define a Container with Dockerfile ������������������������������������������������������������������������������������������ 8 Play with Google Jib �������������������������������������������������������������������������������������������������������������� 20 Meeting the Docker Services ������������������������������������������������������������������������������������������������������ 22 Create the First docker-compose.yml File ����������������������������������������������������������������������������� 23 Achieving More with Docker ������������������������������������������������������������������������������������������������������� 24 Get the Needed Tools Quickly ������������������������������������������������������������������������������������������������ 24 Unleash the Requirements Chains ���������������������������������������������������������������������������������������� 26

v Table of Contents

Containerization Is Not Docker Only �������������������������������������������������������������������������������������������� 29 What Are Docker’s Limitations? ��������������������������������������������������������������������������������������������� 29 Meet Podman and Buildah ���������������������������������������������������������������������������������������������������� 30 Conclusion ���������������������������������������������������������������������������������������������������������������������������������� 33

Chapter 2: Introduction to the Monolithic Architecture ������������������������������������������ 35 Introduction to an Actual Situation ���������������������������������������������������������������������������������������������� 35 Presenting the Context ���������������������������������������������������������������������������������������������������������������� 36 Solving These Issues ������������������������������������������������������������������������������������������������������������������� 38

Chapter 3: Coding a Monolithic Application ����������������������������������������������������������� 39 Presenting the Domain ���������������������������������������������������������������������������������������������������������������� 39 Use Case Diagram ����������������������������������������������������������������������������������������������������������������� 39 Class Diagram ����������������������������������������������������������������������������������������������������������������������� 41 Sequence Diagram ���������������������������������������������������������������������������������������������������������������� 42 Coding the Application ���������������������������������������������������������������������������������������������������������������� 42 Presenting the Technology Stack ������������������������������������������������������������������������������������������ 43 Implementing the QuarkuShop ���������������������������������������������������������������������������������������������� 47 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 111

Chapter 4: Upgrading a Monolithic Application ���������������������������������������������������� 113 Implementing QuarkuShop Tests ���������������������������������������������������������������������������������������������� 113 Introducing Tests Libraries in Quarkus �������������������������������������������������������������������������������� 113 Writing the First Tests ���������������������������������������������������������������������������������������������������������� 119 Discovering SonarQube ������������������������������������������������������������������������������������������������������� 127 Building and Running QuarkuShop ������������������������������������������������������������������������������������������� 135 Building the QuarkuShop ����������������������������������������������������������������������������������������������������� 135 Packaging and Running the Native QuarkuShop ����������������������������������������������������������������� 140 Differences Between the JVM and Native Modes ��������������������������������������������������������������� 146 The Magic Behind GraalVM’s Power ������������������������������������������������������������������������������������ 153 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 153

vi Table of Contents

Chapter 5: Building and Deploying a Monolithic Application ������������������������������� 155 Introduction ������������������������������������������������������������������������������������������������������������������������������� 155 Importing the Project into Azure DevOps ���������������������������������������������������������������������������������� 155 Creating the CI/CD Pipelines ����������������������������������������������������������������������������������������������������� 161 Creating the Continuous Integration Pipeline ���������������������������������������������������������������������� 161 Making the Continuous Deployment Pipeline ���������������������������������������������������������������������� 169 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 186

Chapter 6: Adding Anti-Disaster Layers ��������������������������������������������������������������� 187 Introduction ������������������������������������������������������������������������������������������������������������������������������� 187 Implementing the Security Layer ���������������������������������������������������������������������������������������������� 188 Analyzing Security Requirements and Needs ���������������������������������������������������������������������� 188 Defining Authorization Matrices for REST APIs �������������������������������������������������������������������� 190 Implementing the Security Layer ���������������������������������������������������������������������������������������� 193 Implementing the Monitoring Layer ������������������������������������������������������������������������������������������ 238 Implementing Health Checks ����������������������������������������������������������������������������������������������� 238 Implementing the Metrics Service �������������������������������������������������������������������������������������� 243 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 251

Chapter 7: Microservices Architecture Pattern ���������������������������������������������������� 253 Introduction ������������������������������������������������������������������������������������������������������������������������������� 253 Microservices Architecture ������������������������������������������������������������������������������������������������������� 255 Benefits of a Microservices Architecture ����������������������������������������������������������������������������� 255 What Really Is a Microservice? ������������������������������������������������������������������������������������������� 256 Conclusion: Making the Switch ������������������������������������������������������������������������������������������������� 257

Chapter 8: Splitting the Monolith: Bombarding the Domain ��������������������������������� 259 Introduction ������������������������������������������������������������������������������������������������������������������������������� 259 What Is Domain-Driven Design? ����������������������������������������������������������������������������������������������� 259 Context �������������������������������������������������������������������������������������������������������������������������������� 260 Domain �������������������������������������������������������������������������������������������������������������������������������� 260 Model ����������������������������������������������������������������������������������������������������������������������������������� 260

vii Table of Contents

Ubiquitous Language ����������������������������������������������������������������������������������������������������������� 260 Strategic Design ������������������������������������������������������������������������������������������������������������������ 260 Bombarding QuarkuShop ���������������������������������������������������������������������������������������������������������� 262 Codebase ����������������������������������������������������������������������������������������������������������������������������� 262 Dependencies and Commons ��������������������������������������������������������������������������������������������������� 262 Entities �������������������������������������������������������������������������������������������������������������������������������������� 262 Example: Breaking Foreign Key Relationships �������������������������������������������������������������������� 263 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 264

Chapter 9: Applying DDD to the Code ������������������������������������������������������������������� 265 Applying Bounded Contexts to Java Packages ������������������������������������������������������������������������� 265 The Birth of the Commons Package ������������������������������������������������������������������������������������ 266 Locating the Bounded Contexts Relationships �������������������������������������������������������������������� 267 Breaking the BC Relationships �������������������������������������������������������������������������������������������� 269 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 275

Chapter 10: Meeting the Microservices Concerns and Patterns �������������������������� 277 Cloud Patterns �������������������������������������������������������������������������������������������������������������������������� 277 Service Discovery and Registration ������������������������������������������������������������������������������������� 278 Externalized Configuration �������������������������������������������������������������������������������������������������� 279 Circuit Breaker ��������������������������������������������������������������������������������������������������������������������� 280 Database Per Service ���������������������������������������������������������������������������������������������������������� 281 API Gateway ������������������������������������������������������������������������������������������������������������������������ 282 CQRS ������������������������������������������������������������������������������������������������������������������������������������ 283 Event Sourcing �������������������������������������������������������������������������������������������������������������������� 285 Log Aggregation ������������������������������������������������������������������������������������������������������������������ 286 Distributed Tracing �������������������������������������������������������������������������������������������������������������� 287 Audit Logging ���������������������������������������������������������������������������������������������������������������������� 287 Application Metrics �������������������������������������������������������������������������������������������������������������� 288 Health Check API ����������������������������������������������������������������������������������������������������������������� 288 Security Between Services: Access Token �������������������������������������������������������������������������� 289 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 289 viii Table of Contents

Chapter 11: Getting Started with Kubernetes ������������������������������������������������������� 291 Introduction ������������������������������������������������������������������������������������������������������������������������������� 291 What Is Kubernetes? ����������������������������������������������������������������������������������������������������������������� 292 The Kubernetes Architecture ����������������������������������������������������������������������������������������������� 292 Kubernetes Core Concepts �������������������������������������������������������������������������������������������������� 294 Run Kubernetes Locally ������������������������������������������������������������������������������������������������������������ 302 Practical Summary and Conclusion ������������������������������������������������������������������������������������������ 304 Additional Reading �������������������������������������������������������������������������������������������������������������������� 306

Chapter 12: Implementing the Cloud Patterns ������������������������������������������������������ 309 Introduction ������������������������������������������������������������������������������������������������������������������������������� 309 Bringing the Monolithic Universe to Kubernetes ����������������������������������������������������������������������� 309 Deploying PostgreSQL to Kubernetes ���������������������������������������������������������������������������������� 309 Deploying Keycloak to Kubernetes �������������������������������������������������������������������������������������� 315 Deploying the Monolithic QuarkuShop to Kubernetes ��������������������������������������������������������� 321 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 332

Chapter 13: Building the Kubernetized Microservices ����������������������������������������� 333 Introduction ������������������������������������������������������������������������������������������������������������������������������� 333 Creating the Commons Library ������������������������������������������������������������������������������������������������� 334 Implementing the Product Microservice ����������������������������������������������������������������������������������� 338 Implementing the Order Microservice �������������������������������������������������������������������������������������� 346 Implementing the Customer Microservice �������������������������������������������������������������������������������� 356 Implementing the User Microservice ���������������������������������������������������������������������������������������� 359 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 361

Chapter 14: Flying All Over the Sky with Quarkus and Kubernetes ��������������������� 363 Introduction ������������������������������������������������������������������������������������������������������������������������������� 363 Implementing the Circuit Breaker Pattern �������������������������������������������������������������������������������� 364 Implementing the Log Aggregation Pattern ������������������������������������������������������������������������������ 368 Step 1: Deploying the ELK Stack to Kubernetes ������������������������������������������������������������������ 369 Step 2: Configuring the Microservices to Log Into the ELK Stack ��������������������������������������� 375 Step 3: Collecting Logs �������������������������������������������������������������������������������������������������������� 376 ix Table of Contents

Implementing the Distributed Tracing Pattern �������������������������������������������������������������������������� 380 Step 1: Deploying the Jaeger All-in-One to Kubernetes ������������������������������������������������������ 381 Step 2: Enabling Jaeger Support in Our Microservices ������������������������������������������������������� 387 Step 3: Collecting Traces ����������������������������������������������������������������������������������������������������� 389 Implementing the API Gateway Pattern ������������������������������������������������������������������������������������ 391 Step 1: Enabling Ingress Support in Minikube ��������������������������������������������������������������������� 392 Step 2: Creating the API Gateway Ingress ��������������������������������������������������������������������������� 392 Step 3: Testing Ingress �������������������������������������������������������������������������������������������������������� 395 Conclusion �������������������������������������������������������������������������������������������������������������������������������� 395

Afterword: Final Words and Thoughts ������������������������������������������������������������������ 397

Index ��������������������������������������������������������������������������������������������������������������������� 399

x About the Author

Nebrass Lamouchi is a senior software engineer at Microsoft who is addicted to Java and cloud technologies. He is also a former NetBeans Dream Team member. Nebrass was one of the four happy winners of the Oracle Groundbreaker Awards in May, 2019. He has also been a project leader on the Barbarus Project for the OWASP Foundation since March, 2013. He is the author of the following books: • Playing with Java Microservices on Kubernetes and OpenShift, published with Leanpub, November 2018. • Pairing Apache Shiro with Java EE 7, published with InfoQ, May 2016.

Nebrass graduated with an M.Sc Degree in Information Systems Security and a Bachelor’s Degree in Computing Sciences and Management from the Higher Institute of Management of Tunis, Tunisia. Over the past eight years, he has worked on Java SE/EE projects in many sectors, including business management, petroleum, finance and banking, medical and healthcare, and defense and space. He has developed applications using many frameworks and Java-related technologies, such as native Java EE APIs and third-party frameworks and tools (Spring, Quarkus, , Primefaces, JBoss Forge). He has managed and used infrastructure and programming tools such as DBMS, Java EE servers (Glassfish and JBoss), quality and continuous integration/deployment tools (Sonar, Jenkins, and Azure DevOps), and Docker, Kubernetes, and OpenShift.​

xi About the Technical Reviewer

Georgios Andrianakis is a principal software engineer working for Red Hat. He works on Java frameworks like Spring and Quarkus, while also exploring their synergies with cloud-native systems like Kubernetes and OpenShift.

xiii Acknowledgments

I would like to express my gratitude to the many people who saw me through this book. To all those who provided support, read, wrote, offered comments, and assisted in its editing and design. Many thanks to the great Georgios Andrianakis for his technical review and guidelines that helped me write this book. To my wife and my family, thank you for all your great support and encouragement. To Laurent Ellerbach, thank you for all your support and guidance! Last and not least, I beg forgiveness from all those who have been with me over the course of many years and whose names I have failed to mention.

xv Preface

Pro Java Microservices with Quarkus and Kubernetes will teach you how to build and design microservices using Java and the Quarkus platform. This book covers topics related to developing Java microservices and deploying them to Kubernetes. Traditionally, Java developers are used to developing large, complex, monolithic applications. The process of developing and deploying monoliths has always been slow and painful. This book will help Java developers quickly get started with the features and concerns of the microservices architecture. It will introduce Docker and Kubernetes for the deployment in the cloud. This book is aimed at Java developers who want to build microservices using the new stack and who want to deploy them to Kubernetes. You will be guided on how to install the appropriate tools, and for those who are new to enterprise development using Quarkus, you will be introduced to its core principles and main features through a deep step-by-step tutorial of its many components. For those who have prior experience using Quarkus for enterprise development, this book offers some recipes that illustrate how to split monoliths and implement microservices and deploy them as containers to Kubernetes. Here are some of the key challenges that I address in this book: • Introducing containerization with Docker • Introducing Quarkus for beginners • Implementing a sample monolithic application • Splitting a monolith using the domain driven design (DDD) approach • Implementing the cloud patterns • Rethinking the deployment process • Introducing the Kubernetes world • Introducing best practices and the recommended patterns while creating cloud-native applications

xvii Preface

By the end of this book, you will have practical hands-on experience building microservices using Quarkus and you will be able to deploy them as containers to Kubernetes.

What This Book Covers

• Chapter 1, “Getting Started with Containerization,” presents containerization with Docker and Podman. • Chapter 2, “Introduction to the Monolithic Architecture,” provides an introduction to monolithic architecture with a focus on its advantages and drawbacks. • Chapter 3, “Coding a Monolithic Application,” includes a step-by- step tutorial for modeling and creating a monolith using Maven, Java 11, and Quarkus. • Chapter 4, “Upgrading a Monolithic Application,” lists some upgrades for our monolithic application, such as adding tests and most-wanted features. • Chapter 5, “Building and Deploying a Monolithic Application,” covers how to build and package the example application before showing how to deploy it in the runtime environment. • Chapter 6, “Adding Anti-Disaster Layers,” introduces how to implement the security and monitoring layers to help the application avoid disasters. • Chapter 7, “Microservices Architecture Pattern,” presents the drawbacks that can be faced in a typical monolithic architecture and illustrates the need something new, like the Microservices Architecture Pattern. • Chapter 8, “Splitting the Monolith: Bombarding the Domain,” presents domain driven design concepts to help you understand the business domain of a monolithic application, and to be able to split it into subdomains.

xviii Preface

• Chapter 9, “Applying DDD to the Code,” shows how to apply all the DDD concepts to the monolithic application source code and to successfully split the monolith into bounded contexts. • Chapter 10, “Meeting the Microservices Concerns and Patterns,” offers a deep presentation of the concerns and cloud patterns related to the Microservices Architecture Pattern. • Chapter 11, “Getting Started with Kubernetes,” covers how to build real standalone business microservices. • Chapter 12, “Implementing Cloud Patterns,” presents an in-depth examination of the most efficient container orchestrator: Kubernetes. • Chapter 13, “Building Kubernetized Microservices,” shows how to migrate a monolith’s code to build microservices while applying Kubernetes concepts and features. • Chapter 14, “Flying all Over the Sky with Quarkus and Kubernetes,” explains how implement additional cloud patterns using Quarkus and Kubernetes. • And more The source code of this book is available via the Download Source Code link located at www.apress.com/9781484271698.

Reader Feedback

I always welcome feedback from my great readers. Please let me know what you thought about this book—what you liked or disliked. If you have any questions or inquiries, feel free to get in touch by emailing me at [email protected].

xix Introduction

Quarkus is the latest Java Framework project in the long list of frameworks created by Red Hat. First released in 2018, it’s the successor to the WildFly Swarm and Thorntail frameworks. These two frameworks came to market in the golden age of the Spring Boot Framework. This is why they were defeated and didn’t win the battle. After test-running WildFly Swarm on my own projects, I decided not to adopt it. Why did Red Hat make another framework? What does this framework bring to the table? Red Hat is one of the biggest contributors to the Java platform, from design and specifications to providing implementations and tooling. While contributing to the GraalVM project, Red Hat spotted an opportunity to create a framework specifically geared toward this great project and to the cloud. Wait! What is GraalVM, and what is its added value? From the Oracle official documentation:

GraalVM is a high-performance runtime that provides significant improve- ments in application performance and efficiency, which is ideal for μservices. It is designed for applications written in Java, JavaScript, LLVM-­ based languages such as C and C++, and other dynamic languages. It removes the isolation between programming languages and enables interoperability in a shared runtime. It can run either standalone or in the context of OpenJDK, Node.js, or Oracle Database. GraalVM can run in the context of OpenJDK to make Java applications run faster with a new just-in-time compilation technology. GraalVM takes over the compilation of Java bytecode to machine code. The compiler of GraalVM provides performance advantages for highly abstracted programs due to its ability to remove costly object allocations in many scenarios. —Official GraalVM Documentation from Oracle at https://www.graalvm.org/docs/why-­ ­graal/

xxi Introduction

This abstract definition probably doesn’t give you a clear view of this runtime. But what’s sure is that you can see how many times the word “performance” appears in it. In my words, GraalVM offers the ability to compile your Java code into a native executable binary, which will be executed natively in the operating system without the Java runtime. The native executable binary offers two main features: • Much faster startup • Lower memory footprint Here, Red Hat found a big opportunity to make a Java Framework dedicated to this high-performance runtime. This is what encouraged them to give Quarkus a slogan: Supersonic Subatomic Java. It’s not sufficient to make a framework just based on a specific runtime. Red Hat had the same point of view, so they added more features (that we will cover later) to their checklist so that their framework can compete against Spring Boot! This is what attracted me to Quarkus! I wanted to see how Red Hat compared to Spring Boot. In this book, I try to introduce Quarkus and GraalVM to you in a soft way. If you are a beginner, you will not have a lot of problems dealing with it. Maybe you will not see many differences between it and Spring Boot, and I try to make the picture clear for you! We will start by building a small “Hello World” application using Quarkus and then begin making our monolith, which we will migrate to the microservices architecture. You can jump to Chapter 2 if you are already familiar with the Quarkus platform.

xxii