Java 3 - 2026

Week 2

Lesson 1 - Setup Pet Clinic App. Deployment using Docker.
Lesson 2 - Create, Read, Update, Delete (CRUD) functionality.
Lesson 3 - Homepage with content from the database. Custom not found and error pages.
Lesson 4 - Users, roles, and permissions setup from Java 2. User Registration.
Lesson 5 - Login and logout. Cookies. User permission access.

Lesson 6 - Edit and delete user profile. Password reset.
Lesson 7 - Pagination. Filtering and limiting records by category.
Lesson 8 - Web Sockets.
Lesson 9 - Internationalization. Date and currency formatting.
Lesson 10 - Email and SMS messaging. Failed login attempts.
Lesson 11 - Shopping Cart. Payment processing.

Course Plan

  • Modify the Pet Clinic application based on the user stories and personas you created in Java 2.
  • Derive an entity-relationship diagram and SQL queries for the data you will collect.
  • Create user interface drawings and wireframes for all web layouts.
  • Write use case narratives and build diagrams for each feature you add.
  • Write unit tests as necessary.

Expectations

  • Navigate to your Azure Container App.
  • On the left menu, scroll down to Settings and click Custom domains.

  • Click + Add custom domain.

  • Select a Managed Certificate.

  • Type your registered domain name

  • Select A record for the Hostname record type.

  • Do not click "Add" yet. Look at the box that appears below. It will show you two critical values you need to copy:

    • A record IP address (A record or CNAME)

    • Verification ID (TXT, a long string of random characters)

Azure Custom Domain

  • I registered a domain using SiteGround.
  • Log in to SiteGround -> Websites -> Site Tools for your domain.

  • Go to Domain -> DNS Zone Editor. Add two records.

  • The "Proof of Ownership" (TXT)

    • Name: If using the root domain (domain.com), enter: asuid

      If using a subdomain (www.domain.com), enter: asuid.www
    • Value: Paste the Verification ID from Azure.

  • The Traffic Route (A Record)

    • Name: If using the root domain, leave it Empty (or type @).

      If using a subdomain (www), type www

    • Value: Paste the IP address from Azure.

SiteGround Registration

  • Go back to your Azure Portal tab.
  • Click the Validate button.

    • It might take 1–5 minutes for SiteGround's changes to propagate. If it fails, wait a few minutes and try clicking Validate again.

  • Once the checks turn green, click Add.

  • Click on the "Add Binding" option.

  • Select the existing certificate.

  • Click Add.

  • Azure will now issue a free SSL certificate for your SiteGround domain.

  • A secure lock icon will appear when you visit the domain in the browser shortly.

Finish and Secure in Azure

  • Install the AWS Command Line Interface (CLI).
  • Open a terminal and type this command to confirm it was installed.
    aws --version
  • For AWS, the direct equivalent to Azure Container Apps is AWS App Runner. It is the modern, "serverless" way to run containers without managing servers.
  • Unlike Azure (and Google Cloud), AWS App Runner does not support pulling images directly from Docker Hub. It only trusts its own registry, called Amazon ECR (Elastic Container Registry).
  • Sign in to the AWS Management Console as the root user.
  • Using your "Root" account (the email/password you use to log into the console) can be a major security risk, especially for the CLI

AWS

  • Search for IAM in the top search bar and click it (Identity and Access Management).
  • On the left menu, click Users.

  • You will create a limited "Service User" that can only touch Container Registry (ECR) and App Runner.
  • Click the orange Create user button.

  • User details:

    • User name: petclinic-deployer (or whatever you prefer).

    • Leave the "Provide user access to the AWS Management Console" box unchecked. (This user is for the CLI only, not for clicking around the website).

    • Click Next.

Create a User in AWS IAM

  • We are going to attach two specific "Managed Policies." This gives the user power over only the tools you are currently using.

  • Permission options: Select Attach policies directly.

  • Permissions policies: In the search box, type and check the box for these two policies:

    • AmazonEC2ContainerRegistryPowerUser (This allows reading/writing images to the registry, but prevents deleting the registry itself.)

    • AWSAppRunnerFullAccess (This allows the user to create and manage the App Runner service.)

  • Click Next.

  • Review and click Create user.

Grant Permissions

  • Now that the user exists, you need to generate the "password" (Keys) for your terminal.

  • You should be back on the "Users" list. Click on the name of the user you just created (petclinic-deployer).

  • Click the Security credentials tab.

  • Scroll down to the Access keys section and click Create access key.

  • For the UseCase , select Command Line Interface (CLI).

  • Scroll down, check the "I understand..." confirmation box, and click Next.

  • (Optional) Set a description tag like "Laptop CLI", then click Create access key.

