├── .gitignore ├── README.md ├── images ├── .DS_Store ├── astra-create-db.png ├── astra-login.png └── tutorials │ ├── AstraTodos.png │ ├── Filexplorer0.png │ ├── HW1.png │ ├── Lens01.png │ ├── Lens02.png │ ├── LensDownload1.png │ ├── LensLDK1.png │ ├── LensLaunchManual1.png │ ├── LensPortForward1.png │ ├── LensPortForward2.png │ ├── LensRunning1.png │ ├── LensRunning2.png │ ├── LensStop1.png │ ├── LensStopped1.png │ ├── Lensresource01.png │ ├── Lensresource02.png │ ├── Lensresource03.png │ ├── Lenssecret01.png │ ├── Lenssecret02.png │ ├── Lenssecret03.png │ ├── Lensvalues1.png │ ├── NewSplash.png │ ├── OpenPorts.png │ ├── allow.png │ ├── astra-create-db.gif │ ├── astra-create-token.gif │ ├── astra-token.png │ ├── astra_signup.gif │ ├── badge.png │ ├── db-pending.png │ ├── debug1.png │ ├── debug2.png │ ├── debug3.png │ ├── debug4.png │ ├── debug5.png │ ├── debug6.png │ ├── editapplicationproperties1.png │ ├── editapplicationproperties2.png │ ├── gitpod-01-home-annotated.png │ ├── gitpod-01-home-plain.png │ ├── gitpod-02-url.png │ ├── gitpod-quarkus-1.jpg │ ├── newbrowser1.png │ ├── oktetoconfig1.png │ ├── oktetoconfig2.png │ ├── oktetorunning1.png │ ├── quarkus-dev-0.png │ ├── quarkus-dev-1.png │ ├── quarkus-dev-2.png │ ├── quarkus-dev-3.png │ ├── quarkus-dev-4.png │ ├── quarkus-dev-5.png │ ├── rags.png │ ├── secureconnectbundle1.png │ ├── secureconnectbundle2.png │ ├── secureconnectbundle3.png │ ├── splash-quarkus-cassandra.png │ ├── splash.png │ ├── stefano.png │ └── thankyou.gif └── slides.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse conf file 2 | .settings 3 | .classpath 4 | .project 5 | .cache 6 | 7 | # idea conf files 8 | .idea 9 | *.ipr 10 | *.iws 11 | *.iml 12 | 13 | # building 14 | target 15 | build 16 | tmp 17 | dist 18 | 19 | # misc 20 | .DS_Store 21 | 22 | .factorypath 23 | .sts4-cache 24 | *.log 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Intro to Quarkus and Cassandra with Kubernetes 2 | 3 | [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/datastaxdevs/quarkus-astra-intro-demo) 4 | [![License Apache2](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0) 5 | [![Discord](https://img.shields.io/discord/685554030159593522)](https://discord.com/widget?id=685554030159593522&theme=dark) 6 | 7 | Today we showcase an application using **Apache Cassandra™** as a backend implemented with **Quarkus**, and experience some developer joy with features that often have been an envy for Java programmers - hot reloading, debugging, containerizing and finally generating native code. 8 | 9 | There are many other features of the Quarkus platform that we will not be looking into that are widely considered as unique strengths of the platform including testing. 10 | 11 | We will deploy the app on containers in Kubernetes using Lens. 12 | 13 | The application we will be using is based on [Jake's port](https://github.com/tjake/todo-astra-react-serverless/) of the [TodoMVC code](https://github.com/tastejs/todomvc/tree/master/examples/react) originally written by [Pete Hunt](https://github.com/petehunt). The example is modified from [https://github.com/huksley/todo-react-ssr-serverless](https://github.com/huksley/todo-react-ssr-serverless). 14 | 15 | A screenshot of this simple app is below. 16 | 17 | ![AstraTodo](images/tutorials/AstraTodos.png?raw=true) 18 | 19 | ℹ️ **Objective(s) of workshop** 20 | 21 | Whether you're a seasoned developer or relatively new to programming, you will be spending a lot of time in an Integrated Development Environment and the "inner loop" of development with a lightweight CI/CD cycle. 22 | 23 | Once you have a stable environment after repeated iterations in the editor, testing environments, profiler, debugger, etc. you push it to the outer loop which has a more robust CI/CD cycle usually backed by gitops, Jenkins and other CI/CD tools. 24 | 25 | The objective of today's workshop is to understand how the Quarkus platform simplifies the "inner loop" of development which results in huge developer productivity gains. You will see in today's workshop you can go from plain old Java to containers with relative ease and yet not make a significant change in devlopment. 26 | 27 | Although, the Quarkus platform leverages a reactive architecture, the developer tools are drawn from a list that they are familar with and complements them while making those same tools leaner and more performant. This means that Quarkus does not force developers to use reactive programming styles. Additionally, it helps to build better and more performant applications (which is always necessary) and also enhances the day-to-day life of a developer having to bridge the gap between their existing platforms and taking a plunge into microservices, service mesh and so on. Developers can use their current tools and methodologies and let Quarkus take care of being "reactive", or build new fully-reactive applications that take advantage of Quarkus' reactive core. 28 | 29 | ℹ️ **Frequently asked questions** 30 | 31 | - _Can I run the workshop on my computer?_ 32 | > There is nothing preventing you from running the workshop on your own machine. If you do so, you will need _java jdk11+_, _Graal VM_, _Maven_, an IDE like _VSCode, IntelliJ, Eclipse, Spring STS_. You will have to adapt commands and paths based on your environment and install the dependencies by yourself. **We won't provide support** to keep on track with schedule. 33 | 34 | ## Prerequisites 35 | 36 | We strive to make our hands-on workshops prerequisites free -- who has the time to install prerequistes? :-) 37 | 38 | However, docker login credentials, some familiarity with an IDE like [Visual Studio Code](https://code.visualstudio.com) or [Gitpod](https://gitpod.io) (although not strictly necessary) might help. 39 | 40 | ## Materials for the Session 41 | 42 | It doesn't matter if you join our workshop live or you prefer to do at your own pace, we have you covered. In this repository, you'll find everything you need for this workshop: 43 | 44 | - [Slide deck](./slides.pdf) 45 | - [Discord chat](https://bit.ly/cassandra-workshop) 46 | - [Questions and Answers](https://community.datastax.com/) 47 | - [Workshop code](https://github.com/datastaxdevs/quarkus-astra-intro-demo) 48 | 49 | ## Alternate Learning Path(s) in this workshop 50 | 51 | If you're primarily interested in containerization (as in **Slay the complexity of Kubernetes Inner Loop Development**), you can skip most of the early steps and jump straight to [Containerizing](#10-containerizing). Summarizing 52 | 53 | |Focus| Step(s) | Verify connection | Step(s) skipped | 54 | | ----------- | --- | ---|----------- | 55 | |**Containers/Inner loop**| Do steps 1-6 and 10 onwards | [After steps 1-6, verify connection](#6-run-some-unit-tests) | Skip steps 7,8,9| 56 | 57 | ## 0. Table of contents 58 | 59 | 1. [Database Initialization](#1-create-astra-db-instance) 60 | 3. [Launch Gitpod](#3-launch-gitpod) 61 | 4. [Know your Gitpod](#4-know-your-gitpod) 62 | 5. [Setup your Application](#5-setup-your-application) 63 | 6. [Run Unit test(s)](#6-run-some-unit-tests) 64 | 7. [Quarkus Dev Mode](#7-quarkus-dev-mode) 65 | 8. [Debugging](#8-debugging) 66 | 9. [Packaging](#9-packaging) 67 | 10. [Containerizing](#10-containerizing) 68 | 11. [Native Image](#11-native-image) 69 | 12. [Homework](#12-homework) 70 | 71 | 72 | ## 1. Database Initialization 73 | 74 | ### 1.1 - Create an Astra Account 75 | 76 | > **Note**: **Datastax Astra** is a cloud-native, fully managed database-as-a-service (DBaaS) based on Apache Cassandra. It provides a scalable, performant and highly available database solution without the operational overhead of managing Cassandra clusters. Astra supports both SQL and NoSQL APIs, and includes features like backup and restore, monitoring and alerting, and access control. It enables developers to focus on application development while the database infrastructure is managed by Datastax. 77 | 78 | - `✅ 1.1.a` - Access [https://astra.datastax.com](https://astra.datastax.com) and register with `Google` or `Github` account 79 | 80 | ![](images/astra-login.png?raw=true") 81 | 82 | 83 | ### 1.2 - Create an Astra DB 84 | 85 | > **Info** [Reference Documentation](https://awesome-astra.github.io/docs/pages/astra/create-instance/) 86 | 87 | | Parameter | Value | 88 | |---------------|-----------| 89 | | Database name | `workshops` | 90 | | Keyspace name | `todolist` | 91 | | Cloud | `GCP` | 92 | | Region | `us-east1` | 93 | 94 | ![](images/astra-create-db.png?raw=true") 95 | 96 | 97 | [🏠 Back to Table of Contents](#0-table-of-contents) 98 | 99 | ### 1.3 - Create an Astra Token 100 | 101 | - `✅ 1.2.a` Locate `Settings` (#1) in the menu on the left, then `Token Management` (#2) 102 | 103 | - `✅ 1.2.b`Select the role `Organization Administrator` before clicking `[Generate Token]` 104 | 105 | ![](https://github.com/DataStax-Academy/cassandra-for-data-engineers/blob/main/images/setup-astra-2.png?raw=true) 106 | 107 | - `✅ 1.2.c` - Copy your token in the clipboard. With this token we will now create what is needed for the training. 108 | 109 | ![](https://github.com/DataStax-Academy/cassandra-for-data-engineers/blob/main/images/setup-astra-3.png?raw=true) 110 | 111 | 112 | [🏠 Back to Table of Contents](#0-table-of-contents) 113 | 114 | ## 2. Gitpod 115 | 116 | [Gitpod](https://www.gitpod.io/) is an IDE 100% online based on [VS Code](https://github.com/gitpod-io/vscode/blob/gp-code/LICENSE.txt?lang=en-US). To initialize your environment simply click on the button below 117 | _(CTRL + Click to open in new tab)_ You will be asked for you github account, as needed. 118 | 119 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/datastaxdevs/quarkus-astra-intro-demo) 120 | 121 | **👁️ Expected output** 122 | 123 | _The screenshot may be slightly different based on your default skin and a few edits in the read me._ 124 | 125 | ![gitpod](images/tutorials/gitpod-01-home-plain.png?raw=true) 126 | 127 | **That's it.** Gitpod provides all tools we will need today including `maven` and exposing port `8080`, ports `5005` which is used for debugging, etc. 128 | 129 | **You may safely ignore the error output at the end of the terminal window.** 130 | 131 | **👁️ Expected output** 132 | 133 | ![image](images/tutorials/gitpod-quarkus-1.jpg?raw=true) 134 | 135 | Although GitPod terminal might seem to be available, the setup might still be ongoing. Wait for a few minutes before entering commands in the GitPod terminal window. 136 | 137 | [🏠 Back to Table of Contents](#table-of-contents) 138 | 139 | ## 4. Know your gitpod 140 | 141 | Take a moment to read this entire section since it'll help you with the rest of the workshop as you'll be spending most of your time in Gitpod. If you're familiar with Gitpod, you can easily skip this entire section. 142 | 143 | The extreme left side has the explorer view(1). The top left, middle to right is where you'll be editing files(2), etc. and the bottom left, middle to right is what we will refer to as the Gitpod terminal window(3) as shown below. 144 | 145 | **👁️ Expected output** 146 | 147 | ![gitpod](images/tutorials/gitpod-01-home-annotated.png?raw=true) 148 | 149 | 150 | You can always get back to the file explorer view whenever by clicking on the hamburger menu on the top left followed by `View` and `Explorer` as shown below. 151 | 152 | ![gitpod](images/tutorials/Filexplorer0.png?raw=true) 153 | 154 | ✅ **Step 4a: Know your public URL** 155 | 156 | The workshop application has opened with an ephemeral URL. To know the URL where your application endpoint will be exposed you can run the following command in the terminal after the build has completed. **Please note this URL and open this up in a new browser window as shown below**. 157 | 158 | ```bash 159 | gp url 8080 160 | ``` 161 | 162 | **👁️ Expected output** 163 | 164 | ![gitpod](images/tutorials/gitpod-02-url.png?raw=true) 165 | 166 | 167 | Although the application is not running yet, 168 | launch a new browser window (**don't close it for the rest of the workshop since you'll continually keep using this**. If you accidentally close it, just come back to this step. The browser will generate an error (due to application not running yet) which is fine for now as shown below. 169 | 170 | **👁️ Expected output** 171 | 172 | ![gitpod](images/tutorials/newbrowser1.png?raw=true) 173 | 174 | You may encounter the following at different steps and although this may not be applicable right away, the steps are included **in advance** and summarized here so that you can keep an eye out for it. Different paths and different environments might be slightly different although Gipod levels the playing field a bit. 175 | 176 | You can allow cutting and pasting into the window by clicking on `Allow` as shown below. 177 | 178 | ![gitpod](images/tutorials/allow.png?raw=true) 179 | 180 | Or allow ports to be opened by just exiting windows that are informational messages about ports like below. 181 | 182 | ![gitpod](images/tutorials/OpenPorts.png?raw=true) 183 | 184 | 185 | [🏠 Back to Table of Contents](#0-table-of-contents) 186 | 187 | ## 5. Setup your application 188 | 189 | To run the application you need to provide the credentials and identifier to the application. 190 | 191 | Issue the following command from the Gitpod terminal window. 192 | 193 | ``` 194 | gp open src/main/resources/application.properties 195 | ``` 196 | 197 | ![gitpod](images/tutorials/editapplicationproperties1.png?raw=true) 198 | 199 | 200 | ✅ **Step 5a: Enter 2 values from the token** 201 | 202 | Enter the values of `Client Id` and `Client Secret` from values noted earlier for `astra-username` and `astra-password` respectively. The two lines with a TBD in comments is shown below. 203 | 204 | ![gitpod](images/tutorials/editapplicationproperties2.png?raw=true) 205 | 206 | 207 | ✅ **Step 5b: Download the secure connect bundle** 208 | 209 | ``` 210 | curl -Ls "https://dtsx.io/get-astra-cli" | bash 211 | source /home/gitpod/.astra/cli/astra-init.sh 212 | astra 213 | astra setup --token <> 214 | astra db download-scb workshops -f /workspace/quarkus-astra-intro-demo/secure-connect-workshops.zip 215 | ls -l secure-connect-workshops.zip 216 | ``` 217 | 218 | The file size should be roughly 12K otherwise something may have gone wrong in the process. 219 | 220 | **👁️ Expected output** 221 | 222 | ``` 223 | -rw-r--r-- 1 gitpod gitpod 12231 Oct 26 00:15 secure-connect-workshops.zip 224 | ``` 225 | 226 | TADA your application is now configured we can finally play with some code. 227 | 228 | [🏠 Back to Table of Contents](#0-table-of-contents) 229 | 230 | ## 6. Run some unit test(s) 231 | 232 | The application is now set and you should be able to interact with your DB, although connecting to a "real" DB is not necessary in order to execute tests. The application's tests use the [Quarkus Cassandra Test Framework](https://github.com/datastax/cassandra-quarkus/tree/main/test-framework). Quarkus will automatically bootstrap a Cassandra Docker container and connect it to the application when the tests execute. 233 | 234 | Under the covers, all interaction with Cassandra is implemented in Java through the `com.datastax.oss.driver.api.core.CqlSession`, part of the [DataStax Java Driver](https://docs.datastax.com/en/developer/java-driver/latest). Higher level frameworks like Quarkus, Spring, Spring Data, rely on this object. The [Quarkus Cassandra Test Framework](https://github.com/datastax/cassandra-quarkus/tree/main/test-framework) makes sure its available to the tests. 235 | 236 | Let's run this unit test in the Gitpod terminal window. 237 | 238 | ```bash 239 | ./mvnw test -Dtest=com.datastaxdev.todo.rest.TodoResourceTests 240 | ``` 241 | 242 | **👁️ Expected output** 243 | 244 | ``` 245 | Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 246 | [INFO] Scanning for projects... 247 | [INFO] 248 | [INFO] ---------< quarkus-astra-intro-demo:quarkus-astra-intro-demo >---------- 249 | [INFO] Building quarkus-astra-intro-demo 0.01 250 | [INFO] --------------------------------[ jar ]--------------------------------- 251 | [INFO] 252 | [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ quarkus-astra-intro-demo --- 253 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 254 | [INFO] Copying 24 resources 255 | [INFO] 256 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code (default) @ quarkus-astra-intro-demo --- 257 | [INFO] 258 | [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ quarkus-astra-intro-demo --- 259 | [INFO] Nothing to compile - all classes are up to date 260 | [INFO] 261 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code-tests (default) @ quarkus-astra-intro-demo --- 262 | [INFO] 263 | [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ quarkus-astra-intro-demo --- 264 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 265 | [INFO] Copying 1 resource 266 | [INFO] 267 | [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ quarkus-astra-intro-demo --- 268 | [INFO] Nothing to compile - all classes are up to date 269 | [INFO] 270 | [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ quarkus-astra-intro-demo --- 271 | [INFO] 272 | [INFO] ------------------------------------------------------- 273 | [INFO] T E S T S 274 | [INFO] ------------------------------------------------------- 275 | [ERROR] Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 276 | [INFO] Running com.datastaxdev.todo.rest.TodoResourceTests 277 | INFO [org.jbo.threads] (main) JBoss Threads version 3.4.2.Final 278 | INFO [org.tes.uti.ImageNameSubstitutor] (main) Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor') 279 | INFO [org.tes.doc.DockerClientProviderStrategy] (pool-4-thread-1) Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first 280 | INFO [org.tes.doc.DockerClientProviderStrategy] (pool-4-thread-1) Found Docker environment with local Unix socket (unix:///var/run/docker.sock) 281 | INFO [org.tes.DockerClientFactory] (pool-4-thread-1) Docker host IP address is localhost 282 | INFO [org.tes.DockerClientFactory] (pool-4-thread-1) Connected to docker: 283 | Server Version: 20.10.14 284 | API Version: 1.41 285 | Operating System: Ubuntu 20.04.4 LTS 286 | Total Memory: 64312 MB 287 | INFO [org.tes.uti.RegistryAuthLocator] (pool-4-thread-1) Failure when attempting to lookup auth config. Please ignore if you don't have images in an authenticated registry. Details: (dockerImageName: testcontainers/ryuk:0.3.3, configFile: /home/gitpod/.docker/config.json. Falling back to docker-java default behaviour. Exception message: /home/gitpod/.docker/config.json (No such file or directory) 288 | INFO [org.tes.uti.RyukResourceReaper] (pool-4-thread-1) Ryuk started - will monitor and terminate Testcontainers containers on JVM exit 289 | INFO [org.tes.DockerClientFactory] (pool-4-thread-1) Checking the system... 290 | INFO [org.tes.DockerClientFactory] (pool-4-thread-1) ✔︎ Docker server version should be at least 1.6.0 291 | INFO [org.tes.DockerClientFactory] (pool-4-thread-1) ✔︎ Docker environment should have more than 2GB free disk space 292 | INFO [com.dat.oss.qua.tes.CassandraTestResource] (pool-4-thread-1) Container cassandra:latest starting... 293 | INFO [🐳 [cassandra:latest]] (pool-4-thread-1) Creating container for image: cassandra:latest 294 | INFO [🐳 [cassandra:latest]] (pool-4-thread-1) Container cassandra:latest is starting: 001d53b387a0a5861466621f6828e753036bec4d9958562ba24a934442c430e5 295 | INFO [com.dat.dri.core] (ducttape-0) DataStax Java driver 3.7.1 for Apache Cassandra 296 | INFO [com.dat.dri.cor.GuavaCompatibility] (ducttape-0) Detected Guava >= 19 in the classpath, using modern compatibility layer 297 | INFO [com.dat.dri.cor.ClockFactory] (ducttape-0) Using native clock to generate timestamps. 298 | INFO [com.dat.dri.cor.NettyUtil] (ducttape-0) Did not find Netty's native epoll transport in the classpath, defaulting to NIO. 299 | INFO [com.dat.dri.cor.ClockFactory] (ducttape-0) Using native clock to generate timestamps. 300 | INFO [com.dat.dri.cor.ClockFactory] (ducttape-0) Using native clock to generate timestamps. 301 | WARN [com.dat.dri.cor.Cluster] (ducttape-0) You listed localhost/127.0.0.1:49156 in your contact points, but it wasn't found in the control host's system.peers at startup 302 | INFO [com.dat.dri.cor.pol.DCAwareRoundRobinPolicy] (ducttape-0) Using data-center name 'datacenter1' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) 303 | INFO [com.dat.dri.cor.Cluster] (ducttape-0) New Cassandra host localhost/0:0:0:0:0:0:0:1:49156 added 304 | INFO [🐳 [cassandra:latest]] (pool-4-thread-1) Container cassandra:latest started in PT9.049449S 305 | INFO [org.tes.ext.ScriptUtils] (pool-4-thread-1) Executing database script from init_script.cql 306 | INFO [com.dat.dri.cor.ClockFactory] (pool-4-thread-1) Using native clock to generate timestamps. 307 | WARN [com.dat.dri.cor.Cluster] (pool-4-thread-1) You listed localhost/127.0.0.1:49156 in your contact points, but it wasn't found in the control host's system.peers at startup 308 | INFO [com.dat.dri.cor.pol.DCAwareRoundRobinPolicy] (pool-4-thread-1) Using data-center name 'datacenter1' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) 309 | INFO [com.dat.dri.cor.Cluster] (pool-4-thread-1) New Cassandra host localhost/0:0:0:0:0:0:0:1:49156 added 310 | INFO [org.tes.ext.ScriptUtils] (pool-4-thread-1) Executed database script from init_script.cql in 2132 ms. 311 | INFO [com.dat.dri.cor.ClockFactory] (pool-4-thread-1) Using native clock to generate timestamps. 312 | WARN [com.dat.dri.cor.Cluster] (pool-4-thread-1) You listed localhost/0:0:0:0:0:0:0:1:49156 in your contact points, but it wasn't found in the control host's system.peers at startup 313 | INFO [com.dat.dri.cor.pol.DCAwareRoundRobinPolicy] (pool-4-thread-1) Using data-center name 'datacenter1' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) 314 | INFO [com.dat.dri.cor.Cluster] (pool-4-thread-1) New Cassandra host localhost/127.0.0.1:49156 added 315 | INFO [com.dat.oss.qua.tes.CassandraTestResource] (pool-4-thread-1) Container cassandra:latest listening on 127.0.0.1:49156 (inferred local DC: datacenter1) 316 | WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.service-type" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 317 | WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.env.secrets" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 318 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientRecorder] (main) Enabling Cassandra metrics using Micrometer. 319 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientStarter] (main) Eagerly initializing Quarkus Cassandra client. 320 | INFO [com.dat.oss.dri.int.cor.DefaultMavenCoordinates] (main) DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.14.0 321 | INFO [com.dat.oss.dri.int.cor.tim.Clock] (vert.x-eventloop-thread-0) Using native clock for microsecond precision 322 | INFO [com.dat.tod.res.TodoResource] (main) **** Table created true**** 323 | INFO [io.quarkus] (main) quarkus-astra-intro-demo 0.01 on JVM (powered by Quarkus 2.9.1.Final) started in 16.146s. Listening on: http://localhost:41159 324 | INFO [io.quarkus] (main) Profile test activated. 325 | INFO [io.quarkus] (main) Installed features: [cassandra-client, cdi, micrometer, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-health, smallrye-openapi, swagger-ui, vertx] 326 | [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 19.304 s - in com.datastaxdev.todo.rest.TodoResourceTests 327 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientRecorder] (main) Closing Quarkus Cassandra session. 328 | INFO [io.quarkus] (main) quarkus-astra-intro-demo stopped in 0.039s 329 | [INFO] 330 | [INFO] Results: 331 | [INFO] 332 | [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 333 | [INFO] 334 | [INFO] ------------------------------------------------------------------------ 335 | [INFO] BUILD SUCCESS 336 | [INFO] ------------------------------------------------------------------------ 337 | [INFO] Total time: 25.096 s 338 | [INFO] Finished at: 2022-05-16T18:22:07Z 339 | [INFO] ------------------------------------------------------------------------ 340 | ``` 341 | 342 | You can see from the output that the `cassandra:latest` Docker container was started before the tests were executed. 343 | 344 | Verfiy that the table got created with the following command 345 | 346 | ```bash 347 | ./mvnw test -Dcom.datastaxdev.todo.rest.TodoResourceTests | grep -i table 348 | ``` 349 | 350 | **👁️ Expected output** 351 | 352 | ``` 353 | INFO [com.dat.tod.res.TodoResource] (main) **** Table created true**** 354 | ``` 355 | 356 | > You will likely see that output repeated more than once. 357 | 358 | Although a significant strength of the Quarkus platform is it's [continuous testing](https://quarkus.io/guides/continuous-testing) capabilities, we will skip tests going foraward and focus on the other capabilities of the platform (perhaps, another workshop sometime focussed mainly on testing capabilities, assuming there is enough demand). 359 | 360 | [🏠 Back to Table of Contents](#0-table-of-contents) 361 | 362 | ## 7. Quarkus Dev Mode 363 | 364 | Before we get started let's check that the Graal VM is available. 365 | 366 | ``` 367 | echo $GRAALVM_HOME 368 | ``` 369 | 370 | **👁️ Expected output** 371 | 372 | ``` 373 | /home/gitpod/.sdkman/candidates/java/current 374 | ``` 375 | 376 | ✅ **Step 7a: Begin dev** 377 | 378 | In the Gitpod terminal window, We will begin the inner loop journey in dev mode using the following command. 379 | 380 | 381 | ```bash 382 | ./mvnw quarkus:dev -DskipTests 383 | ``` 384 | **👁️ Expected output** 385 | 386 | ``` 387 | __ ____ __ _____ ___ __ ____ ______ 388 | --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 389 | -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ 390 | --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 391 | WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.kubernetes.service-type" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 392 | 393 | WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.kubernetes.env.secrets" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 394 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientRecorder] (Quarkus Main Thread) Enabling Cassandra metrics using Micrometer. 395 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientStarter] (Quarkus Main Thread) Eagerly initializing Quarkus Cassandra client. 396 | INFO [com.dat.oss.dri.int.cor.DefaultMavenCoordinates] (Quarkus Main Thread) DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.14.0 397 | INFO [com.dat.oss.dri.int.cor.tim.Clock] (vert.x-eventloop-thread-0) Using native clock for microsecond precision 398 | INFO [com.dat.oss.dri.int.cor.ses.DefaultSession] (vert.x-eventloop-thread-9) [s0] Negotiated protocol version V4 for the initial contact point, but cluster seems to support V5, keeping the negotiated version 399 | INFO [com.dat.tod.res.TodoResource] (Quarkus Main Thread) **** Table created true**** 400 | INFO [io.quarkus] (Quarkus Main Thread) quarkus-astra-intro-demo 0.01 on JVM (powered by Quarkus 2.9.1.Final) started in 7.383s. Listening on: http://localhost:8080 401 | INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. 402 | INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cassandra-client, cdi, micrometer, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-health, smallrye-openapi, swagger-ui, vertx] 403 | 404 | -- 405 | Tests paused 406 | Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options> 407 | ``` 408 | ✅ **Step 7b: Explore Quarkus dev mode** 409 | 410 | Typing `h` in the terminal window should bring up the following 411 | 412 | **👁️ Expected output** 413 | 414 | ``` 415 | The following commands are currently available: 416 | 417 | == Continuous Testing 418 | 419 | [r] - Resume testing 420 | [o] - Toggle test output (disabled) 421 | 422 | == Exceptions 423 | 424 | [x] - Opens last exception in IDE (None) 425 | 426 | == HTTP 427 | 428 | [w] - Open the application in a browser 429 | [d] - Open the Dev UI in a browser 430 | 431 | == System 432 | 433 | [s] - Force restart 434 | [i] - Toggle instrumentation based reload (disabled) 435 | [l] - Toggle live reload (enabled) 436 | [j] - Toggle log levels (INFO) 437 | [h] - Shows this help 438 | [:] - Enters terminal mode 439 | [q] - Quits the application 440 | 441 | -- 442 | Tests paused 443 | Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options> 444 | ``` 445 | 446 | You can try the different options available. 447 | 448 | Note that you may have to allow popups from `gitpod.io` as shown below. 449 | 450 | ![gitpod](images/tutorials/quarkus-dev-0.png?raw=true) 451 | 452 | Try connecting to the application in a browser by pressing the `w` key as indicated above. This should bring up the application as below. 453 | 454 | > **NOTE:** This may not actually work in Gitpod because of the way Gitpod handles links. If the page doesn't open for you simply go to the browser tab you opened back in step 4a. 455 | 456 | **👁️ Expected output** 457 | 458 | ![gitpod](images/tutorials/quarkus-dev-1.png?raw=true) 459 | 460 | ✅ **Step 7c: Hot reload** 461 | Now, let's go ahead and make an illustrative change. 462 | 463 | Navigate to the file `src/main/java/resources/META-INF/resources/index.html` and change the `data-ribbon` entry from "Fork me on Github" to "Fork me today on Github." 464 | 465 | Next, refresh the browser page. You should immediately see the update. This hot reloading feature of Quarkus works for more than just static content too! 466 | 467 | **👁️ Expected output** 468 | 469 | ![gitpod](images/tutorials/quarkus-dev-2.png?raw=true) 470 | 471 | You could add a few entries to the "todo list" as shown below. 472 | 473 | **👁️ Expected output** 474 | 475 | ![gitpod](images/tutorials/quarkus-dev-3.png?raw=true) 476 | 477 | ✅ **Step 7d: Quarkus dev metrics** 478 | 479 | You can get Quarkus development metrics and so on hitting the `d` key as indicated in the help and this should bring up a window that looks like below. 480 | 481 | > **NOTE:** Again, because of the way Gitpod works, this may not bring up the window. If it doesn't, go back to the browser window containing the running application and append `/q/dev` to the URL. 482 | 483 | **👁️ Expected output** 484 | 485 | ![gitpod](images/tutorials/quarkus-dev-4.png?raw=true) 486 | 487 | > The `/q/dev` end point can be accessed using the URL below when the application is running in `dev` mode. You can use another `bash` tab in the gitpod terminal window to enter the commands while the application is running and switch between tabs as required. 488 | 489 | ``` 490 | echo $(gp url 8080)/q/dev 491 | ``` 492 | 493 | and the `openapi` spec is at 494 | 495 | ``` 496 | echo $(gp url 8080)/q/openapi 497 | ``` 498 | 499 | as shown below. 500 | 501 | ![gitpod](images/tutorials/quarkus-dev-5.png?raw=true) 502 | 503 | You could continue developing your entire application without ever leaving dev mode! It will even handle refactorings and project dependency changes! 504 | 505 | Let's out of development mode by hitting `q` or hitting `+C`. 506 | 507 | ✅ **Step 7e: Quarkus smart dispatch** 508 | 509 | Let's quickly examine the [Quarkus smart dispatching mechanism](https://quarkus.io/blog/resteasy-reactive-smart-dispatch). Let's open the `com.datastaxdev.todo.rest.TodoResource.java` class by executing the following in a terminal: 510 | 511 | ``` 512 | gp open src/main/java/com/datastaxdev/todo/rest/TodoResource.java 513 | ``` 514 | 515 | Notice some methods return [Mutiny reactive types](https://quarkus.io/guides/mutiny-primer) (i.e. `Uni` and `Multi`) while others return non-reactive types (i.e. `String`, `Response`, and `void`). Quarkus doesn't care whether you write reactive or blocking code. Quarkus will make sure reactive code runs on the I/O thread while blocking code will be moved off onto worker thread(s). As you can see, you can even mix and match within the same class! 516 | 517 | This application was designed to illustrate both approaches. Which methods are implemented in which manner were randomly chosen. 518 | 519 | [🏠 Back to Table of Contents](#0-table-of-contents) 520 | 521 | ## 8. Debugging 522 | 523 | You can always get back to the file explorer view whenever by clicking on the hamburger menu on the top left followed by `View` and `Explorer` as shown below. 524 | 525 | ![gitpod](images/tutorials/Filexplorer0.png?raw=true) 526 | 527 | Let's go ahead and hit `q` or `Ctrl+C` to exit out of the running application if you have not already. 528 | 529 | Before we set a breakpoint and start debugging, let's explain the application's structure a bit. The `TodoResource` class (which you saw in the previous section) calls a `com.datastaxdev.todo.service.AstraService`. `AstraService` is an interface with 2 implementations: 530 | 1. `com.datastaxdev.todo.service.CqlSessionAstraService.java` 531 | - Uses the `com.datastax.oss.quarkus.runtime.api.session.QuarkusCqlSession` directly using CQL queries to implement the operations. 532 | 2. `com.datastaxdev.todo.service.MapperAstraService.java` 533 | - Uses the [DataStax Object Mapper](https://docs.datastax.com/en/developer/java-driver/latest/manual/mapper) and [Cassandra Entity Modeling](https://quarkus.io/guides/cassandra#creating-the-data-model-and-data-access-objects) to model entities as Java objects, greatly simplifying the application's data access layer by sparing you the hassle of writing CQL queries by hand. This is conceptually similar to how [Hibernate](https://hibernate.org) works in the [JPA](https://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html) world. 534 | - Uses [Mapstruct](https://mapstruct.org) to easily convert between the `com.datastaxdev.todo.dao.TodoItem` dao entities and the `com.datastaxdev.todo.api.Todo` POJO used at the REST layer. See the `com.datastaxdev.todo.mapping.TodoMapper` class for details. 535 | 536 | The application has a [build-time property](https://quarkus.io/guides/cdi-reference#enable_build_properties) (not overridable at runtime) called `astra-service.type`. Resolving dependency injection at build time is one of the key benefits of Quarkus, allowing Quarkus applications to be super small and memory-performant. 537 | 538 | By default, if this property is undefined _OR_ has the value `cql-session`, `com.datastaxdev.todo.service.CqlSessionAstraService` will be injected as the implementation for `com.datastaxdev.todo.service.AstraService`. 539 | 540 | If, at build time, `astra-service.type=dao`, then `com.datastaxdev.todo.service.MapperAstraService` will be used instead. 541 | 542 | The `com.datastaxdev.todo.config.AstraConfig` class contains everything needed for reading the `astra-service.type` flag at build time and injecting the appropriate `com.datastaxdev.todo.service.AstraService` implementation. 543 | 544 | There is a full suite of unit tests that cover both implementations! See `src/test/java/com/datastaxdev/todo/service/CqlSessionAstraServiceTests.java` and `src/test/java/com/datastaxdev/todo/service/MapperAstraServiceTests.java` for details. 545 | 546 | > If you'd like to play around with the mapper implementation, open `src/main/resources/application.properties` and un-comment the line `#astra-service.type=dao`. 547 | 548 | Since the application, by default, uses the `com.datastaxdev.todo.service.CqlSessionAstraService` implementation, we'll use that implementation for setting the breakpoint. 549 | 550 | ✅ **Step 8a: Set breakpoint** 551 | 552 | Now issue the following command to open up the file where we will subsequently set a breakpoint to be hit whenever we create a new todo item. 553 | 554 | ``` 555 | gp open src/main/java/com/datastaxdev/todo/service/CqlSessionAstraService.java 556 | ``` 557 | 558 | Now navigate to line 52 and set a breakpoint by clicking to the left of the line number 52 and you'll see a stop sign as shown below. 559 | 560 | ![gitpod](images/tutorials/debug1.png?raw=true) 561 | 562 | Re-run the application with the following command and we will debug it live. 563 | 564 | ```bash 565 | ./mvnw quarkus:dev 566 | ``` 567 | 568 | ✅ **Step 8b: Start debugging** 569 | 570 | First, click on the debug button on the left towards top. 571 | 572 | Then, click on the arrow on the top left to start debugging as shown below. 573 | 574 | ![gitpod](images/tutorials/debug2.png?raw=true) 575 | 576 | Notice debug related information populate in the left side of the window as shown below. 577 | 578 | ![gitpod](images/tutorials/debug3.png?raw=true) 579 | 580 | > If for some reason the debugger doesn't attach, there may be some weirdness going on with the Gitpod IDE. Refreshing the browser tab containing the workspace or restarting the workspace will usually fix it. 581 | 582 | We will demonstrate debugging by fixing a todo item that was entered although there are more powerful features that you can try. 583 | 584 | Go to the new browser window you created and the application should be up and running. Hit enter after filling up a todo item as shown below. The application freezes and you see a red square that signals the breakpoint has been hit. 585 | 586 | ![gitpod](images/tutorials/debug4.png?raw=true) 587 | 588 | Now that you hit the breakpoint, Cool! Let's go back to the Gitpod window and verify if the breakpoint was really hit. You should see something like below. 589 | 590 | **👁️ Expected output** 591 | 592 | ![gitpod](images/tutorials/debug5.png?raw=true) 593 | 594 | ✅ **Step 8c: Use debugger features** 595 | 596 | Now, fix the entry spelling in debug mode by clicking on the left(>) arrow of `todo`, double clicking on the `title` entry and entering `debugging`. Finally, hit arrow button in the top small middle pane in the center which will allow the application to continue as shown below. 597 | 598 | ![gitpod](images/tutorials/debug6.png?raw=true) 599 | 600 | Go back to your browser and check the todo item that was added to the list. You should see that the updated entry that you fixed with a debug session is what's persisted. 601 | 602 | Hit `q` or `Ctrl+C` in the GitPod terminal window to exit the application. 603 | 604 | [🏠 Back to Table of Contents](#0-table-of-contents) 605 | 606 | ## 9. Packaging 607 | 608 | ✅ **Step 9a: Package** 609 | You can package up the application with the command below. 610 | 611 | ```bash 612 | ./mvnw clean package -DskipTests 613 | ``` 614 | 615 | **👁️ Expected output** 616 | 617 | ``` 618 | Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 619 | [INFO] Scanning for projects... 620 | [INFO] 621 | [INFO] ---------< quarkus-astra-intro-demo:quarkus-astra-intro-demo >---------- 622 | [INFO] Building quarkus-astra-intro-demo 0.01 623 | [INFO] --------------------------------[ jar ]--------------------------------- 624 | [INFO] 625 | [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ quarkus-astra-intro-demo --- 626 | [INFO] Deleting /workspace/quarkus-astra-intro-demo/target 627 | [INFO] 628 | [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ quarkus-astra-intro-demo --- 629 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 630 | [INFO] Copying 24 resources 631 | [INFO] 632 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code (default) @ quarkus-astra-intro-demo --- 633 | [INFO] 634 | [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ quarkus-astra-intro-demo --- 635 | [INFO] Changes detected - recompiling the module! 636 | [INFO] Compiling 10 source files to /workspace/quarkus-astra-intro-demo/target/classes 637 | [INFO] 638 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code-tests (default) @ quarkus-astra-intro-demo --- 639 | [INFO] 640 | [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ quarkus-astra-intro-demo --- 641 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 642 | [INFO] Copying 1 resource 643 | [INFO] 644 | [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ quarkus-astra-intro-demo --- 645 | [INFO] Changes detected - recompiling the module! 646 | [INFO] Compiling 6 source files to /workspace/quarkus-astra-intro-demo/target/test-classes 647 | [INFO] 648 | [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ quarkus-astra-intro-demo --- 649 | [INFO] Tests are skipped. 650 | [INFO] 651 | [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ quarkus-astra-intro-demo --- 652 | [INFO] Building jar: /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01.jar 653 | [INFO] 654 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:build (default) @ quarkus-astra-intro-demo --- 655 | [WARNING] [io.quarkus.config] Unrecognized configuration key "quarkus.kubernetes.env.secrets" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 656 | [WARNING] [io.quarkus.config] Unrecognized configuration key "quarkus.kubernetes.service-type" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 657 | [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 2076ms 658 | [INFO] ------------------------------------------------------------------------ 659 | [INFO] BUILD SUCCESS 660 | [INFO] ------------------------------------------------------------------------ 661 | [INFO] Total time: 9.681 s 662 | [INFO] Finished at: 2022-05-16T20:21:41Z 663 | [INFO] ------------------------------------------------------------------------ 664 | ``` 665 | 666 | ✅ **Step 9b: Run** 667 | 668 | You can run the recently packaged application as below. 669 | 670 | ```bash 671 | java -jar ./target/quarkus-app/quarkus-run.jar 672 | ``` 673 | 674 | **👁️ Expected output** 675 | 676 | ``` 677 | Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 678 | __ ____ __ _____ ___ __ ____ ______ 679 | --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 680 | -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ 681 | --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 682 | WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.service-type" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 683 | WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.env.secrets" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo 684 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientRecorder] (main) Enabling Cassandra metrics using Micrometer. 685 | INFO [io.qua.sma.ope.run.OpenApiRecorder] (main) Default CORS properties will be used, please use 'quarkus.http.cors' properties instead 686 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientStarter] (main) Eagerly initializing Quarkus Cassandra client. 687 | INFO [com.dat.oss.dri.int.cor.DefaultMavenCoordinates] (main) DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.14.0 688 | INFO [com.dat.oss.dri.int.cor.tim.Clock] (vert.x-eventloop-thread-0) Using native clock for microsecond precision 689 | INFO [com.dat.oss.dri.int.cor.ses.DefaultSession] (vert.x-eventloop-thread-9) [s0] Negotiated protocol version V4 for the initial contact point, but cluster seems to support V5, keeping the negotiated version 690 | INFO [com.dat.tod.res.TodoResource] (main) **** Table created true**** 691 | INFO [io.quarkus] (main) quarkus-astra-intro-demo 0.01 on JVM (powered by Quarkus 2.9.1.Final) started in 3.882s. Listening on: http://0.0.0.0:8080 692 | INFO [io.quarkus] (main) Profile prod activated. 693 | INFO [io.quarkus] (main) Installed features: [cassandra-client, cdi, micrometer, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-health, smallrye-openapi, swagger-ui, vertx] 694 | ``` 695 | 696 | You can play with the application from the new browser window you created in step 4. 697 | 698 | Hit `Ctrl+C` in the GitPod terminal window to exit the application. 699 | 700 | [🏠 Back to Table of Contents](#0-table-of-contents) 701 | 702 | ## 10. Containerizing 703 | 704 | ✅ **Step 10a: Adjust for containerization** 705 | 706 | We are using the [Quarkus Jib container extension](https://quarkus.io/guides/container-image#jib) for easy containerization. Copy the secure connect bundle to the directory that Jib will create on the container as below. We take advantage of the property of Jib plugin which automaticaly includes the relevant artifacts from the `src/main/jib` sub-directory as part of the process -- we include the secure connect bundle to be able to connect to the Astra database. 707 | 708 | 709 | ```bash 710 | mkdir -p src/main/jib/workspace/quarkus-astra-intro-demo/ 711 | cp secure-connect-workshops.zip src/main/jib/workspace/quarkus-astra-intro-demo/ 712 | ``` 713 | 714 | ✅ **Step 10b: Containerize** 715 | 716 | Let's containerize the application with the following command. 717 | 718 | ```bash 719 | ./mvnw clean package -Dquarkus.container-image.build=true -DskipTests 720 | ``` 721 | 722 | Once complete, check that the image exists on your local repository with the following command: 723 | 724 | ```bash 725 | docker images 726 | ``` 727 | 728 | **Expected Output** 729 | 730 | ``` 731 | REPOSITORY TAG IMAGE ID CREATED SIZE 732 | gitpod/quarkus-cassandra 0.01 77431983359a 26 seconds ago 216MB 733 | ``` 734 | 735 | ✅ **Step 10c: Run the containerized image** 736 | 737 | You can execute the recently generated containerized image with the following command. 738 | 739 | ```bash 740 | docker run -i --rm -p 8080:8080 gitpod/quarkus-cassandra:0.01 741 | ``` 742 | 743 | Hit in the GitPod terminal window to exit the application. 744 | 745 | ✅ **Step 10d: docker login** 746 | 747 | Login to Dockerhub to be able to push containerized images and to be able for you and the rest of the world to pull them. 748 | 749 | If you do not have a docker login credential you can skip this step and go right to [Native Image](#11-native-image) 750 | 751 | ```bash 752 | docker login 753 | ``` 754 | 755 | **Expected Output** 756 | 757 | ``` 758 | Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. 759 | Username: ragsns 760 | Password: 761 | WARNING! Your password will be stored unencrypted in /home/gitpod/.docker/config.json. 762 | Configure a credential helper to remove this warning. See 763 | https://docs.docker.com/engine/reference/commandline/login/#credentials-store 764 | 765 | Login Succeeded 766 | ``` 767 | 768 | Get the Docker ID as below. 769 | 770 | ```bash 771 | docker system info | grep -E 'Username' || echo "you have not done a docker login(yet)" 772 | DOCKER_LOGINID=$(docker system info | grep -E 'Username' | awk '{print $2}') 773 | echo "Docker login ID that will be used: " "$DOCKER_LOGINID" 774 | ``` 775 | 776 | You should see an output of your Docker Login ID. If you do not see this repeat this step from the beginning. 777 | 778 | ``` 779 | Docker login ID that will be used: ragsns 780 | ``` 781 | 782 | ✅ **Step 10e: Push to Dockerhub** 783 | 784 | Let's not only build the containerized image but also push it to DockerHub (**be sure to substitute the group with docker ID**) with the following command. 785 | 786 | ```bash 787 | ./mvnw clean package -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true -Dquarkus.container-image.group=$DOCKER_LOGINID -DskipTests 788 | ``` 789 | 790 | **NOTE:** If the repo in your Docker Hub account didn't previously exist it will be created for you as a _private_ repo. You will need to go into your Docker Hub account and make the repo public. 791 | 792 | In today's world of microservices and service meshes, it's all about deploying to Kubernetes. Quarkus gives us an easy way to do that! 793 | 794 | **Step A**: Quarkus includes the [Kubernetes extension](https://quarkus.io/guides/deploying-to-kubernetes), allowing developers to deploy directly to Kubernetes and use Kubernetes `ConfigMap`s and `Secret`s as configuration sources. To use this update `pom.xml` with the following command in the Gitpod ternimal window as below. 795 | 796 | ```bash 797 | ./mvnw quarkus:add-extension -Dextensions="kubernetes" 798 | ``` 799 | 800 | and verify with the following command 801 | 802 | ```bash 803 | git diff pom.xml 804 | ``` 805 | 806 | which should that the `io.quarkus:quarkus-kubernetes` dependency has been added. 807 | 808 | ```bash 809 | diff --git a/pom.xml b/pom.xml 810 | index 371e35e..4b842d8 100644 811 | --- a/pom.xml 812 | +++ b/pom.xml 813 | + 814 | + io.quarkus 815 | + quarkus-kubernetes 816 | + 817 | ``` 818 | 819 | **Step B**: 820 | Ensure that `DOCKER_LOGINID` was set in the earlier step as below and the command should output the Docker login ID. 821 | 822 | ``` 823 | echo $DOCKER_LOGINID 824 | ``` 825 | 826 | Next, let's generate the containerized image with the secrets as below. 827 | 828 | ``` 829 | ./mvnw clean package -Dquarkus.container-image.build=true -Dquarkus.container-image.push=false -Dquarkus.container-image.group=$DOCKER_LOGINID -DskipTests 830 | ``` 831 | 832 | Next, let's generate and push the containerized image with the secrets removed as below. 833 | 834 | ``` 835 | sed -i '/# TBD Below/,+4 d' ./target/classes/application.properties 836 | ./mvnw package -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true -Dquarkus.container-image.group=$DOCKER_LOGINID -DskipTests 837 | ``` 838 | 839 | ✅ **Step 10f: Stand up application in Kubernetes** 840 | 841 | 842 | Hereafter, there are two paths -- steps prefixed with `Lens` OR steps prefixed with `Okteto` as summarized below. 843 | 844 | |Steps prefixed with|Details| First step| 845 | | ----------- | ----------- |-----| 846 | |Lens| Install on Lens IDE|Lens.A 847 | |Okteto| Sample Kubernetes provider|Okteto.A 848 | 849 | If you're familiar with using `kubectl` command you can pick either. If you're not you're recommended to use Steps prefixed with `Lens`. 850 | 851 | **Step Lens.A**: Download Lens 852 | 853 | [Lens](https://k8slens.dev/) is a popular Integrated Development Environment (IDE) for Kubernetes and enables developers and engineers to develop and deploy apps on multiple clusters and adminster them easier than using command line tools like `kubectl`. 854 | 855 | [Download](https://docs.k8slens.dev/main/#downloading-lens) Lens on your local system. 856 | 857 | **Step Lens.B**: Download, install and run Lens Desktop 858 | 859 | Sign up for a free trial and download Lens desktop and install it as shown below. Make sure you select the tiny icon on the bottom left and click on the free trial as shown below. 860 | 861 | ![lens](images/tutorials/LensDownload1.png?raw=true) 862 | 863 | 864 | If needed, launch the desktop manually as shown below. 865 | 866 | ![lens](images/tutorials/LensLaunchManual1.png?raw=true) 867 | 868 | After the launch the Lens Desktop might be in a stopped state as shown in the bottom left below. 869 | 870 | ![lens](images/tutorials/LensStop1.png?raw=true) 871 | 872 | Click on the `Lens Desktop Kube: Stopped` and pick appropriate values as shown below. 873 | 874 | ![lens](images/tutorials/Lensvalues1.png?raw=true) 875 | 876 | Note that the current state is shown as stopped as shown below. 877 | 878 | ![lens](images/tutorials/LensStopped1.png?raw=true) 879 | 880 | Toggle the button as shown below to move it from stopped to running. 881 | 882 | ![lens](images/tutorials/LensRunning1.png?raw=true) 883 | 884 | Make sure that Lens is running as shown below. **It might take well over five minutes for the state to move to running.** 885 | 886 | ![lens](images/tutorials/LensRunning2.png?raw=true) 887 | 888 | You should have Lens desktop in your clusters list as shown below. 889 | 890 | ![lens](images/tutorials/LensLDK1.png?raw=true) 891 | 892 | Now that Lens Desktop is installed, up and running we're ready to deploy the ToDo app. 893 | 894 | **Step Lens.C**: Set up secrets 895 | 896 | Start by clicking on `Config`, `Secrets` and `+` as shown below. 897 | 898 | ![lens](images/tutorials/Lenssecret01.png?raw=true) 899 | 900 | Now add the secret `astra` and the secrets `astra-username` and `astra-password` as shown below. 901 | 902 | ![lens](images/tutorials/Lenssecret02.png?raw=true) 903 | 904 | You can verify you entered the values correctly by hitting the button as shown below which will show the values in clear. 905 | 906 | ![lens](images/tutorials/Lenssecret03.png?raw=true) 907 | 908 | **Step Lens.D**: Start the workload 909 | 910 | We use the generated `kubernetes.yml` file to install the workload in Lens. 911 | 912 | Click on `+` and `Create resource` as shown below. 913 | 914 | ![lens](images/tutorials/Lensresource01.png?raw=true) 915 | 916 | We are going to cut-n-paste the contents from the Gitpod window into Lens. 917 | 918 | Issue the following command in the Gitpod terminal window to look at the Kubernetes manifests that were automatically generated and applied to the cluster. 919 | 920 | ``` 921 | gp open target/kubernetes/kubernetes.yml 922 | ``` 923 | 924 | and cut-n-paste the contents into Lens as shown below and hit `Create` as shown below. 925 | 926 | ![lens](images/tutorials/Lensresource02.png?raw=true) 927 | 928 | If you dig into `Pods` you should be see it running as shown below. 929 | 930 | ![lens](images/tutorials/Lensresource03.png?raw=true) 931 | 932 | You can look through other Kubernetes artifacts which you can easily navigate via Lens. 933 | 934 | **Step Lens.F**: Setup port forwarding 935 | 936 | Click on Network, Services and Forward... as shown below. 937 | 938 | ![lens](images/tutorials/LensPortForward1.png?raw=true) 939 | 940 | Next forward to `8080` as shown below. 941 | 942 | ![lens](images/tutorials/LensPortForward2.png?raw=true) 943 | 944 | This will setup the port forwarding to the appropriate pod. Ignore errors if any. You can now access the app via `8080` on `localhost`. 945 | 946 | **Step Lens.G**: Cleanup 947 | 948 | You can delete the service, deployment and secret using Lens. 949 | 950 | You're now done with Lens deployment and can skip other deployment(s). 951 | 952 | **OR** 953 | 954 | **Step Okteto.A**: Create a cluster 955 | 956 | We've included some steps here using [okteto](https://www.okteto.com) (you can modify the steps below depending on your choice of provider). 957 | 958 | Create a Kubernetes cluster. You can get one for free at [https://okteto.com](https://okteto.com) with your Github credentials. 959 | 960 | **Step Okteto.B**: Download config file 961 | 962 | Download the `config` file from [https://cloud.okteto.com/#/settings/setup](https://cloud.okteto.com/#/settings/setup) locally as shown below. 963 | 964 | ![okteto](images/tutorials/oktetoconfig1.png?raw=true) 965 | 966 | **Step Okteto.C**: Drag and drop config into Gitpod 967 | 968 | Now "drag and drop" it over to the gitpod window (similar to how we transferred the secure connect bundle) as shown below. 969 | 970 | ![okteto](images/tutorials/oktetoconfig2.png?raw=true) 971 | 972 | **Step Okteto.D**: Setup config in Gitpod window 973 | 974 | Use the transferred okteto config file with the following command in the Gitpod terminal window and verify 975 | 976 | ```bash 977 | export KUBECONFIG=okteto-kube.config 978 | kubectl config get-contexts 979 | kubectl get all 980 | ``` 981 | 982 | If you get a message like `error: You must be logged in to the server (Unauthorized)` reauthorize and download the `okteto-kube.config` file again. 983 | 984 | Since okteto only provides access to your namespace, you should see something like below and you won't be able to run other commands like you would normally with a cluster that you created. 985 | 986 | ``` 987 | No resources found in ragsns namespace. 988 | ``` 989 | 990 | **Step Okteto.E**: Setup secrets 991 | 992 | The `application.properties` file is setup to use the Kubernetes secrets already (`quarkus.kubernetes.env.secrets=astra`). Setup the Kubernetes secrets as below from the`Client Id` and `Client Secret` respectively as we did earlier. 993 | 994 | ``` 995 | kubectl create secret generic astra --from-literal=astra-username= --from-literal=astra-password= 996 | ``` 997 | 998 | Verify the screts are setup properly with the following commands. 999 | 1000 | ```bash 1001 | kubectl get secret astra -o jsonpath="{.data.astra-username}" | base64 --decode 1002 | kubectl get secret astra -o jsonpath="{.data.astra-password}" | base64 --decode 1003 | ``` 1004 | 1005 | The `kubernetes.yml` deployment file that will be generated in the next step will be setup to use the secrets. 1006 | 1007 | **Step Okteto.F**: Push image 1008 | 1009 | You may want to remove the actual values of `astra-username` and `astra-password` from the`application.properties` file as below before pushing the container image to a public registry. 1010 | 1011 | ``` 1012 | sed -i '/# TBD Below/,+4 d' ./target/classes/application.properties 1013 | ./mvnw package -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true -Dquarkus.container-image.group=$DOCKER_LOGINID -Dquarkus.kubernetes.deploy=true -DskipTests 1014 | ``` 1015 | 1016 | The result of this command will be that your application's container image is built, pushed to the registry, and then deployed on Kubernetes. The Quarkus Kubernetes extension generates all the necessary Kubernetes desriptors for you. 1017 | 1018 | Issue the following command in the Gitpod terminal window to look at the Kubernetes manifests that were automatically generated and applied to the cluster. 1019 | 1020 | ``` 1021 | gp open target/kubernetes/kubernetes.yml 1022 | ``` 1023 | 1024 | You should see the following output which indicates the deployment and the service have been created. **You can ignore errors related to webhook.** 1025 | 1026 | ``` 1027 | [INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Pushed container image xxx/quarkus-cassandra:0.01 (sha256:xxxxxx) 1028 | 1029 | [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Deploying to kubernetes server: https://a.b.c.d:443/ in namespace: xxxx. 1030 | [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Service quarkus-cassandra. 1031 | [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Deployment quarkus-cassandra. 1032 | [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 12904ms 1033 | ``` 1034 | 1035 | Running the command 1036 | 1037 | ```bash 1038 | kubectl get all 1039 | ``` 1040 | 1041 | should yield a different output as below. 1042 | 1043 | ``` 1044 | NAME READY STATUS RESTARTS AGE 1045 | pod/quarkus-cassandra-5f4d69b8d-lx46l 1/1 Running 0 95s 1046 | 1047 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 1048 | service/quarkus-cassandra ClusterIP 10.154.219.218 80/TCP 96s 1049 | 1050 | NAME READY UP-TO-DATE AVAILABLE AGE 1051 | deployment.apps/quarkus-cassandra 1/1 1 1 96s 1052 | 1053 | NAME DESIRED CURRENT READY AGE 1054 | replicaset.apps/quarkus-cassandra-5f4d69b8d 1 1 1 96s 1055 | ``` 1056 | 1057 | You should be able to access the application from the endpoint provided by the [okteto console](https://cloud.okteto.com/#/spaces) and also be able to access the application logs as shown below. 1058 | 1059 | ![okteto](images/tutorials/oktetorunning1.png?raw=true) 1060 | 1061 | Alternately, you can access the application provided by the gitpod URL like we have always been doing throughout the workshop by issuing the following command. 1062 | 1063 | ``` 1064 | kubectl port-forward svc/quarkus-cassandra 8080:80 & 1065 | ``` 1066 | 1067 | **Step Okteto.G**: Cleanup 1068 | 1069 | You can stop the port forwarding by deleting the background job as below. 1070 | 1071 | ``` 1072 | kill -9 %1 1073 | ``` 1074 | 1075 | You can go ahead and get rid of the application as well with the following command from the Gitpod terminal window. 1076 | 1077 | ``` 1078 | kubectl delete all --all 1079 | ``` 1080 | 1081 | and you should see the following output. 1082 | 1083 | ``` 1084 | pod "quarkus-cassandra-886d9f8b9-h7tw5" deleted 1085 | service "quarkus-cassandra" deleted 1086 | deployment.apps "quarkus-cassandra" deleted 1087 | ``` 1088 | 1089 | Additionally, you should delete the `Secret` you created. 1090 | 1091 | ``` 1092 | kubectl delete secret astra 1093 | ``` 1094 | 1095 | If the public docker image contains the credentials to be able to access the database, it's a good idea to delete the docker image [from docker hub](http://hub.docker.com) right away, anyway. 1096 | 1097 | [🏠 Back to Table of Contents](#0-table-of-contents) 1098 | 1099 | ## 11. Native Image 1100 | 1101 | Finally, Quarkus can build a native executable image with the help of the GraalVM that was pre-installed with a simple command as below. **Get yourself some coffee** or water as this will take almost 10 minutes but exceuting this image will be super fast with minimal startup time since it does not depend on the JVM. 1102 | 1103 | ✅ **Step 11a: Generating Native Image** 1104 | 1105 | ```bash 1106 | ./mvnw clean package -Pnative -DskipTests 1107 | ``` 1108 | 1109 | **Expected output:** 1110 | 1111 | ``` 1112 | Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 1113 | [INFO] Scanning for projects... 1114 | [INFO] 1115 | [INFO] ---------< quarkus-astra-intro-demo:quarkus-astra-intro-demo >---------- 1116 | [INFO] Building quarkus-astra-intro-demo 0.01 1117 | [INFO] --------------------------------[ jar ]--------------------------------- 1118 | [INFO] 1119 | [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ quarkus-astra-intro-demo --- 1120 | [INFO] Deleting /workspace/quarkus-astra-intro-demo/target 1121 | [INFO] 1122 | [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ quarkus-astra-intro-demo --- 1123 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 1124 | [INFO] Copying 24 resources 1125 | [INFO] 1126 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code (default) @ quarkus-astra-intro-demo --- 1127 | [INFO] 1128 | [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ quarkus-astra-intro-demo --- 1129 | [INFO] Changes detected - recompiling the module! 1130 | [INFO] Compiling 10 source files to /workspace/quarkus-astra-intro-demo/target/classes 1131 | [INFO] 1132 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:generate-code-tests (default) @ quarkus-astra-intro-demo --- 1133 | [INFO] 1134 | [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ quarkus-astra-intro-demo --- 1135 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 1136 | [INFO] Copying 1 resource 1137 | [INFO] 1138 | [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ quarkus-astra-intro-demo --- 1139 | [INFO] Changes detected - recompiling the module! 1140 | [INFO] Compiling 6 source files to /workspace/quarkus-astra-intro-demo/target/test-classes 1141 | [INFO] 1142 | [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ quarkus-astra-intro-demo --- 1143 | [INFO] Tests are skipped. 1144 | [INFO] 1145 | [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ quarkus-astra-intro-demo --- 1146 | [INFO] Building jar: /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01.jar 1147 | [INFO] 1148 | [INFO] --- quarkus-maven-plugin:2.9.1.Final:build (default) @ quarkus-astra-intro-demo --- 1149 | [INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building native image source jar: /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01-native-image-source-jar/quarkus-astra-intro-demo-0.01-runner.jar 1150 | [INFO] Checking for existing resources in: /workspace/quarkus-astra-intro-demo/src/main/kubernetes. 1151 | [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Building native image from /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01-native-image-source-jar/quarkus-astra-intro-demo-0.01-runner.jar 1152 | [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Running Quarkus native-image plugin on GraalVM 22.0.0.2 Java 11 CE (Java Version 11.0.14+9-jvmci-22.0-b05) 1153 | [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] /home/gitpod/.sdkman/candidates/java/current/bin/native-image -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=en -J-Duser.country=US -J-Dfile.encoding=UTF-8 -H:-ParseOnce -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy\$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -J-Djava.awt.headless=true -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http,https -H:NativeLinkerOption=-no-pie -H:-UseServiceLoaderFeature -H:+StackTrace quarkus-astra-intro-demo-0.01-runner -jar quarkus-astra-intro-demo-0.01-runner.jar 1154 | Picked up JAVA_TOOL_OPTIONS: -Xmx3435m 1155 | ======================================================================================================================== 1156 | GraalVM Native Image: Generating 'quarkus-astra-intro-demo-0.01-runner'... 1157 | ======================================================================================================================== 1158 | [1/7] Initializing... (4.9s @ 0.42GB) 1159 | Version info: 'GraalVM 22.0.0.2 Java 11 CE' 1160 | 3 user-provided feature(s) 1161 | - io.quarkus.runner.AutoFeature 1162 | - io.quarkus.runtime.graal.DisableLoggingAutoFeature 1163 | - io.quarkus.runtime.graal.ResourcesFeature 1164 | [2/7] Performing analysis... [20:33:32,360 INFO [com.dat.oss.qua.run.int.qua.CassandraClientRecorder] Enabling Cassandra metrics using Micrometer. 1165 | 20:33:36,471 INFO [com.dat.oss.dri.int.cor.DefaultMavenCoordinates] DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.14.0 1166 | **********] (31.7s @ 2.17GB) 1167 | 14,155 (95.32%) of 14,850 classes reachable 1168 | 20,586 (66.60%) of 30,912 fields reachable 1169 | 69,696 (82.00%) of 84,993 methods reachable 1170 | 482 classes, 39 fields, and 850 methods registered for reflection 1171 | 68 classes, 88 fields, and 54 methods registered for JNI access 1172 | [3/7] Building universe... (2.0s @ 2.69GB) 1173 | [4/7] Parsing methods... [***] (5.3s @ 1.81GB) 1174 | [5/7] Inlining methods... [*****] (4.7s @ 3.18GB) 1175 | [6/7] Compiling methods... [*****] (22.6s @ 3.42GB) 1176 | [7/7] Creating image... (4.3s @ 2.54GB) 1177 | 25.64MB (36.89%) for code area: 46,599 compilation units 1178 | 37.07MB (53.33%) for image heap: 9,899 classes and 350,222 objects 1179 | 6.80MB ( 9.78%) for other data 1180 | 69.50MB in total 1181 | ------------------------------------------------------------------------------------------------------------------------ 1182 | Top 10 packages in code area: Top 10 object types in image heap: 1183 | 1.67MB sun.security.ssl 19.83MB byte[] for general heap data 1184 | 1.03MB java.util 3.40MB java.lang.Class 1185 | 686.94KB com.sun.crypto.provider 2.65MB java.lang.String 1186 | 531.52KB io.quarkus.runtime.generated 2.21MB byte[] for java.lang.String 1187 | 490.01KB sun.security.x509 627.75KB java.util.HashMap$Node 1188 | 458.87KB java.util.concurrent 581.63KB java.util.LinkedHashMap 1189 | 446.33KB io.netty.buffer 534.65KB com.oracle.svm.core.util.LazyFinalReference 1190 | 426.93KB com.oracle.svm.core.reflect 526.91KB java.lang.String[] 1191 | 425.74KB com.typesafe.config.impl 439.28KB byte[] for method metadata 1192 | 379.99KB java.lang 427.69KB c.o.s.c.h.DynamicHub$$Lambda$~31d9af6a7fe68cfc2a1f 1193 | ... 661 additional packages ... 3407 additional object types 1194 | (use GraalVM Dashboard to see all) 1195 | ------------------------------------------------------------------------------------------------------------------------ 1196 | 6.2s (7.7% of total time) in 40 GCs | Peak RSS: 5.21GB | CPU load: 4.98 1197 | ------------------------------------------------------------------------------------------------------------------------ 1198 | Produced artifacts: 1199 | /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01-native-image-source-jar/quarkus-astra-intro-demo-0.01-runner (executable) 1200 | /workspace/quarkus-astra-intro-demo/target/quarkus-astra-intro-demo-0.01-native-image-source-jar/quarkus-astra-intro-demo-0.01-runner.build_artifacts.txt 1201 | ======================================================================================================================== 1202 | Finished generating 'quarkus-astra-intro-demo-0.01-runner' in 1m 20s. 1203 | [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] objcopy --strip-debug quarkus-astra-intro-demo-0.01-runner 1204 | [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 83782ms 1205 | [INFO] ------------------------------------------------------------------------ 1206 | [INFO] BUILD SUCCESS 1207 | [INFO] ------------------------------------------------------------------------ 1208 | [INFO] Total time: 01:29 min 1209 | [INFO] Finished at: 2022-05-16T20:34:47Z 1210 | [INFO] ------------------------------------------------------------------------ 1211 | ``` 1212 | 1213 | ✅ **Step 11b: Running Native Image** 1214 | 1215 | Run the native image with the following command: 1216 | 1217 | ```bash 1218 | ./target/quarkus-astra-intro-demo-0.01-runner 1219 | ``` 1220 | 1221 | ``` 1222 | __ ____ __ _____ ___ __ ____ ______ 1223 | --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 1224 | -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ 1225 | --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 1226 | INFO [io.qua.sma.ope.run.OpenApiRecorder] (main) Default CORS properties will be used, please use 'quarkus.http.cors' properties instead 1227 | INFO [com.dat.oss.qua.run.int.qua.CassandraClientStarter] (main) Eagerly initializing Quarkus Cassandra client. 1228 | INFO [com.dat.oss.dri.int.cor.os.Native] (vert.x-eventloop-thread-0) Using Graal-specific native functions 1229 | INFO [com.dat.oss.dri.int.cor.tim.Clock] (vert.x-eventloop-thread-0) Using native clock for microsecond precision 1230 | INFO [com.dat.oss.dri.int.cor.ses.DefaultSession] (vert.x-eventloop-thread-9) [s0] Negotiated protocol version V4 for the initial contact point, but cluster seems to support V5, keeping the negotiated version 1231 | INFO [com.dat.tod.res.TodoResource] (main) **** Table created true**** 1232 | INFO [io.quarkus] (main) quarkus-astra-intro-demo 0.01 native (powered by Quarkus 2.9.1.Final) started in 2.273s. Listening on: http://0.0.0.0:8080 1233 | INFO [io.quarkus] (main) Profile prod activated. 1234 | INFO [io.quarkus] (main) Installed features: [cassandra-client, cdi, kubernetes, micrometer, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-health, smallrye-openapi, swagger-ui, vertx] 1235 | ``` 1236 | 1237 | Notice the fast startup time since the image is running as a native image. 1238 | 1239 | Hit `Ctrl+C` in the GitPod terminal window to exit the application. 1240 | 1241 | [🏠 Back to Table of Contents](#0-table-of-contents) 1242 | 1243 | ## 12. Homework 1244 | 1245 | 1246 | 1247 | Don't forget to complete your upgrade and get your verified skill badge! Finish and submit your homework! You have 2 options (option A or Option B). Pick whichever works for you. 1248 | 1249 | Option A. Complete the practice steps from this repository as described above (including optional steps 10d and 10e) and deploy to a Kubernetes cluster. Make screenshots of the deployment to a Kubernetes cluster. 1250 | 1251 | Option B: Learn more about Quarkus and do some development with https://github.com/datastax/cassandra-quarkus. Send a screenshot of the working "Fruits application" with the following entry "Jackfruit" and the correpsonding description as "King/Queen of fruits". 1252 | 1253 | Submit your homework [here](https://docs.google.com/forms/d/e/1FAIpQLSd3hMHgHURsNGq2-jDAIr-XPLJGHqaRAm9CAMkYveybuYfBRw/viewform) 1254 | 1255 | That's it, you are done! Expect an email next week! 1256 | 1257 | [🏠 Back to Table of Contents](#0-table-of-contents) 1258 | 1259 | ## 13. The END 1260 | 1261 | Congratulations, your made it to the END of the show. 1262 | 1263 | 1264 | **🧑🏻‍🤝‍🧑🏽 Let's get in touch** 1265 | 1266 | | ![B](images/tutorials/rags.png) | 1267 | | ---------------------------------------------------------- | 1268 | | Rags Srinivas
[@ragsns](https://github.com/ragsns) | 1269 | 1270 | [🏠 Back to Table of Contents](#0-table-of-contents) 1271 | --- 1272 | 1273 | [![thankyou](images/tutorials/thankyou.gif)]() 1274 | -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/.DS_Store -------------------------------------------------------------------------------- /images/astra-create-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/astra-create-db.png -------------------------------------------------------------------------------- /images/astra-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/astra-login.png -------------------------------------------------------------------------------- /images/tutorials/AstraTodos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/AstraTodos.png -------------------------------------------------------------------------------- /images/tutorials/Filexplorer0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Filexplorer0.png -------------------------------------------------------------------------------- /images/tutorials/HW1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/HW1.png -------------------------------------------------------------------------------- /images/tutorials/Lens01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lens01.png -------------------------------------------------------------------------------- /images/tutorials/Lens02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lens02.png -------------------------------------------------------------------------------- /images/tutorials/LensDownload1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensDownload1.png -------------------------------------------------------------------------------- /images/tutorials/LensLDK1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensLDK1.png -------------------------------------------------------------------------------- /images/tutorials/LensLaunchManual1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensLaunchManual1.png -------------------------------------------------------------------------------- /images/tutorials/LensPortForward1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensPortForward1.png -------------------------------------------------------------------------------- /images/tutorials/LensPortForward2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensPortForward2.png -------------------------------------------------------------------------------- /images/tutorials/LensRunning1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensRunning1.png -------------------------------------------------------------------------------- /images/tutorials/LensRunning2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensRunning2.png -------------------------------------------------------------------------------- /images/tutorials/LensStop1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensStop1.png -------------------------------------------------------------------------------- /images/tutorials/LensStopped1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/LensStopped1.png -------------------------------------------------------------------------------- /images/tutorials/Lensresource01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lensresource01.png -------------------------------------------------------------------------------- /images/tutorials/Lensresource02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lensresource02.png -------------------------------------------------------------------------------- /images/tutorials/Lensresource03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lensresource03.png -------------------------------------------------------------------------------- /images/tutorials/Lenssecret01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lenssecret01.png -------------------------------------------------------------------------------- /images/tutorials/Lenssecret02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lenssecret02.png -------------------------------------------------------------------------------- /images/tutorials/Lenssecret03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lenssecret03.png -------------------------------------------------------------------------------- /images/tutorials/Lensvalues1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/Lensvalues1.png -------------------------------------------------------------------------------- /images/tutorials/NewSplash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/NewSplash.png -------------------------------------------------------------------------------- /images/tutorials/OpenPorts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/OpenPorts.png -------------------------------------------------------------------------------- /images/tutorials/allow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/allow.png -------------------------------------------------------------------------------- /images/tutorials/astra-create-db.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/astra-create-db.gif -------------------------------------------------------------------------------- /images/tutorials/astra-create-token.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/astra-create-token.gif -------------------------------------------------------------------------------- /images/tutorials/astra-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/astra-token.png -------------------------------------------------------------------------------- /images/tutorials/astra_signup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/astra_signup.gif -------------------------------------------------------------------------------- /images/tutorials/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/badge.png -------------------------------------------------------------------------------- /images/tutorials/db-pending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/db-pending.png -------------------------------------------------------------------------------- /images/tutorials/debug1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug1.png -------------------------------------------------------------------------------- /images/tutorials/debug2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug2.png -------------------------------------------------------------------------------- /images/tutorials/debug3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug3.png -------------------------------------------------------------------------------- /images/tutorials/debug4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug4.png -------------------------------------------------------------------------------- /images/tutorials/debug5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug5.png -------------------------------------------------------------------------------- /images/tutorials/debug6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/debug6.png -------------------------------------------------------------------------------- /images/tutorials/editapplicationproperties1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/editapplicationproperties1.png -------------------------------------------------------------------------------- /images/tutorials/editapplicationproperties2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/editapplicationproperties2.png -------------------------------------------------------------------------------- /images/tutorials/gitpod-01-home-annotated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/gitpod-01-home-annotated.png -------------------------------------------------------------------------------- /images/tutorials/gitpod-01-home-plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/gitpod-01-home-plain.png -------------------------------------------------------------------------------- /images/tutorials/gitpod-02-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/gitpod-02-url.png -------------------------------------------------------------------------------- /images/tutorials/gitpod-quarkus-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/gitpod-quarkus-1.jpg -------------------------------------------------------------------------------- /images/tutorials/newbrowser1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/newbrowser1.png -------------------------------------------------------------------------------- /images/tutorials/oktetoconfig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/oktetoconfig1.png -------------------------------------------------------------------------------- /images/tutorials/oktetoconfig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/oktetoconfig2.png -------------------------------------------------------------------------------- /images/tutorials/oktetorunning1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/oktetorunning1.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-0.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-1.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-2.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-3.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-4.png -------------------------------------------------------------------------------- /images/tutorials/quarkus-dev-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/quarkus-dev-5.png -------------------------------------------------------------------------------- /images/tutorials/rags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/rags.png -------------------------------------------------------------------------------- /images/tutorials/secureconnectbundle1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/secureconnectbundle1.png -------------------------------------------------------------------------------- /images/tutorials/secureconnectbundle2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/secureconnectbundle2.png -------------------------------------------------------------------------------- /images/tutorials/secureconnectbundle3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/secureconnectbundle3.png -------------------------------------------------------------------------------- /images/tutorials/splash-quarkus-cassandra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/splash-quarkus-cassandra.png -------------------------------------------------------------------------------- /images/tutorials/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/splash.png -------------------------------------------------------------------------------- /images/tutorials/stefano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/stefano.png -------------------------------------------------------------------------------- /images/tutorials/thankyou.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/images/tutorials/thankyou.gif -------------------------------------------------------------------------------- /slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/workshop-intro-quarkus-cassandra/7da83481d1f32f2d04d62579b3058777649926a8/slides.pdf --------------------------------------------------------------------------------