Continuous Delivery in Java

Book description

Continuous delivery adds enormous value to the business and the entire software delivery lifecycle, but adopting this practice means mastering new skills typically outside of a developer’s comfort zone. In this practical book, Daniel Bryant and Abraham Marín-Pérez provide guidance to help experienced Java developers master skills such as architectural design, automated quality assurance, and application packaging and deployment on a variety of platforms.

Not only will you learn how to create a comprehensive build pipeline for continually delivering effective software, but you’ll also explore how Java application architecture and deployment platforms have affected the way we rapidly and safely deliver new software to production environments.

  • Get advice for beginning or completing your migration to continuous delivery
  • Design architecture to enable the continuous delivery of Java applications
  • Build application artifacts including fat JARs, virtual machine images, and operating system container (Docker) images
  • Use continuous integration tooling like Jenkins, PMD, and find-sec-bugs to automate code quality checks
  • Create a comprehensive build pipeline and design software to separate the deploy and release processes
  • Explore why functional and system quality attribute testing is vital from development to delivery
  • Learn how to effectively build and test applications locally and observe your system while it runs in production

Publisher resources

View/Submit Errata

Table of contents

  1. Forewords
  2. Preface
    1. Why Did We Write This Book?
    2. Why You Should Read This Book
    3. What This Book Is Not
    4. Conventions Used in This Book
    5. Using Code Examples
    6. O’Reilly Safari
    7. How to Contact Us
    8. Acknowledgments
  3. 1. Continuous Delivery: Why and What
    1. Setting the Scene
    2. Enabling Developers: The Why
      1. Rapid Feedback Reduces Context Switching
      2. Automatic, Repeatable, and Reliable Releases
      3. Codifying the Definition of “Done”
    3. Exploring a Typical Build Pipeline: The What
      1. Core Build Pipeline Stages
      2. Impact of Container Technology
      3. Changes with Contemporary Architectures
    4. Summary
  4. 2. Evolution of Java Development
    1. Requirements of Modern Java Applications
      1. Need for Business Speed and Stability
      2. Rise of the API Economy
      3. Opportunities and Costs of the Cloud
      4. Modularity Redux: Embracing Small Services
      5. Impact on Continuous Delivery
    2. Evolution of Java Deployment Platforms
      1. WARs and EARs: The Era of Application Server Dominance
      2. Executable Fat JARs: Emergence of Twelve-Factor Apps
      3. Container Images: Increasing Portability (and Complexity)
      4. Function as a Service: The Emergence of “Serverless”
      5. Impact of Platforms on Continuous Delivery
    3. DevOps, SRE, and Release Engineering
      1. Development and Operations
      2. Site Reliability Engineering
      3. Release Engineering
      4. Shared Responsibility, Metrics, and Observability
    4. Summary
  5. 3. Designing Architecture for Continuous Delivery
    1. Fundamentals of Good Architecture
      1. Loose Coupling
      2. High Cohesion
      3. Coupling, Cohesion, and Continuous Delivery
    2. Architecture for Business Agility
      1. Bad Architecture Limits Business Velocity
      2. Complexity and Cost of Change
    3. Best Practices for API-Driven Applications
      1. Build APIs “Outside-In”
      2. Good APIs Assist Continuous Testing and Delivery
    4. Deployment Platforms and Architecture
      1. Designing Cloud-Native “Twelve-Factor” Applications
      2. Cultivating Mechanical Sympathy
      3. Design and Continually Test for Failure
    5. The Move Toward Small Services
      1. Challenges for Delivering Monolithic Applications
      2. Microservices: SOA Meets Domain-Driven Design
      3. Functions, Lambdas, and Nanoservices
    6. Architecture: “The Stuff That’s Hard to Change”
    7. Summary
  6. 4. Deployment Platforms, Infrastructure, and Continuous Delivery of Java Apps
    1. Functionality Provided by a Platform
    2. Essential Development Processes
    3. Traditional Infrastructure Platforms
      1. Traditional Platform Components
      2. Challenges with Traditional Infrastructure Platforms
      3. Benefits of Being Traditional
      4. CI/CD on Traditional Infrastructure Platforms
    4. Cloud (IaaS) Platform
      1. Looking Inside the Cloud
      2. Cloud Challenges
      3. Benefits of the Cloud
      4. Continuously Delivering into the Cloud
    5. Platform as a Service
      1. Peeking Inside a PaaS
      2. PaaS Challenges
      3. Benefits of PaaS
      4. CI/CD and PaaS
    6. Containers (Docker)
      1. Container Platform Components
      2. Container Challenges
      3. Container Benefits
      4. Continuously Delivering Containers
    7. Kubernetes
      1. Core Concepts of Kubernetes
      2. Kubernetes Challenges
      3. Benefits of Kubernetes
      4. Continuous Delivery on Kubernetes
    8. Function-as-a-Service/Serverless Functions
      1. FaaS Concepts
      2. Challenges of FaaS
      3. FaaS Benefits
      4. CI/CD and FaaS
    9. Working with Infrastructure as Code
    10. Summary
  7. 5. Building Java Applications
    1. Breaking Down the Build Process
    2. Automating the Build
      1. Build Dependencies
      2. External Dependencies
      3. Multimodule Projects
      4. Multiple Repositories (or a Monorepo)?
      5. Plugins
      6. Releasing and Publishing Artifacts
    3. Java Build Tooling Overview
      1. Ant
      2. Maven
      3. Gradle
      4. Bazel, Pants, and Buck
      5. Other JVM Build Tools: SBT and Leiningen
      6. Make
    4. Choosing a Build Tool
    5. Summary
  8. 6. Additional Build Tooling and Skills
    1. Linux, Bash, and Basic CLI Commands
      1. Users, Permissions, and Groups
      2. Working with the Filesystem
      3. Viewing and Editing Text
      4. Joining Everything Together: Redirects, Pipes, and Filters
      5. Searching and Manipulating Text: grep, awk, and sed
      6. Diagnostic Tooling: top, ps, netstat, and iostat
    2. HTTP Calls and JSON Manipulation
      1. curl
      2. HTTPie
      3. jq
    3. Basic Scripting
      1. xargs
      2. Pipes and Filters
      3. Loops
      4. Conditionals
    4. Summary
  9. 7. Packaging Applications for Deployment
    1. Building a JAR: Step-by-Step
    2. Building a Fat Executable “Uber” JAR
      1. Maven Shade Plugin
      2. Building Spring Boot Uber JARs
    3. Skinny JARs—Deciding Not to Build Fat JARs
    4. Building WAR Files
    5. Packaging for the Cloud
      1. Cooking Configuration: Baking or Frying Machines
      2. Building RPMs and DEBs OS Packages
      3. Additional OS Package Build Tools (with Windows Support)
      4. Creating Machine Images for Multiple Clouds with Packer
      5. Additional Tools for Creating Machine Images
    6. Building Containers
      1. Creating Container Images with Docker
      2. Fabricating Docker Images with fabric8
    7. Packaging FaaS Java Applications
    8. Summary
  10. 8. Working Locally (Like It Was Production)
    1. Challenges with Local Development
    2. Mocking, Stubbing, and Service Virtualization
      1. Pattern #1: Profiles, Mocks, and Stubs
      2. Mocking with Mockito
      3. Pattern #2: Service Virtualization and API Simulation
      4. Virtualizing Services with Hoverfly
    3. VMs: Vagrant and Packer
      1. Installing Vagrant
      2. Creating a Vagrantfile
      3. Pattern #3: Production-in-a-Box
    4. Containers: Kubernetes, minikube, and Telepresence
      1. Introducing the “Docker Java Shop” Sample App
      2. Building Java Applications and Container Images
      3. Deploying into Kubernetes
      4. Simple Smoke Test
      5. Building the Remaining Applications
      6. Deploying the Entire Java Application in Kubernetes
      7. Viewing the Deployed Application
      8. Telepresence: Working Remotely, Locally
      9. Pattern #4: Environment Leasing
    5. FaaS: AWS Lamba and SAM Local
      1. Installing SAM Local
      2. AWS Lambda Scaffolding
      3. Testing AWS Lambda Event Handling
      4. Smoke Testing with SAM Local
    6. FaaS: Azure Functions and VS Code
      1. Installing Azure Function Core Tools
      2. Building and Testing Locally
      3. Testing Remotely, Locally Using VS Code
    7. Summary
  11. 9. Continuous Integration: The First Steps in Creating a Build Pipeline
    1. Why Continuous Integration?
    2. Implementing CI
    3. Centralized Versus Distributed Version-Control Systems
    4. Git Primer
      1. Core Git CLI Commands
      2. Hub: An Essential Tool for Git and GitHub
    5. Working Effectively with DVCS
      1. Trunk-based Development
      2. Feature Branching
      3. Gitflow
      4. No One-Size Fits All: How to Choose a Branching Strategy
    6. Code Reviews
      1. What to Look For
      2. Automation: PMD, Checkstyle, and FindBugs
      3. Reviewing Pull Requests
    7. Automating Builds
      1. Jenkins
    8. Getting Your Team Onboard
      1. Merge Code Regularly
      2. “Stop the Line!”: Managing Broken Builds
      3. Don’t @Ignore Tests
      4. Keep the Build Fast
    9. CI of the Platform (Infrastructure as Code)
    10. Summary
  12. 10. Deploying and Releasing from the Pipeline
    1. Introducing the Extended Java Shop Application
    2. Separating Deployment and Release
    3. Deploying Applications
      1. Creating a Container Image
      2. Deployment Mechanisms
      3. It All Starts (and Ends) with Health Checks
      4. Deployment Strategies
      5. Working with Unmanaged Clusters
      6. Changing Databases
    4. Releasing Functionality
      1. Feature Flags
      2. Semantic Versioning (semver)
      3. Backward Compatibility and Versions in APIs
      4. Multiple-Phase Upgrades
    5. Managing Configuration and Secrets
      1. “Baked-In” Configuration
      2. Externalized Configuration
      3. Handling Secrets
    6. Summary
  13. 11. Functional Testing: Correctness and Acceptance
    1. Why Test Software?
    2. What to Test? Introducing Agile Testing Quadrants
    3. Continuous Testing
      1. Building the Right Feedback Loop
    4. Turtles All the Way Down
    5. Synthetic Transactions
    6. End-to-End Testing
    7. Acceptance Testing
      1. Behavior-Driven Development
      2. Stubbing or Virtualizing Third-Party Services
      3. Bringing It All Together
    8. Consumer-Driven Contracts
      1. RESTful API Contracts
      2. Message Contracts
    9. Component Testing
      1. Embedded Data Stores
      2. In-Memory Message Queues
      3. Test Doubles
      4. Creating Internal Resources/Interfaces
      5. In-Process Versus Out-Of-Process
    10. Integration Testing
      1. Verifying External Interactions
      2. Testing Fault Tolerance
    11. Unit Testing
      1. Sociable Unit Testing
      2. Solitary Unit Testing
    12. Dealing with Flaky Tests
      1. Data
      2. Resource That Is Not Available Yet
      3. Nondeterministic Events
      4. If Nothing Else Works
    13. Testing Outside-In Versus Testing Inside-Out
      1. Outside-In
      2. Inside-Out
    14. Putting It All Together Within the Pipeline
    15. How Much Testing Is Enough?
    16. Summary
  14. 12. System-Quality Attributes Testing: Validating Nonfunctional Requirements
    1. Why Test Nonfunctional Requirements?
    2. Code Quality
    3. Architectural Quality
      1. ArchUnit: Unit-Testing Architecture
      2. Generate Design-Quality Metrics with JDepend
    4. Performance and Load Testing
      1. Basic Performance Testing with Apache Benchmark
      2. Load Testing with Gatling
    5. Security, Vulnerabilities, and Threats
      1. Code-Level Security Verification
      2. Dependency Verification
      3. Deployment Platform-Specific Security Issues
      4. Next Steps: Threat Modeling
    6. Chaos Testing
      1. Causing Chaos in Production (Bring in the Monkeys)
      2. Causing Chaos in Preproduction
    7. How Much NFR Testing Is Enough?
    8. Summary
  15. 13. Observability: Monitoring, Logging, and Tracing
    1. Observability and Continuous Delivery
      1. Why Observe?
      2. What to Observe: Application, Network, and Machine
      3. How to Observe: Monitoring, Logging, and Tracing
      4. Alerting
    2. Designing Systems for Observability
    3. Metrics
      1. Type of Metrics
      2. Dropwizard Metrics
      3. Spring Boot Actuator
      4. Micrometer
      5. Best Practices with Metrics
    4. Logging
      1. Forms of Logging
      2. SLF4J
      3. Log4j 2
      4. Logging Best Practices
    5. Request Tracing
      1. Traces, Spans, and Baggage
      2. Java Tracing: OpenZipkin, Spring Sleuth, and OpenCensus
      3. Recommended Practices for Tracing
    6. Exception Tracking
      1. Airbrake
    7. System-Monitoring Tooling
      1. collectd
      2. rsyslog
      3. Sensu
    8. Collection and Storage
      1. Prometheus
      2. Elastic-Logstash-Kibana
    9. Visualization
      1. Visualization for Business
      2. Operational Visualization
      3. Visualization for Developers
    10. Summary
  16. 14. Migrating to Continuous Delivery
    1. Continuous Delivery Capabilities
    2. Picking Your Migration Project
    3. Situational Awareness
      1. The Cynefin Framework and Continuous Delivery
      2. All Models Are Wrong, Some Are Useful
    4. Bootstrapping Continuous Delivery
    5. Measuring Continuous Delivery
    6. Start Small, Experiment, Learn, Share, and Repeat
    7. Increase Adoption: Leading Change
    8. Additional Guidance and Tips
      1. Bad Practices and Common Antipatterns
      2. Ugly Architecture: To Fix, or Not to Fix
    9. Summary
  17. 15. Continuous Delivery and Continuous Improvement
    1. Start from Where You Are
    2. Build on Solid Technical Foundations
    3. Continuously Deliver Value (Your Highest Priority)
    4. Increase Shared Responsibility of Software
    5. Promote Fast Feedback and Experimentation
    6. Expand Continuous Delivery in an Organization
    7. Continuous Improvement
    8. Summary
  18. Index

Product information

  • Title: Continuous Delivery in Java
  • Author(s): Daniel Bryant, Abraham Marín-Pérez
  • Release date: November 2018
  • Publisher(s): O'Reilly Media, Inc.
  • ISBN: 9781491986028