Create Access Keys

  • You will see an Access Key ID (starts with AKIA...) and a Secret Access Key (a long string of random characters).

  • Download the .csv file.

  • This is the only time AWS will ever show you the Secret Key. If you close this window without saving it, you have to delete the key and start over.

Create Access Keys

  • In the AWS Management Console, search for "ECR" or "Elastic Container Registry".
  • Click Create repository.

  • Give the repository a name, like petclinic.

  • Click Create.

  • Click the radio button next to the repository's name.
  • Click the View push commands button in the top right.

  • AWS provides 4 commands you need to run. We'll do that in a later slide.

Create Repository

  • Go back to your terminal and run this command:
    aws configure

  • It will ask you four questions. Copy/paste the answers from the CSV file you downloaded.

    • AWS Access Key ID: [Paste the AKIA... string]

    • AWS Secret Access Key: [Paste the secret string]

    • Default region name: Look at your ECR push command from before. If it said ecr.us-east-1.amazonaws.com, type us-east-1. If it said us-east-2 (Ohio) or us-west-2 (Oregon), match that.

    • Default output format: json

  • Run this command. If it replies with an "Arn" that ends in user/project-name-deployer, you are authenticated safely.
    aws sts get-caller-identity

Configure Your Computer

  • Run those 4 commands in your terminal (PowerShell).
    • Command 1: Logs your local Docker client into AWS.

    • Command 2: Builds the image (you can skip this since you already built it).

    • Command 3: Tags your existing image.

    • Command 4: Pushes the image to AWS.

  • Before running commands 3 and4, run this command and use the name of your image.
    docker images

  • After running command 3, run the docker images command again to verify that both images share the same ID.

  • After running command 4, go back to the AWS Managment Console, close the push commands modal, and click the copy URI button.

Create Repository

  • In the AWS Management Console, search for "App Runner" in the top search bar.
  • Click Create an App Runner service.

  • Select "Container registry" for the repository type.

  • Select "Amazon ECR" as the provider (the Private one, not Public).

  • Paste your container image URI or click the Browse button to select your image repository and tag.

  • Select "Create new service role". It will likely suggest a default name like AppRunnerECRAccessRole. You can leave this as is.

  • Click Next.

Create Service

  • Enter "petclinic-service" for the Service name.
  • 1 vCPU and 2 GB Memory is a safe choice for Spring Boot. It balances cost with the assurance that your app will actually start up without crashing or timing out. Read more on the next slides.

  • Environment variables: Click "Add environment variable" for each of your secrets:

    • MYSQL_URL : jdbc:mysql://...

    • MYSQL_USER : ...

    • MYSQL_PASS : ...

  • Enter "8080" for the port number for Spring Boot projects.

  • Click Next.
  • Click "Create & deploy" at the end of the Review & Create page.
  • It will take several minutes to provision the infrastructure, pull your image, and go live. Be patient.

Configure Service

  • Think of this as the "horsepower" of your engine.

  • It determines how fast your code executes, and especially for Spring Boot, it determines how fast your app starts.

  • 0.25 vCPU: Too weak. Spring Boot does a lot of complex work immediately when it turns on (scanning classes, building beans). If the CPU is this small, the startup might take so long that AWS thinks the app is "frozen" and kills it before it finishes loading.

  • 1 vCPU: The Sweet Spot. This provides enough power to start the application quickly (usually under 30 seconds) and handle normal web traffic smoothly.

  • 2 or 4 vCPU: Overkill. Unless you have hundreds of users hitting this specific demo app simultaneously, you are just paying for power you won't use.

Virtual CPU (vCPU)

  • Think of this as the "desk space" your app has to work on.

  • The Java Virtual Machine (JVM) heap requires a baseline amount of memory just to exist.

  • 2 GB: Recommended. This gives the Java Virtual Machine (JVM) plenty of room.

  • 3 GB / 4 GB: Unnecessary for this specific app.

  • You could try 1 GB if available, but Java apps in containers commonly have "Out of Memory" errors. If the app tries to grab 1.1 GB of RAM and the limit is 1 GB, the container vanishes instantly. 2 GB buys you safety.

Virtual Memory (GB)

  • AWS App Runner charges you based on these settings per second.

  • You pay for the memory (~$0.007/GB-hour) while the app is idle.

  • You pay for the vCPU only when the app is actively processing a request or starting up.

  • By choosing 1 vCPU / 2 GB, you are choosing a configuration that costs roughly $0.015 - $0.02 per hour (approx. $11-15/month) if left running 24/7.

Cost Implication

  • After deployment, the status changes to "Running":
  • Click the "Default domain" awsapprunner.com URL to test your app.

  • View the "Logs" tab in the App Runner dashboard.

    • Look for "Application logs" to see your Spring Boot startup output.

    • Unlike Azure's live stream command, AWS logs here might have a slight delay.

