Week 02 - Architecture
Week 02 - Architecture
Readings
Read
DS4: 2.1 (Architectural styles), 2.5.2 (Cloud Computing), 3.2 (Virtualization)
CN1: Chapter 2: Fundamentals (Containers, Microservices)
Foundations of Scalable Systems: Chapter 2: Distributed Systems Architectures: An
Introduction
Optional extensive reading:
An Introduction to Containers has more in-depth coverage on containers
Installing Software
You should use the latest JDK (or at least 17). I recommend the latest version of Adoptium Eclipse
Temurin. To install the JDK, follows the instructions from https://adoptium.net/. You may choose
another JDK of your preference. https://whichjdk.com/
Once the JDK installation is complete, make two environment variable changes in your operating
system (applied to Windows):
Check that your operating system recognizes Java by entering java -version in a terminal (e.g.
PowerShell in Windows 10) and the Java compiler with javac -version .
For example:
$java -version
IDE
I recommend VS Code but you may choose other IDEs such as Eclipse, IntelliJ. If you use VS Code, you
should also install the Java extensions for Visual Studio Code.
Rancher Desktop
Instead of Docker, we will use Rancher Desktop which provides the same capabilities but also lets
you run Kubernetes locally. Rancher Desktop runs Kubernetes and container management on your
desktop. You can choose the version of Kubernetes you want to run. You can build, push, pull, and
run container images using either containerd or Moby (dockerd). The container images you build can
be run by Kubernetes immediately without the need for a registry.
Installing Rancher Desktop
Once installed, launch Rancher Desktop and wait until it finishes initialization. Then check that both
docker and kubectl are available in your PATH :
Server:
Engine:
Version: 26.1.5
API version: 1.45 (minimum version 1.24)
Go version: go1.22.5
Git commit: 411e817ddf710ff8e08fa193da80cb78af708191
Built: Fri Jul 26 17:51:06 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.7.17
GitCommit: 3a4de459a68952ffb703bbe7f2290861a75b6b67
runc:
Version: 1.1.14
GitCommit: 2c9f5602f0ba3d9da1c2596322dfc4e156844890
docker-init:
Version: 0.19.0
GitCommit:
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
Quarkus supports popular build automation tools such as Gradle and Maven. We will use Maven in
the labs and project. It is beneficial to learn the basics of Maven:
https://www.simplilearn.com/tutorials/maven-tutorial/introduction-to-maven
Optional
The following tools are not required but you may find them handy for developing your program.
Purpose
In this lab, you will learn:
This lab has two parts (slides). The first part is for you to learn, practice, and get prepared for the
tasks in the second part for credit.
Tasks
1. Create, compile and execute your first Quarkus project
The first step is to create a starter project. There are multiple ways to start a project with Quarkus
such as by using the Quarkus CLI. If you are not keen on using command line, an easier alternative is
creating your project at https://code.quarkus.io/.
Web UI
Open https://code.quarkus.io/ and click “Let's start coding!”. The default build tool is Maven. Let’s not
change it. You will use Maven to create a new project, add or remove extensions, launch development
mode, debug your application, and build your application into a jar, native executable, or container-
friendly executable in this course.
groupId – a unique base name of the company or group that created the project (e.g.,
edu.franklin)
artifactId – a unique name of the project (e.g., comp655-lab1-chunbo. You cannot have any
uppercase letter)
version – a version of the project (you may use the default value for now)
packaging – a packaging method (Quarkus allows you to download the starter as a zip)
The first three of these (groupId:artifactId:version) combine to form the unique identifier and are the
mechanism by which you specify which versions of external libraries (e.g. JARs) your project will use.
Choose your preferred groupId and artifactId for your project. They should be meaningful, simple,
and short. You may also include your name in either identifier. Avoid using underscores ("_").
Extensions
Quarkus supports a lot of extensions. The list is lengthy. Typing some keywords in the search box will
help you find the desired ones. For your first project, select the following:
Next, click the "Generate your application" button. By default, you will be prompted to download the
starter project as a zip.
If you need more extensions later, you may simply modify the pom.xml file in your project root
directory. For example, instead of selecting SmallRye OpenAPI at https://code.quarkus.io/, you can
add the following:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
between <dependencies> ... </dependencies> in pom.xml . Project Object Model or POM is the
fundamental unit of work in Maven. It contains information about the project and configuration
details used by Maven to build the project. You should learn the fundamentals of it at
https://maven.apache.org/guides/introduction/introduction-to-the-pom.html.
Unzip your project into a folder (e.g., C:\COMP655\Projects\Lab1) on your computer. Open your
favorite IDE and import the project. With VS Code, you can choose File->Open Folder... to open the
starter project.
It may take a few minutes for VS Code to load and process your project. You will see "Java Ready" on
the status bar when it's completed.
To launch your project in Quarkus development mode in VS Code, choose Terminal ->New Terminal,
and type:
./mvnw quarkus:dev
Your project will be compiled and executed. mvnw is an executable shell script used in place of a fully
installed Maven. It is provided by Maven Wrapper. You can also run your project without an IDE. Just
open a terminal window (e.g., Windows PowerShell), switch to the project root directory and type the
command above.
When you see the Quarkus banner is printed and "Listening on: http://localhost:8080", open
http://localhost:8080/ in your browser. You should see the default landing page.
quarkus:dev runs Quarkus in development mode. It enables hot deployment with background
compilation, which means that when you modify your Java files or your resource files and invoke a
REST endpoint (e.g., via a cURL command or refreshing your browser), these changes will
automatically take effect. It works too for resource files like the configuration property and HTML
files. Refreshing the browser triggers a scan of the workspace, and if any changes are detected, the
Java files are recompiled and the application is redeployed; your request is then serviced by the
redeployed application. If there are any issues with compilation or deployment an error page will let
you know.
Spend sometime exploring the structure of the project. The Java source code generated is in the
/src/main folder. You may also review this tutorial to get more information about getting started
with Quarkus: https://quarkus.io/guides/getting-started
Study the generated GreetingResource.java in the starter code to understand how to specify URIs,
annotate REST endpoints (i.e., Java methods with annotations such as @GET ) etc.
Focus on the following sections in the guide of "WRITING JSON REST SERVICES":
https://quarkus.io/guides/rest-json#creating-your-first-json-rest-service
https://quarkus.io/guides/rest-json#using-response
In this guide, the Fruit class is the domain class; the FruitResource class exposes a REST API
allowing CRUD (Create, Read, Update, Delete) operations on Fruit . Create the two classes in your
project.
In VS Code, choose Terminal ->New Terminal to open a terminal window and type: ./mvnw
quarkus:dev to run your project.
You can use any REST client (such as cURL or Postman ) to interact with your REST service. With the
SmallRye OpenAPI extension, Quarkus provides a user-friendly UI named Swagger UI.
Go to http://localhost:8080/. Click "VISIT THE DEV UI". The Dev Console integrates Swagger, a UI to
invoke your endpoints from the comfort of your browser. Click on the "Swagger UI" button located in
the "SmallRye OpenAPI" widget. You will see the list of all available resources. Thanks to Quarkus
development mode, when you modify your Java files or your resource files and invoke a REST
endpoint (i.e., cURL command or refresh your browser, or use the Swagger UI as mentioned below),
these changes will automatically take effect. You can learn more at
https://quarkus.io/guides/openapi-swaggerui#dev-mode
Interact with every endpoint to make sure you understand its intended effect and result. When you
execute an operation, pay attention to the idempotency of the method, and the Code and
Description under Responses. For PUT and POST operations, you can add a JSON document with
the data in the Request body. For example, you may have the following request body for a PUT
operation:
{
"name": "Apple",
"description": "Winter fruit"
}
You can explore other parts of the guide of "WRITING JSON REST SERVICES" if you are interested, but
are not required to do so for this lab.
When you are ready, proceed to Lab 1-2 in the next slide.
Lab 1-2: Implement a simple REST application with Quarkus
Due Date: check Canvas
You must complete Lab 1-1: A self-paced study of REST service with Quarkus first.
You should have the basic knowledge and skills to create a simple REST application with Quarkus
after completing Lab 1-1.
Requirements
This is an individual lab.
Create a new starter project with Quarkus REST Jackson and SmallRye OpenAPI extensions.
REST service
1. Implement a domain class Student defined as follows: id is an unique integer. name and
phone are String. A student may have taken multiple courses. Each course is a Course class
with a course prefix (e.g., 'COMP'), course number (e.g., 655), semester (e.g., 'SP25'), letter grade
(e.g., 'A').
{
"name": "John Doe",
"phone": "555-1234",
"courses": [
{
"prefix": "COMP",
"number": 655,
"semester": "SP25",
"grade": "A"
},
{
"prefix": "MATH",
"number": 101,
"semester": "FA24",
"grade": "B+"
}
]
}
2. Read an existing student: HTTP Method: GET URI: /api/students/{id} or all existing
students: /api/students
3. Update an exist student: HTTP Method: PUT URI: /api/students/{id} Request Body:
JSON data. id cannot be changed.
4. Delete an existing student: HTTP Method: DELETE URI: /api/students/{id} or all
existing students: /api/students
To read URI path parameters, such as id , you can use the @RestPath annotation. The @RestPath
annotation is optional: any parameter whose name matches an existing URI template variable will be
automatically assumed to have @RestPath . In the following example, @RestPath is not necessary
because the matching Java method parameter has the same name as the URI path parameter ( id ):
import org.jboss.resteasy.reactive.RestPath;
//.... ....
@Path("/{id}")
public Response getStudent(@RestPath int id) {
//ToDO
}
You can refer this document for more details and examples:
https://quarkus.io/guides/rest#accessing-request-parameters
Response
Your endpoints must return a proper Response indicating the status of the operation. For example:
Response.ok for a successful operation (For Read operation, your endpoint will return the
representation of the resource in addition to the status. See the example in
https://quarkus.io/guides/rest-json#using-response ).
Use the following guide for this lab:
1. Create: 201 Created - The most fitting for Create operations. This code should signal backend-
side resource creation and come along with a location header that defines the most specific URI
for that newly created resource. It’s also a good idea to include appropriate representation of
the resource or at least one or more URIs to that resource in the response body. For example,
your "create a new student" endpoint will return a Response.created() with the URI for the
newly created Student , (e.g. /api/students/1 ) and the resource representation in the
message body.
2. Read: 200 OK - Most of the read actions will be answered with a 200 OK status.
3. Update: 200 OK - This is the most appropriate code for most use-cases.
4. Delete: 204 No Content - The most fitting status code for this case. HTTP 204 means the server
has fulfilled the request but does not need to return an entity-body.)
You may use 202 Accepted code for "delete a Student" or "update a Student", and the URI of the
resource being deleted or updated. Reference: https://www.moesif.com/blog/technical/api-
design/Which-HTTP-Status-Code-To-Use-For-Every-CRUD-App/
If a resource (a student with a specified id in this case) does not exist, use Response.status(...) to
build a new Response with the Response.Status.NOT_FOUND status code which generates HTTP 404.
You may want to review:
https://jakarta.ee/specifications/restful-ws/4.0/apidocs/jakarta.ws.rs/jakarta/ws/rs/core/response
https://jakarta.ee/specifications/restful-
ws/4.0/apidocs/jakarta.ws.rs/jakarta/ws/rs/core/response.status
OpenAPI
Your StudentResource class and each endpoint should be furtherly described with the @Tag
annotations: (https://quarkus.io/blog/openapi-for-everyone/#adding-some-openapi-annotations-to-
your-operations
https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#tag).
Once your application is started, you can issue a request to the default /q/openapi endpoint to see a
list of your API.
Comments
You must properly comment your code to help the instructor understand how you implement the
application. Add a comment block at the beginning of every Java source file to briefly describe the
purpose of the class and your full name.
JUnit Testing (optional)
Writing JUnit testing is optional for this lab, but may be required for future labs. You are encouraged
to take this opportunity to get started. The tests should verify that the endpoints return required
status code and, if applicable, that the response body contains expected data. Refer to the following :
https://quarkus.io/guides/getting-started#testing
https://quarkus.io/guides/getting-started-testing
README.md (optional)
This task is optional for this lab, but will be required for future labs. You are encouraged to take this
opportunity to get started.
Replace the content in the default README.md file in the root directory of your project. This file will
serve as the primary documentation for your code, explaining what it does and how to run it.
Use Markdown formatting to make your README easy to read. Use headings, lists, and code blocks
to structure your document effectively.
Submission
Compress your entire project in a zip file, include your full name in the zip file name, and upload it to
the Canvas assignment Lab 1 by the due date.