Live URL and Logs

  • Unlike Azure Container Apps or Google Cloud Run, AWS App Runner does not "scale to zero". It keeps at least one instance running to ensure instant responses.
  • The Good: No "cold starts" (no 20-second delay on the first request).
  • The Bad: It burns through your free tier hours faster if you leave it running 24/7.
  • You must remember to "Pause" or "Delete" the service when you are done testing.

  • To Stop Billing, go to the App Runner service list, select your service, and click Actions -> Pause. This keeps your configuration but stops the hourly charge.

  • To Destroy, click Actions -> Delete.

Cleanup (Money Saving Tip)

  • From the App Runner Service, click the "Custom domains" tab.
  • Click the "Link Domain" button.
  • You can register a domain through Amazon Route 53 or your own registrar.
  • Select "Non-Amazon" and enter the domain.
  • Click "Link Domain".

AWS Domain

  • I registered a domain using SiteGround.
  • Log in to SiteGround -> Websites -> Site Tools for your domain.

  • Go to Domain -> DNS Zone Editor. Add two records.

  • Delete any existing CNAME records.

  • Configure certificate validation. Create the two given CNAME records.

    • Name: Enter everything provided except .domain.com.

    • Value: Paste the values from AWS.

  • Configure DNS target. The the one given CNAME record.

    • Name: If using the root domain, leave it Empty (or type @).

      If using a subdomain (www), type www

    • Value: Paste the value from AWS.

SiteGround Registration

  • Go back to your AWS Management Console.
  • Wait for status to become 'Active'. It can take 24-48 hours after adding the records for the status to change.

  • AWSwill issue a free SSL certificate for your SiteGround domain.

  • A secure lock icon will appear when you visit the domain.

Finish and Secure in Azure

  • X

CRUD Functions

  • GitHub Actions works as your "robot butler." Instead of you manually running gradle build, docker build, and docker push on your laptop, GitHub does it automatically every time you push code.

    Here is the workflow:

  • You push code to your GitHub repository.

  • GitHub Actions wakes up, spins up a temporary server (runner).

  • It builds your jar using Gradle.

  • It logs in to Docker Hub (using secrets you provide).

  • It builds and pushes your Docker image.

GitHub Actions

  • You should never put your Docker Hub password directly in the file. You use GitHub Secrets.

  • Go to your GitHub repository.

  • Click Settings -> Secrets and variables -> Actions.

  • Click New repository secret.

  • Add these two:

    • Name: DOCKERHUB_USERNAME

      • Value: your_actual_username

    • Name: DOCKERHUB_TOKEN

      • Value: (Go to Docker Hub -> Account Settings -> Security -> New Access Token. Use this token instead of your real password.)

Set up Secrets

  • In your project, create this directory structure and file: .github/workflows/deploy.yml

  • Paste this content in. I have customized it for Gradle and Java 17.

Create the Workflow File

name: Build and Push Docker Image

on:
  push:
    branches: [ "main" ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
    # 1. Download your code
    - name: Checkout code
      uses: actions/checkout@v4

    # 2. Set up Java 17 (Same as your local environment)
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin' # or 'microsoft' if you prefer

    # 3. Build the JAR file with Gradle
    # We skip tests here to speed it up, but you can remove '-x test' to be safer
    - name: Build with Gradle
      run: ./gradlew clean bootJar -x test -x jar

    # 4. Set up Docker Buildx (required for modern Docker builds)
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    # 5. Log in to Docker Hub
    - name: Log in to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}

    # 6. Build and Push the Docker image
    - name: Build and push
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ secrets.DOCKERHUB_USERNAME }}/petclinic:latest
  • Commit this file and push it to GitHub.
    git add .
    git commit -m "Add GitHub Action workflow"
    git push

  • Go to the "Actions" tab in your GitHub repository. You will see the workflow running. When it turns green, check Docker Hub—your image will have been freshly updated!

Trigger it

  • Right now, GitHub pushes the image, but Azure doesn't know about it yet. You have two choices:

  • Continuous Deployment (CD) in Azure:

    • Go to your Azure Container App in the portal.

    • Under Application -> Revision management (or Continuous deployment), you can enable a setting that says "Create a new revision when a new image is pushed."

    • Note: This often requires a webhook setup.

  • Add an Azure Step to the YAML:

    • You can add a final step to the GitHub Action that runs az containerapp update to tell Azure to pull the new image immediately.

  • Would you like the code snippet to force Azure to update at the end of this workflow?

How does Azure know to update?

Java 3 - Week 2

By Marc Hauschildt

Java 3 - Week 2

  • 2