 Hello everybody. Welcome to our workshop and my colleagues. Okay, so what we are going to do today, I sent already a link to the chat, but I will send it one more, is a Quarkus Superheroes application, which is a set of, maybe I can share it really quickly. Hopefully this will work. So you should, if you open the link, you will get into the same page that I am in. Basically, this workshop is really written in a best possible way for you to go at your own self-pace. So what we would prefer is actually for you to go basically on your own and just ask us when you will get stuck, or you want us to explain something. However, if you would prefer, and please write this to chat to do this also on my screen. So I will go with you step by step, because I see that somebody is still in a bed. Then I can do that for sure. But really, I would prefer personally for you to go on your own pace, because there is a lot of stuff that you need to do actually on your machine, which doesn't really make sense for me to show on my machine. If you can see where I'm going. So I can then start maybe in half an hour if you prefer to really start coding the Quarkus applications themselves. So please write this to the chat. But for now, I would ask you to open that link that I sent to the chat and just go step by step and basically start with Installing Software section. So you have all necessary built tools installed before we will proceed, because this is really something that you need to have for us to finish that workshop successfully. I don't know if Martin or Ladislav want to say something. Now I think I agree. There's a lot of preparatory steps that you need to follow. And if you don't have all these tools yet, it wouldn't make much sense for anyone to go further. So yeah. But really, if you would like us to explain anything, just write it to the chat. We can even spin up some separate meeting for individual consultations. If you would like and otherwise, just please take it at your own pace. We will check in from time to time to see where you are going, if somebody needs to have something explained. But please jump in as you will go. So that would be everything from our introduction. So please start working on it. Basically in about 20, 30 minutes, I will check in if I should start coding it too with you. But really, I don't think it's necessary to the matter because it's really self-explanatory. I went through whole work yesterday, so I know that it works. So okay. Thank you for visiting our workshop and good luck. There is no response in the chat, so really nobody, even that person in the bed, doesn't want me to go really over this workshop with you. Okay then. Then please take it at your own pace. We will be still in this meeting. We will be checking out periodically. And if you get stuck, just write something into chat or ask. Marcin, there is a question in the chat. Is there in a link to GitHub repo instead of the zip? So we should probably answer. Yes, there is a GitHub repo with the completed project, but you should probably only use the repo if you are stuck, because otherwise you should start with the zip and then adding stuff as the workshop goes. Maybe I have a wrong chat done. I don't see the question. Probably you need to switch from event to session. Yeah, you got it. Thank you. Okay, I will use session chat then. Thank you, Durka. So just before we will continue, I would like to point you to the main and now I will be posting to the session chat, because I was recommended to the main Quarkus site, which is quarkus.io, where, and maybe I can share this too, where when you scroll totally down, hopefully, you should see how to join Quarkus community. And somewhere here, you will see that we are at Zulip, which is a communication platform, a platform where you can find all three of us, usually all the time. So the thank you for the link. So you probably won't be able to finish the full workshop in just two and a half hours. But if you would like to finish it, definitely you should. And if you get stuck or something, you can always catch us later on the Zulip chat if you will have any questions. Okay, so that's it. Thank you. Okay, so I am being told that you should see me normally, but for some reason, I am frozen on my side. So hopefully, at least you can hear me. Can you please write into the session chat, at least plus one or something that I am working on the workshop so we know how many people we are actually following, only one. Come on. Great. Okay, so it is very quiet for us. So I would like to go with you slowly, see where I can go. If you want to go on your own, please just mute me and do it on your own and write the questions to the session chat. Ladiya and Martin will be monitoring that. So they will answer your questions if you will go. And if somebody wants to follow with me, please go ahead. My camera is frozen, so hopefully nothing will be showing. It shouldn't be. But okay, let me share my screen. Well, just Martin, your camera is not frozen on our side. We can see you just. Yeah, exactly. It's frozen only on my side because of my home internet. So hopefully, I will not show something that I shouldn't. Okay, so you should be able to see my screen, and at least I can see my screen moving. That's great. Okay, so I will basically go slowly at my own pace and we'll see where I will get. So what we are going to create in this workshop is basically a set of microservices, which will be the streamlining fights between the superheroes and supervillains. It consists only of five services. If I remember correctly, one for hero, one for villains, which is basically crud operations on heroes and on villains, villains, fight service, which uses both hero and villain to get random heroes, random villains to fight. UI is an Angular application that it's just showing a nice pictures of everything and basically will give you an option to click that fight. Well, basically, Prometheus is also a standalone service, but it's not something that we are going to code ourselves. If you are familiar, if you're not familiar with what Prometheus is, it's an application service, which is basically polling individual applications for metrics or some statistics and can then display them in really nice structured way. And we also have our own statistics service, which will show some statistics that are specific to our application services. We have also here Kafka and ZooKeeper. We will get to it when we will get to it. And also we have a UI for that. I thought that is integrated in the statistics, but maybe I forgot. That doesn't matter. So when we will finish, hopefully successfully, our application should look like this. So we can trigger the fight, get new fighters, etc. Okay. So hopefully all of you already went through software requirements. I will skip that because I should have everything installed. So basically just copy paste this into terminal. Hopefully, this is big enough for everybody. Hopefully, Ladiah, Martin, can you? It's very small. Oh, come on. You are on your home computer, right? Okay. So basically, just copy paste these commands to your terminal. You should see something print for every of these commands. So I have Java 11 installed. I think that I don't have this installed. No, I don't have because I don't need to have Growl installed because Quarkus in the current version that we are using in the workshop already comes with an option which has a fallback for you if you don't have Growl VM installed and it will trigger the Growl VM image build inside Docker container. So this is what I'm using, but this only works on a Linux machine. So if you are not on Linux, you need to download and install Growl. But I'm not doing it for some quite some time now. Maven, I definitely should have because I'm working with it. Let's please make sure that the Java version that you are using in Maven corresponds to the Java version that you are printing here because this can be different if you have multiple Java installations on your machine. And Growl, I should have on Linux Docker version. Actually, if you are on Fedora, I think 33, 34 plus, we don't have no longer have an option to use Docker. So for me, Docker actually is podman. In the background, I just have alias installed. So when I type Docker BS, for instance, then I have a podman running on the background. And I have something here. So let me just do it. So we have a clean environment. Okay. And Docker compose, that's the same case for me because I am using podman. So in the background, there is instead of Docker compose, there is podman compose. Okay, so I should have everything installed so I can start working on the workshop. So first thing that it tells me is I should download the zip, which I already should have installed download it. So I can just unzip it here, go to Quarkus superheroes. Yes. And I can open it in my favorite IDE. I guess this is also small. There you go into presentation mode. This should hopefully be now big enough. This is just a wrapper around individual services that we will be coding so you can open it, open them all in one IDE window. Basically, when you're coding microservices, of course, you usually don't code them all on one machine. There are different teams writing them on different environments. But this allows us to have only one window open and we can do everything in one place. So, okay. Okay, so I unzip it. Here we have the whole application how it will look like in the end. We will be creating individual services step by step as we will be going. And yeah, all of this will be a Maven projects because Quarkus prefers to use Maven, but not necessarily. It will be Maven Java projects, but with Quarkus you can do also Gradle and also Kotlin or Scala, if that's your thing. And we should check that we have empty ports because we will be running quite a few things. So let me just check this because I actually have something running here. Okay, so 8081 with this. Let me try this one more. Okay, 8080. It's empty, empty, empty. Okay, this keyboard. Okay, I think that's more than enough. Then the one for Postgres should be empty. That's good. Let me use running on 1990. Great. So, I should be ready to start working on this. Okay, so first thing first, we should build what they provided for us. Okay, so that's green, that's okay. Warming up Docker. So, hopefully everybody is familiar with Docker. Basically, it will allow us to start a bunch of containers that we will be using as our infrastructure in the background, mainly database Prometheus and Kafka. And actually in that infrastructure directory, so we will go to infrastructure directory, we have Docker Compulse Linux. So, depending on your system, please use the one that is relevant to you. Since I am on Linux on Fedora, I need to use Docker Compulse Linux YAML. With this app, it will basically take all the containers that are defined in that, I can check it. Basically, if you are not familiar with Docker Compulse, it's just listing individual Docker containers that you can start and stop or manage in a unified manner. So, basically, here we will be starting Postgres, Prometheus, Kafka, et cetera. And you can set some defaults for these containers inside one file. So, if you want to start all of these containers, you need to run it with app command. But if you just run it like this, without the DGD at the end, it will start them running in the foreground inside your Linux terminal, which we don't want to do. With this minus D, it will just detach them to the background. So, if I... Okay. Guys, Martin Lajda, if there will be some questions to what I am talking about, just jump into my speaking please. Docker Compulse is... Basically, yes, there is also Podman Compulse for Podman. So, it's basically the same thing just on a Podman side. Usually, with Docker and Podman, you can use the same commands in the same manner. I think that Podman is fully compatible with Docker. Because, really, I am using Docker as an LES for Podman on my machine because many scripts are still using Docker. But Fedora decided that we will be not using Docker anymore. So, when I run this with minus D, it should start all of that three, four containers in the background. And if I now run Podman PS or Docker PS or the matter, you should see all of that four containers being started and running. And we can actually, I think, leave them running for the whole duration of the workshop. Okay. So, yeah, I think that I am good because now it runs for me. There is also Docker PS, Docker Compulse PS. I need to use the correct YAML, which will get me basically the same information. Just this is useful if you have more containers running because Docker or Podman PS will take everything on your machine. But I killed everything. And if you want to stop it, there is a command down and RM, which I think that it, RM doesn't exist in Podman Compulse anymore because down will directly remove the containers. But yeah, that doesn't matter. But I don't want to really stop them because I think that I can keep them running for the whole duration. We'll see. Because we might have some conflicts going on and we will get to it. Okay. I don't want to download the whole workshop. So, hopefully, I am ready now to start finally developing in the first microservice that we are going to develop is the VLAN service. So, this is pretty straightforward CRUD application with REST API utilizing a Postgres database. Very common use case, I believe, in user applications. So, what we are going to start with is actually create the VLAN Quarkus application. For that, Quarkus comes with a really nice way how to initialize applications, which is Quarkus Maven plugin where you can basically create a Quarkus application with similar mechanism as Maven archetypes, specifying a bunch of properties for your workshops. So, we are specifying group ID, artifact ID, class name that will be generated for us, which will be a VLAN resource. Also, JAXRS or RESTPAD on which this class will be exposed. And we can also specify a list of extensions directly when we are creating the application for which will be included in our application. And we will get into what extension is in a minute. So, let me just really quickly create that application and open it in my IDS. So, I have here RESTVLANs, but if I want to use it, actually, I need to have an idea and tell her that we have now also RESTVLANs and just import omicsML, which is recognized as Maven project. And basically, what I will start with is omicsML that is generated for us. And basically, properties are not that interesting. What is interesting is here, the dependency on Quarkus BOM, which is basically an artifact which lists all the versions of individual, not only dependencies, but extensions that are compatible with a particular Quarkus version. And then in our dependency sections, we don't need to use basically the version tag. So, you shouldn't see version here anywhere because everything is pulled from that Quarkus BOM. So, what Quarkus extension is, Quarkus by itself is really small. I think that CORE itself is only config and CDI implementation arc. And everything else on top of it is based on a concept of extension. So, you will only add into your application what you need to use in your application with the sense that your application then, yeah, I think that 270 was already released. The workshop needs some slight updates, but we will get to it during the weekend, hopefully. So, basically, what we edit on the command line, if you remember, we'll stress easy reactive jackson. So, what this adds for us is basically a main dependency for that extension. We don't need to specify the version because it is pulled. And in this concept, now we can use REST easy, which is an implementation of JaxRS from Red Hat with reactive extension. I don't know what I should... Reactive flavor of REST easy. We will get into reactive in later sections. And, basically, that's it. So, you can list here either manually dependency on individual Quarkus extension, or you can use that minus the extension. There is also an option, even Quarkus List Act. Come on, don't freeze on me. List extensions, I think, which will, yeah, if I can type Quarkus, no. Who is it? Who's list extensions? Yeah, what I need to do is CD to REST, because there I have Quarkus plugin. With Quarkus column list extension, you will get the list of all available extensions that you can use in your application. And I don't even want to scroll it on top, because there is too many of them. So, you can check individual extensions that you might use. What is Quarkus really good for, or where it shines, at least for me, is that Quarkus.io. There is also an option to create your application if you prefer clicking and not using command line with this kind of UI. So, you can specify the individual extension, which was, like, REST easy. They are active here. And I can just stick the checkbox and download a zip, which will be basically the same application as I generated it on the command line. But what I wanted to show you is that, come on, I want to go to Quarkus.io back here in learn tab, you have this guide section, which is basically a set of, I don't know, 15 to 13 minutes, step by step guides for individual extensions. So, if you know that you want to use something like, let's say, reactive messaging, you can just search here for reactive somewhere here, reactive messaging with Apache Kafka. And here in less than 15 minutes, you should be able to get the idea how to use that extension when you are using. So, you will be creating, actually, application, really small application with that extension. And the guide will show you how to use it. So, I think that Quarkus guides is something which is really great for getting starting experience with Quarkus. Okay. So, moving back to the workshop itself. So, I already added it to my POM XML, so that should be good. Yeah, this is not that important how the directory structure will look like in the end. And let's then start. So, here is basically what I was talking about, how POM XML looks like, how we define dependencies and extensions. Quarkus Arc, as I said, is one of the core dependencies, which provides dependency injection based on CDI, Context and Dependency Injection specification. And basically, that's it. Then we can start. So, the first thing that we are going to actually try is to play with that mode, I think. So, what we have right now in our generated application is that single class, real and research that we specify on the command line. If you are not familiar with JuxRS, please write your questions to the chat and Ladea and Martin will answer them. But basically, here we are just saying that on path slash api slash vilans, if you do get, we will produce a text plane with this message. So, what is another great thing about Quarkus is so-called Quarkus Dev mode or Live Reload mode, where you can start Quarkus with this Quarkus column dev. And what it does, it will allow us now to basically have Quarkus automatically being restarted for us on HTTP invocations when we will be changing something. So, I should be now with curl, curl, curl, VLANs, be able to call our service. So, I am calling my application, which is started on localhost 8080 on that path slash api slash vilans, which maps to this. And with get method in curl, if you don't specify anything. So, the string hello as easy to active is returned. I actually prefer to use a different program, which is called HTTP IE. So, I will be using this more. So, VLANs. So, basically, this will do the same call as I did here. Just, it will structure the output more nicely. Martin, can I interrupt you for a while? Yeah, sure. Good. Yeah, the command line is nice, but maybe we could show at least for a few seconds the Quarkus development console we have in Quarkus, because it's more convenient for many users. So, just show the console and basic stuff. Sure thing, but we are jumping ahead, I think, that development console will be there later. But it doesn't matter that much. So, on localhost 8080, we have default index that is served by our application. But if you go to queue slash def slash queue is reserved for Quarkus specific endpoints. So, on slash queue slash def, we have what Martin is calling the def console or def UI. I hope that this is what you meant. Yes, exactly. So, what you have is a really nice overview of individual installed extensions that you have in your application. So, as I said, configuration and arg is usually in there. And you see here that we also have RSC reactive, which will allow you to go inside these individual extensions and to actually do something with them or check what they did. For instance, here we have all beans that's arc processed and CDI bean is basically an object instance that is managed by arc or by Quarkus really easily set. So, yeah, I don't know, Martin, do you want to say something else to this? No, no, no, this is enough, because I remember that actually later on we will be talking and directly looking into deleted beans and etc into arc in this. So, yeah, jumping ahead, but that doesn't matter. Okay, so, okay, so, going back to our demo. So, still my application is running in the demo. So, if I repeat that call, I will still get RSC reactive. But what that library mode gives us is that I can actually change this just in my IDE, save that file, go back into ID and just repeat the same HTTP call. If you check here, Quarkus application will be really fastly recompiled, restarted, and you will get your changes directly reflected. So, you can actually call this and save the file, repeat the calls, and you are getting this back. And where this shines is because usually you are not using curl or HTTP, at least I don't think that many people except for me, because I like terminal, use this. This is a normal HTTP call in basically browser does. So, if I go here to up B lanes, I can do the same thing. So, I will show and just hit F5, refresh the page, and Quarkus will be restarting in the background. In this sense, you are just refreshing your application in the browser, and your application is really fastly recompiled, changes are reflected. So, basically, you can start developing your application and you don't need to stop it until you are finished with it, which is really nice. So, this was development mode or the mode that I just described, and moving up to testing of your application. So, basically, in that generated project, we also had a bunch to test dependencies for June 5 and Rest Assured, which is not mandatory, but Quarkus already comes with the integration for Rest Assured. If this is not your choice, it's still possible to use something else. But, yeah, there is also some management for Surefire plug-in, which is, I don't think, that important. But we already have a generated test. In SensorTest Java, actually, two tests. The first one is basically a test for the generated resource class. It will call that exposed path and assert that we are getting some response, which will now fail. What is important that in Quarkus, you should annotate your test with Quarkus test, which will allow Quarkus, basically, to start Quarkus application in the background before your test is run, also allows you to use dependency injection inside your test. I don't know what else. Can you help me, guys? Also, I think that without it, the Rest Assured integration doesn't work, but I'm not sure. Also, if you don't annotate it with Quarkus test, this won't work. Now I can just call the Rest Assured given, and this will automatically be configured for my test port on which my started Quarkus application will be running, which, by default, is 8081, I think. Okay, so this is basic unit testing, and we also had this native VLAN resource IT test generated, which you just extend our already existing test. You see here that we are just executing the same test, but in native mode, and we have this native, you know, each test annotation, we will get to native mode later. But basically, this will run the same set of tests as we have in VLAN resource test for the generated native executable, when we will generate native executable. So I think that we should now show yes, another great feature of Quarkus, which is called continuous testing. So when you are in Dev mode, and probably some of you already seen this at the bottom, that we have the test post and press R tourism testing, this is what we called continuous testing, which basically allows you to continuously rerun your test when you are reloading Quarkus in Dev mode. So if I press R now in my terminal, just R, you see that tests are starting, we are running our test, and it fails because we are returning hello DevCon 2022-2, and we are expecting that easy to active. So if I go back into my resource, no resource, sorry, test, and fix this here, oops, the test actually correctly asserts what is being now returned from our application. And because I'm doing this only on one monitor, it isn't looking that cool, but when I saved the test, the Quarkus was restarted, and you see here that now all tests are passing, and we see here also that all one test is passing. So this is what that continuous testing is for. So you are continuously rerunning your tests in Dev mode, really nice feature too. Okay, so I showed this, I fixed the test, and now, yeah, of course you can run the test normally as you would do with normal compilation, if you prefer. So if I start Dev mode, I can just run the test, and this will just normally compile my project and run the test. Okay, so this works, going back, packaging and running the application. Basically, this is normal as with any other Maven project. So I can just do Maven, the package, it will again run the test. Now, in our target, we have a bunch of things generated. You see here that we have some jar generated, but this is a normal output of Maven. This is not something that you can run. What you can run is actually placed into Quarkus up directory. So in target Quarkus-app, we have Quarkus-dash-run-jar, which is already a runnable jar, which you can run with Java minus jar. Let's try that. So with Java minus jar, target Quarkus-up-Quarkus-run-dash-jar, I can run my application, I can verify that it's running the same way that it does in Quarkus Dev mode. Maybe one thing that I forgot to mention in the Dev mode, that when you are starting Quarkus, you will get the list of all installed extension printed, which is sometimes useful if you are propagating something that you don't want to propagate or you are missing something that you would like to include. Basically, that's it. So this is how you can really quickly start with your application. One more thing that I will mention, that if you would move this runnable jar somewhere else, you need to also move this lib directory, and I'm not sure if also app nowadays. Can you help me, Martina or Valadja? Because I think that nowadays we are splitting some of the dependencies also to app directory. It's only app. So maybe just lib then. Because in this lib main, you have all of that dependent jars that your applications need to actually use, and that runnable jar is actually rather small. So this is very useful if you are using Docker or something because you can put the dependencies which doesn't change that much into second, last layer and push this somewhere, and then you are only rebuilding that smaller, come on, smaller Quarkus runn jar, 618, and pushing just this. So you have a smaller network. Yeah, Martina is correct, but maybe we should also mention that we also have a bunch of generated bytecode jars. So it's not only this runner jar and lips, but then in the Quarkus directory in the target, if you can take a look there. Yeah, there is this generated bytecode jar and transformed bytecode jar and so on. So if I'm pushing something, I need to push runnable jar, lip folder and this Quarkus folder, right? Yeah, yes. Okay, thank you. Thank you. Okay, so moving on, we run this successfully run this. So we need, we can now move to transactions and are there any questions to what I am doing? Because I see that there is some movement in the chat, but hopefully guys are catching up with everything. Yeah, I think that we figured out to answer all those questions in the chat. Great, thanks. Okay, then I'm moving on to transactions. Really nice topic all the time. Okay, so since we want to make credit application that will be persisting something to database, we actually need the transaction because otherwise we won't be able to persist anything. ORM stands for object relational mapping. And if hopefully everyone is familiar with this, this is basically mapping of your Java classes to entities in your database. This comes from JPA Java Persistence API specification and the implementation that we are using in Quarkus, but basically whole redhead is called Hibernate. And here we have how to install Postgres dependency, Hibernate with Panache and Hibernate validator. Panache is something which is really interesting because if you ever used ORM or Hibernate, I don't want to say Hibernate, let's say JPA. There is a lot of, I don't want to say unnecessary, but there is a lot of boilerplate that you need to write in your Java classes to get fully functioning entity into your database. So the same guys that made Hibernate came with the idea and they created a project Panache which just removes a lot of this boilerplate and your code is way cleaner and we'll get to it in a while. So here we have, here we need to add additional extensions for to our applications that will be actually driver for Postgres, Panache and Hibernate validator. So I will just copy this command and in the same way as I did previously listing that all extensions, wait because I want to show how you can get to it, in the end you have basically this line printed that if you want to add an extension you can use this command Quarkus colon at extension with minus the extensions artifact IDs. So basically this is exactly what we have in the guide and I can just list the individual extensions which I should be able to find somewhere in that long list and just really easily add them with this command and we can see that all of them were installed but you already know that what it actually does is add a dependency into your Pomex and all. So if you prefer to manually edit your, here we have JDBC Postgres, Hibernate validator, Panache. So if you prefer to manually edit your Pomex ML you can do it but there is also this possibility. So going back, yes, so you can actually also manually edit the XML if you prefer that option and basically now we are good to go. Now we can use these extensions and connect to a database. So to define an entity with Panache now this is not traditional JPA entities. What you can do is just really this. So let me just copy these collars. We'll just copy it and then I will explain what it's inside. Here we have time typing the line for something. Okay, so let me just copy paste it into my IDE so it's back and visible. So to create Panache entity all you need to do is annotate it still with entity annotation as similarly as you do in traditional JPA but it needs to extend this Panache entity or Panache entity base if I remember correctly depending on whether or not you have you want to have your ID of your entity generated or you want to somehow influence how it will be generated because now I am getting the ID from the parent class and in Panache entity base I don't have that ID so depending if you want to have ID or not you instant either Panache entity or Panache entity base and then all you need to do is just define public fields that your entity will use and if you are familiar with normal JPA entities this actually needs to be private. Fields needs to be private and you need to provide a public setter and getter which is just because then you have the same thing as you have with public fields. So basically our entity will have these five fields. Basically this is nothing that interesting. You can also use other some JPA annotations. You see that this is coming from Java existence if you would like to but I don't know which all of them are supported which all of them work but again if you would like to see what is possible to do with this extension all you need to do go to Quarkus guides and find Panache and you will see basically the whole configuration reference and basically list of things that you can do with an extension and if you won't find the answer there then we have Zulip chat or GitHub discussions where you can ask these kind of questions. Okay then we have a bunch of bin validation or bin validation annotations which I really don't want to go into inside that this is from another specification from now Jakarta E which you can use to somehow constrain the values that you are putting into database and we also got the toasting but it doesn't matter but you see that basically we could we should be able to reduce these whole class to five lines if we didn't do any form of validations and etc which is way more concise than what you would need to do with traditional JPA. Okay so this is of course opinionated approach I know that some people don't really like this kind of public fields I personally really prefer this kind of I think it's called active record pattern we'll get into it what you can do with this. So actually to use now our entity if you're familiar with JPA you know that you need something we just call entity manager and call some methods on that but with Spanish all you need to do is basically call basically methods directly either on instance of the villain that you will create or some static methods that directly come with your entity class and you don't need to really manage anything else so basically you only need to manage transactions on top of that but we'll get to it you don't need to inject entity manager but I think that you still can you can still use traditional SQL like thingies if you would like to but it's not necessary so this is called active record pattern you are directly calling starting methods on your entity classes so basically this will basically translate to select star from the line in the background somewhere and I will get you know okay I will get a list of the lines back and make another note sorry okay so there is a bunch of these methods that you can use this is not again the point of this workshop to show you everything that you can do with it but if you check the punish guide you will see all of them in really nice matter how you can use it again if I want to persist I will just create the instance and I directly have a method persist on it so I don't need to inject any kind of other infrastructure to go persist so going further down what we need to do now is to add our own business methods to VLAN entity so I will just do that I will just add here find random which we'll use that starting methods from VLAN and basically I will get back only one random VLAN which will which is really interestingly generated because I will find all instances then I will page them for pages of size one and I will just get a random page I'm sure if this is the best way how to do this but yeah as a matter okay so with that I should have now an option to get find a random VLAN if I will need to because I will need to so I'm gonna need some form of configuration and with that we will be getting to how the whole of Quarkus is configured which is really unified manner and in Quarkus all of your main or default configuration lives in a file called application properties in source main resources so I see here that I want to configure to drop and create database on startup so I will go into my source main resources application properties and just paste this here and now I am basically still not ready to start because I still need something that will call the methods on on my VLAN entity and we'll actually start the transaction so this is yet another sorry Jakarta specification called JTA which will basically allow you to manage transactions with the boundary which is the start and end of the method on which you have this at transactional annotation so there are different types of transactions I don't need to waste time of that so we will be now creating our first custom CDI bean VLAN service let me do that VLAN service VLAN service will be CDI bean and again I don't know how much I need to go into what CDI bean is but basically if you annotate something with some scope like here we have application scope there is also request scope dependent single tone etc you are telling Quarkus or in our case Arc CDI implementation that this VLAN service class will be managed by the Quarkus or by your framework your runtime so that means that I will not be manually instantiating VLAN service Arc will do this for me and I will use that instance of VLAN service in my other CDI beans actually when you use applications code this just means that there will be only one instance of this VLAN service created for the whole run of the application request code would create new instance for each HTTP request and we are also saying here a transactional annotation with this required field which basically just says that by default if you have transaction required if you enter a method with a transaction already started your method will be using that transaction and if there is no transaction and your transaction will be started so this is default because it's on a class level and then you can override the transactional on individual methods if you need to do that so transactional required would be used for instance on this persis VLAN or update VLAN but on this free method we override it with supports which she's another type which says that if there is a transaction then I think you join it but if there is no transaction then you just do your method without transaction and this makes sense because for just select operations like list all you don't necessarily need to use transaction but if you're calling it already with the transaction that I think you should okay so we have now this VLAN service and we don't need to do with basically we have operations on that and we can move on to something more interesting so we have applications go yes accessing a database in deathmold so we should start application in deathmold so I think that we have now already started uh postgres database and it doesn't matter because this is our production database that I have started in my docker container maybe I can just just to show what what I mean and you believe me it was infrastructure down so I will just now kill all of that services that we started with docker compose because I want to show something else so I have no containers now running on my machine if I now start application in deathmold and yes you don't need to have queen compile in this but I am using it for some traditional reasons I don't remember actually why I'm using quarkus for since version zero point something so yeah this might be very aracharic so if I start maybe in quarkus then what will now happen is something which we call death services if you are familiar with test containers which is a framework which allows you to start uh docker containers from your uh docker from your job applications so basically quarkus now uses something similar in your deathmold and in uh tests if you have extension like we have extension which is trying to connect to postgres database and quarkus is starting in deathmold and it sees that there is no postgres database started it will actually start one for us so our application can actually connect to some death instance of container postgres which we can use and you should see here somewhere that the services for default data source postgres will start it and if I now check all the containers running on my machine I should see that there was some postgres that started for me and if I now kill my deathmold then hopefully the container is killed again so in this sense I don't really now need to care about my application not working because there is no dependency that I'm using I use this a lot especially with Kafka for instance because again if I will have just extension that is trying to connect to Kafka it will just pin Kafka container for me on the background really nice feature so again if I started in in deathmold oops I again have different postgres started for me and my application actually connected to it we should see here somewhere that we are connecting to it okay so this would be death services another really nice feature of quarkus so yeah I already said that and we are moving on to our villain resource just reading if I can just copy paste this all together hopefully yes so in our villain resource we have just the dummy devcom method or string returning method so this should be already fixed so it will appear in the morning so we will add a just a bunch of another methods which are again basically crud plus random generation which will use our fine random villain and our custom business method on our activity and with that I should be able now to test it let me see because we don't still don't have anything in the database but I should be able to already call it so if I get all villains which is on cement point sorry okay so if I just call now puppy lands I should hopefully get empty json yes because we don't have anything in the database yet so that an anti-injection I already talked about that so if you want to use something which you or somebody else declared as cdib in your application because I told you that you are not instant she think it's yourself you need to inject it with the max inject inject yet another java e specification and we need to say that this is a logger from jbos logging I hope I hope yeah it should be jbos logging so in this sense there is this intricate annotation in a sum already defined cdib in parkus or arc will look for all classes of this type with which are defined as cdib means it will write the find the right instance I know I'm skipping a lot now Martin sorry and it will put that instance into my field so I can use it directly in my application and I don't really need to worry about it being now or misconfigured or something similar because I know that I will get the correct instance in here and in the same way I can inject my vlan service so just to really quickly repeat that inject needs to be used in order the cdis cd and where am I putting this into the vlan service nobody is telling me and if you put it into vlan resource they don't want to inject vlan service in vlan service you are coding and speaking yeah so now I can use this vlan service in my vlan resource and I don't need to specify that scope in uh jacksrs or rest classes because this is automatically detected by parkus that this is a cdib so I can actually put here some scope I don't know what is the default now there is application scope order because do you know Martin Arlaja um sorry what was the question do you know what is the default for jacksrs resources scope yeah by default it's singleton which is basically uh something like application scope except uh except a little bit more performance but singleton singleton also means that you have only one instance per your application but you can also mark uh your resources request scope for example so that a new instance is created for each HTTP request okay so yeah as Martin said if I want to just override this I can just like say here a request scope and now it's a request scope by default it will be singleton okay so now I can actually and I have it already here that's interesting and now already use these services in my application either like this or you can use it in constructor if this is the only constructor that there is then when uh arc will be creating the instance of your resource it will try to find the beans which are declared as parameters for constructor yeah but maybe if you choose to use the constructor injection you should remove the inject uh yeah yeah I prefer field injection okay but yeah sorry I didn't notice that it was already in there so yeah okay so you have it already uh you have it also in the workshop itself so you can see here that either you use an inject on the field which we call field injection or you will use that constructor injection but Martin is actually the author of arc so if he says something about cdi you should listen and then I would rather delete it the constructor injection so we don't mix it okay so moving back to SQL or SQL uh Panache and ORM uh what Quarkus actually allows us to do is to pre-populate the database with some default data when the application is started and you can do this by just creating import SQL file in resources directory where you have normal SQL statements which will add some data into the database and in the guide we have a really big I think 500 or something like this uh pre-populated VLANs which we can just add here into that import SQL file now if I will go back into my terminal and just repeat the same call to get all the VLANs so I will make uh DevMode restart Quarkus hopefully if I typed everything correctly I should get back around 500 pre-populated VLANs which are picked from that import SQL okay again something which I use a lot when I'm uh using Panache okay so moving up to testing uh hopefully everyone is okay with what I'm doing and if there are some questions that you are asking in the chat something that you want to ask me directly okay so then we can continue I hope that I will be able to finish at least VLAN in that two hours okay so what we should do now is actually create a little bit of testing for our SQL integration I think so I will just copy paste this into the VLAN resource yes okay that's quite a lot of tests but again we have this Quarkus test annotation which needs to be placed on test this is something specific to yes j only five which will allow us to somehow order the test and you see here that we are just basically calling that metals that we are exposing now in VLAN resource and we are asserting that some actual VLANs are in return trying to find where they are pre-populating database here and they are not because there are actually then trying to create VLAN I think no they are actually attempting to get like all the VLANs so there is 581 of them then we are creating a VLAN then we are updating that one created VLAN and then we are removing it and asserting that we still have the same number of VLANs again something that we don't need to go into much detail but now in my dev mode because I am already connected to a database running in the background I should be just press R and why only one test maybe I should not I need to restart for this to be picked up because by default quarkus in dev mode only scans your crc main java folder and crc main resources meta resources if I'm not mistaken hopefully I'm right so since my import SQL is not in these paths I think that I need to restart dev mode to get this picked let me just try that and we will finish for wait for quarkus and database to start and yes now I have eight tests so hopefully they will pass yes green so we are good to go okay and then moving on building production package so what we haven't really talked about yet is that quarkus is able to start in different modes of operation depending on how we start quarkus and depending on that we can use different configuration for instance that will influence the execution of our service so when we are actually starting quarkus in dev mode we are using something we just called dev profile but if you start quarkus normally already package application with java minus jar we will be using something we just called the probe mode or probe profile so in that sense what we can do in our configuration is actually this so in my properties I can use this percent or by the name of the profile that we want to use that configuration for so basically here I am saying that this config should take only place when we are running application in prod mode so when it's starting in dev mode this configuration is not used or in test mode for the matter so I can override the same property like here that for dev it would be something else and for and for test it can be also something else you see what I mean we can have the same property several times and different property will be used depending on which in which mode you are running your quarkus application so uh yeah we don't need to use this right here because what we only need to say is that these properties should be only used in prod mode and why is that because here we are really connecting to production database that is running separately for us somewhere else in our example in that the docker compose that we are running somewhere in the background but in a dev mode we want to connect to that dev services that are basically started for us also in test but I forgot to mention is that I don't know if I'm running it in continuous testing if I'm connecting to the same postgres which was started for this services but if I just call it with even test I know that again some postgres would be started for me just for the test but I'm not sure in that mode if it's reused or not do you know I think that it's a separate instance because like if you start the application in the dev mode you have one instance for the dev mode and and another instance is set up for the test because otherwise you make much much sense standing standing too long so I need to see it okay so moving on uh okay so this product will be again as I said only used when we are running our application in uh prod mode so what I need to do now because in previous steps I stopped the container so I will stop the dev mode and hopefully my uh podman is empty I will again start production postgres database from our docker compose okay so now I should have somewhere some production postgres started on 5 4 3 2 which is configured here on localhost 5 4 3 2 and now I should be able to compile my application and I will just compile it without this to save some time and now I should be able to run my parkus up parkus run which will now use that percent prod profile or percent prod properties and should connect to that uh database and I should still have everything prepopulated as I had so we have 581 villains so but now we are connecting to our production database not longer in the demo this is something which is normal production run my parkus application okay and I already did that okay so I may be a little overrun because now we are getting to configuration so I already talked about it if you don't use any person something uh prefix in your configuration so you will just type your configuration normally it will be used in all profiles of course you can also override it in some profiles and then if you are running in a not specified overridden profile then the default will be used so what we are configuring here is just some configuration for our console so if I now start it in dev mode again because of course I don't want to repackage my application every time that I change something that's not something that parkus is for and you can already see that I just darken the parkus log a little bit and change the how the log messages output it nothing too fancy more interesting is configuring the parkus listening port so basically you can say that parkus by default it runs on port 8080 but 8080 is a very much overloaded port so usually you want to push it somewhere else and actually on 8080 we will have our main UI running so our biliant service will be running on port 8084 I'll just into my duration and this is one of a really small number of properties that actually requires you to restart the dev mode because you are running your application now on different port so we need to restart the application and you should see here already somewhere what is it that we are starting on port 8084 so if I now try again port 8080 I should get connection error but if I try 8084 I'm getting the result and with that yes I already showed that injecting configuration so what we used so far is always prefixed with this parkus prefix which means basically that these properties are something which is specific to parkus but configuration in parkus which is based on micro profile config or after implementation which is called smaller config allows you to use this same form of configuration for specific stuff to your application so you can directly use anything that is configured here in your application and to do that you can basically just replace to fill in the service this time and did nicely use this config property annotation which is coming from the micro profile specification in parkus you don't need to now use an inject because in parkus when you are using something which is called qualifier which is this config property you don't need to use an inject again small but really appreciated feature which in which you need to specify the name of the configuration property that you want to use so we are seeing level that multiplier and optionally you can also specify the default value and you are using it as a normal injection so again parkus when it starts it will find the value of this property and will inject it into my field if you specify it like this so this basically I'm saying that I need this configuration for my application if you don't specify it in your application properties or somewhere else so parkus won't find this value your startup should fail and think bill fail because you don't have this configuration but you can also inject optionals here for instance for optional values in that sense you will just get optional empty okay so yeah it's basically written here so if you started without this value and I hope that I won't break it totally so if I repeat that call I will get parkus restart I didn't save it save it why is it working oh yeah because I have default so if I will delete default so now I don't have it configured my application will start because I don't have config value for level multiplier so going back I have default what I can do now with it is actually use it somewhere so in persist vlan vlan service persist vlan we will just multiply the low persist vlan so we will just use that uh injected configuration somewhere and what we can then do is in our application properties specify this property by default overrides the level of all fillings to be just half of their actual level so they're a little bit here so heroes of in more and if we now try to use this so I will now copy paste this because this is more advanced month which I don't want to replicate we should see that we are specifying level five which we are posting to our application but because our in our application properties we specified level multiplier to be 0.5 0.5 our oops created vlan should have only level three because it was multiplied by 0.5 of course if you would like to override this somewhere else in your profile with something else you can again use the profiles actually in this kind of applications and if you check again the configuration guide on quarkus side you can see that application properties is not the only way how to specify this configuration values by default you can also use environment variables or system properties when you're starting our application so basically you can ship some sensible defaults in your application properties but for instance if you are running in cloud like openchief or kubernetes you can specify environment variables for particular boats or running of your container that will override this configuration in a cloud which makes sense okay so with that quarkus should have more than hopefully enable continuous testing so let me try if our tests are passing just to be sure now it's actually I have a link test what I need to do in my application is if I override this property for the test profile so in a test it's still one so because my tests expect one so if I just I don't need to rerun them because I see that all of them are passing now because now in test profile the level multiplier is one again and I saw the question and as Latia is saying that dynamic configuration is generally not encouraged but it is possible to do if you would like to do it with my profile config okay so moving on and we are finishing get full 12 or at half nobody knows full 12 okay so next one on the table is open API I'm almost in the half past that's nice open API again separate specification coming actually from some external body I don't remember from who is this basically yaml specification of your rest API which you can pass to somebody which are going to who is going to invoke your service that will directly describe how to invoke your service and what kind of responsive response is to expect so for that we have again separate extension which is called small right open API smaller is basically a separate project or set of separate projects which are implementing micro profile specifications there is also a micro profile open API specification which we are using Varcus and also in other products so usually when you are checking something particular for like if you are familiar with micro profile there is usually a mapping one-to-one to micro profile specification and small right project so small right open API implements micro profile open API again if I want to add open API extension into my application I will just copy paste at extension command I don't need to stop it but yeah it doesn't matter actually I think that I don't need to stop it otherwise because I can just in different terminal navigate into rest reliance and paste it here I think that this will also retrigger Varcus application yeah it does so I show you don't need to stop it if you're just adding extensions and now I should see here that I have smaller I open API extension in here and with that we will directly get this I will already out of the box get some pre-generated open API document and you can see here that all the points that we are exposing in our view line resource are here with actually available methods that you can call on them HTTP methods sorry and also responses which are allowed and what should they like return so what that small right open API extension allows you to do is to somehow tweak this open API document that is outputted from your application and yeah what we also get from open API is swagger UI which is generated from this open API document so if we now go to the dev console that we already showed we should see here small right open API extension and we see link to the open API but also link to the swagger or UI which hopefully everyone is familiar with swagger is just translation of that open API document to for me already nice UI but I know many people will disagree which you can directly use in here so I can try it out execute and in the background it will just do the same thing that we are doing on command line basically Kuro and we have all of the results here okay so oh not here where am I so I already did so again what you can use with small open API is a set of micro profile open API annotations which you can see here again this is not the point of this workshop to show you there is also open API guide on Quarkus site if you want to dig more deeper into these annotations that's what you can do with this and there is also micro profile open API specification that you can read of course so I will just copy paste this to vln resource and in vln resource I will copy paste this yes and this one from Quarkus rs so you just see here that we are using something to specify different API responses how the operation should be called etc etc for this particular vln resource for this particular juxtas resource but what you can also do with open API is customize the information for the overall application and for that you need to create actually an application on juxtas rs application class which by default is not required in Quarkus because Quarkus is able to generate this for us however if you want to use open API micro profile open API specification mandates that this kind of general information must be placed on application subclass so you need to create it but it's intentionally empty because Quarkus doesn't really need it and here you can specify as you can see title of your application version of your application context servers on which your application can run and what this in turn gives us if we check again the open API document should get a lot of more information in our document so we see here the title version somewhere servers etc for individual more responses for individual endpoints and also somewhere in the end schemas for individual objects that are expected to be passed to our application etc and also in our spec ui if i refresh this we should now get vln api version 1.0 some description servers which we can specify from that also i don't know hello we here see returns all vln for the database that's taken from the operation so we can tweak this in this way if you prefer to really if you want to i think that you can do a lot of more things with open api but i'm not using it that much to be that familiar with what everything it can do and yeah we can create an open api test if i is returned where should i put it this i will just do it so we are following it but you can see here that we are just accepting that we will get the 200 from open api endpoint the tests it's not picked just are not picked so i should have nine now let's try this again yeah so maybe i found the bug because i thought that this was happening before and okay i was able to finish one microservice so any questions to what i did so far this was really small crud application connecting to a database if i wouldn't be explaining it that much you can see that it's basically four classes and i have fully functioning crud application connecting to a database which i think is pretty nice any questions to the v-line i see that martin and ladia is pretty busy in the chat that's good okay so we still have 40 minutes so let's see what we can do going on i don't know if i want to explain that much about quarkus itself because i think that today at five p.m we have a sole quarkus session which hopefully will cover this kind of stuff but i think that this image is really nice so i will just cover this uh why is quarkus so fast and small is basically because it's doing a lot of stuff during build time so when you are compiling your application and then as martin was already showing you that the generated bytecode for instance is pre-built during your application compilation and then it's just around during your application run time while usually when you are starting and i don't want to name any other java runtimes uh but other java runtimes you usually need to do this kind of stuff and processing of classes look up of the cdi beans i don't know what else during runtime when you are starting your application so that's why java usually have a really long startup times while quarkus is because of that able to compete with even go definitely with note and i think that in some cases even with go okay i will just skip this because yeah we don't need to go through this all displaying banner yeah this is really really important to do because every application and i like this in just in this guide should have banner nowadays my application doesn't so what we can do now is to create another class villain application lifecycle let me do that villain application what we are trying to do here with uh villain application lifecycle again it's a cdi bean which will be displaying our own custom header from here is basically what we are trying to show you is how cdi handles firing of events and observing of events so quarkus when it starts up and when it shuts down fires a cdi event startup even or shut down even which your application basically any cdi bean can listen to in this way so you will just use it observes startup event and basically this method will be invoked by quarkus when quarkus is starting save a role really when stopping and in the sense if i now go back into my application and i will just re-trigger sub-end point so quarkus is we started in death mode see here already but but nicely because it's too big that our method printing that acr was invoked and again if i would stop quarkus death mode we would see that uh it shouldn't be any stopping but i don't want to do that do it right now i think it's clear enough what is actually nice to see is going to the dev console as we already mentioned uh before into the arc extension which is implementing that cdi which is basically responsible for triggering our observers and we should be able to see now our observers observer methods in here and we should also somewhere see which events have been fired by quarkus or your custom uh events that are fired and we should see here that startup event was fired at this time and those we know that our own start callback observer should be called okay i think that this is everything that i need to cover here and okay configuration profiles where am i configuration profiles okay i will finish this section and then i will need to take a brief pause because i'm talking for two hours okay i already talked about configuration profiles it's that percent something uh prefix that you can use in uh your configuration by default there are these three at dev running in dev mode tests when running tests and prod running when you are running in when you are not running in development or test mode so basically java minus jar or in native executable run uh you can also get the information about which profile you are running directly from quarkus i don't think that this is necessary to put it there because it would just print that we are running in dev profile but uh yeah we already use it in test multiplier and this is nice that also it is possible for you to create your own quarkus profile when you create your custom profile like if it's called food then you can specify the profile with the quarkus profile property like this and then i can use in my application properties something like percent full level multiplier something something else and i can use this with minus minus dash minus d quarkus profile full okay okay so the last thing in this section is how to build the native executable so what is native executable if you are not familiar with graviem it's basically a way how you can compile your java application into really linux runnable file make runnable file or on windows.exe file which you can directly run and this functionality comes from graviem so basically in in theory any java application should be compilable into the native executable with graviem but it's not that easy to do it because graviem when it creates this native executable needs to do basically static analyses of whole run of your application because it needs to generate runnable bytecode bitcode i think so you often need to help grau to tell grau what actually your application is doing how is it doing you are not able to do some things with grau and this is where quarkus again shines for you because that extensions are not only extension mechanism is not only great for you to specify what exactly your quarkus application depends on and make it smaller but it also allows you to in that extension itself specify how that extension code should be utilized in for instance graviem builds also how it should behave during build time what should it do at runtime etc so extension developer or someone who creates extension can have really can intact the execution of your application for the stuff that is relevant to the application so for instance you can imagine that if you need to put some annotation somewhere for graviem your extension can do it for you so quarkus directly comes and we already have this generated for us in our program example somewhere at the bottom with this native profile which will directly allows us to compile our application into native and you can see that already here we need to specify some properties so which we need for graviem to be successfully compiled i'll basically just the name but log manager i guess is necessary and basically all we need to do to compile application to native is run package minus p native so for this to work you should have your graviem home set and you should also have that native image tool installed which was in the original installation guide however i saw at the beginning if you are following me that i do not have graviem installed actually they just echo graviem home is doesn't exist so this is a computer so i don't have graviem or the native image to install my machine but because i am on linux what i can do is maybe an image minus p native maybe i should again do skip test but i want to show you that the test run in native mode too so it will take a while so here is that interesting stuff so you can see here that quarkus wasn't able to find native image in my system so what it tries it tries to fall back into the container build and because i am on linux what it actually does it will pull image with graviem installed for me copy my code into that image run the build into that image and then just copy that final binary back to my system but because this image is linux based ubi which is universal based image it will only output the linux binary which only of course works on linux if you are running on mac or on windows you need to really download and install graviem and then it will pick your graviem from your system and will output the binary which is specific to your distribution but because i am on linux i don't need to install graviem for hopefully a long time from now if i can i really like to like you know like outsource version handling to somebody else so usually native compilation takes quite some time even for small applications because as i said you need to process whole brand of your application but what you will get back is really small really fast and especially in nowadays serverless architectures it's something that can really compete with definitely note and possibly in some cases getting very close to go or similar languages so when this finishes and it's taking longer than usually because probably i'm sharing screen it's not that long for such a small application i think i can get on my machine to something around one minute for simple crowd application so if i now list what was generated for us so you can see that we had the sredesh rather application which is already runnable so i can just run target rest vline runner and you'll see that our application will start it it's connected to that database production database that we are running and i should be able now another API that's not that interesting this was try with this at the vlines i will get the same functionality and you can see that it will start it just in half a second so okay so this would be native executable if you are not able to build it on your machine that's not a big deal we can help you later or ping us on the Zulip and we can help you figure out how to run native built on your particular system usually on linux this which i showed you should work out of the box hopefully okay and with that if you don't mind i will take a slight pause and i will be back in five minutes martin and ladia can answer any questions that will be in the meantime there's a question about the time of build of a native binary in the event chat not in the session chat but i noticed that and you needed quite a lot honestly like if you if you saw the output when martin was building a native image it includes how much memory it eats and it typically for small application gets to something like five gigabytes or so well most of it is for the JDK so if you have a small application bigger application that will not make too big of a difference because JDK is still much bigger but yeah i would recommend not starting not trying to build a native unless you have at least eight gigabytes of RAM yeah maybe we can also mention that martin's demo the native image started in like half a second which is not usual like in most cases your application will start in few milliseconds but because of too many open tabs in martin's web browser and maybe some other reasons it was way too slow i would say it was slowed down mainly by screen sharing the thing slows down everything and you cannot hear me i'm saying that i usually have 200 tabs open so i know that it's faster it's screen sharing we have 25 minutes left i'm not sure if i want to get really deep into the next part because reactive is not something that i want to go you know like just touch it slightly but maybe i can like talk a little about reactive in the meantime if there are no more questions i think you can like answer normally yeah that that is a complicated topic i i'm afraid i don't have a straightforward answer that would be satisfying to anyone but that's basically how how the grow vm compiler works and i don't think that you can do anything about it i know they are working on that because they they they see that memory concern of the native image compiler is a huge problem for the community but but i think the waiting is the only thing you can do unless you're a compiler expert and want to contribute sizable portion of your time to the grow vm project of course um i mean yeah so sorry to be the point but i don't think you can decrease it in any any way but in any case if you have some ci machine for instance that is more performance that should also be an option so i would be just curious for the ones that are actually doing this on your cell cell phase uh where are you right now in which section not sure if anybody is listening but i would be curious like how much you can do actually in the two two and a half hours of the worship everyone is coding so much yeah maybe you can discuss this a little more like why it's like why like native is attractive but why people still should consider running it running quarkus in jvm mode yeah um right so i think native is attractive because of the of the instant startup time right the certain classes of applications benefit from the great like if you wanted to write a command line application you would these days you would do it in go or rest right for that those are compiled to native and they start instantly right and and if you run a command line application you don't want to spend the second waiting for the jvm to boot and compile all of half of the jdk right so that's that's why that's why native is popular for certain cases at uh at the same time the the traditional jdk with its runtime uh profile guided optimizations have its benefits as well right so if you are writing a traditional uh enterprise application that you would normally write using jacarta ee or spring you can write it in quarkus and run it on a normal normal jvm it will benefit from that either you don't you really care that much about startup time you don't really care if it takes half a half a second or three seconds right but you care about peak performance both throughput and latency but then for that the the adaptive optimizations of regular jdk will trump the native image uh when you give it some time to compile everything right so so native is great for certain use cases for his quarkus has a great story for building command line applications but at the same time running on a regular jvm is beneficial for other use cases right so i mean if if native is confusing for you you can forget about it and you will be fine and you will still benefit from quarkus a lot i think that's that's all i all i want to say maybe also in serverless i'm not sure if people are compiling oh yeah that's a good point yeah um i think i mean i'm i'm no expert on serverless i've never used it but from what i know uh well you you pay by seconds right so so the startup time is crucial in what and though uh quite often serverless architectures spawn new instances until again you don't want to wait a second or two or three until until it starts so so whenever startup time is of great importance you want to use native whenever throughput or peak throughput is is of utmost importance and you can spare a few seconds at the startup you should go for regular jdk yeah maybe also mentioned that cpo is not the only measure you would like to observe because another one is memory consumption because you very often in quality environments memory is expensive and this is where quarkus in both in jvm mode and native mode shines right when i think one other reason what one other use case where native makes sense is horizontal scaling but whenever you get into position where scaling vertically is no longer an option and you need to start scaling horizontally then native becomes interesting as well because of its low memory consumption so if you have like a fixed amount of memory with native you can stick more instances of the application into it right you can you can get like two or three times more maybe maybe even more instances of the same application into the same memory space but if you look at the performance metrics or the the graphs of the quarkus io website you'll see that we're measuring uh what the the metric that we're comparing on is memory density right how many applications you can get into the set into the fixed amount of memory but what which is interesting when you need to start scaling horizontally thank you for reminding me that there are graphs on quarkus side so you can see that basically what we did with that vlan service respools crats is starting typically in 0.0 milliseconds something so really it's just because i am sharing screen and on hop in i guess it takes a little longer on my machine right now yeah so be careful with these numbers and graphs because they'll always depend on what your application does and how many extensions you use and so on so this is really just the basic rest grab example and but it always depends on your application and benchmarks are always tricky and but i still think that you will not get to 0.5 seconds even with more extensions yeah definitely that's a good question and actually we would get this get there really with this reactive section so please continue uh basically reactive applications and especially reactive messaging smaller reactive messaging directly implements publish subscribe pattern reactive steps i can maybe just scroll a little to show you how this works um it's not that important so in uh i'm unmuted in smaller reactive messaging it comes with this incoming and outgoing annotations which basically allows you to plug uh method computations inside to channel processing so basically in here we are taking individual values from fight channel which is our data pipe and do some mapping which we then push to team stats and in the background this is using reactive stream implementations that we also have in smaller i which is called mutiny and if you are interested in this publish subscribe patterns in quarkus tomorrow i think i don't know when but tomorrow somewhere i have a session separately only about how to do reactive with quarkus and micro profile yeah building reactive microservices with micro profile so i will be showing that tomorrow using kafka yes because usually quarkus isn't really pushing you to directly touch the stream you see that in this way you can like really nicely structure processing of the streams because you are just like from saying like from which channel you are consuming values and where you are pushing them or you if you don't use that outgoing then you are just consuming or if you just use outgoing that you are basically a producer producing values no you are not blocking actually when you are using uh reactive maybe i can scroll this up because i think it's described in here somewhere actually quarkus is reactive at core everything quarkus is reactive even blocking stuff is reactive we just block on top of that so i overdone this maybe here i think it's written somewhere in here but i cannot find it uh this fast but basically as you have that extension that we use the rest easy this reactive there is also just rest easy which is a blocking version uh also we have uh panash reactive i don't know what else we have reactive well basically everything in the background is reactive and you as a user can choose whether you want to use reactive programming model or imperative depending on what you should choose actually that a hero and a hero is actually reactive so you see here that instead of hero or villain as we did in uh villain resource we were returning okay response and it doesn't matter we could return villain directly here if we are doing okay villain uh you are basically using imperative model so this method will block when you are the you as a user will call it but if you what is it if you use this uni which is uh coming from that mutiny project which represents yes yes use uni instead represent some reactively asynchronously computed value which will be returned in here uh this should not block and in that sense quarkus is able to process different HTTP requests for instance in the meantime when you invoke this get round of hero so actually yeah i tomorrow i don't think that i will go into this kind of detail but uh quarkus if you use the rest easy reactive extension will depending on the return type of the method from your jackson resource either run it reactively which means on event loop thread or it will switch the switch it to the executor thread where you run blocking code so even if i would use just a hero here without uni i think it would be running run in blocking manner by default but as what i was saying in the chat you can also use ad blocking annotation to manually force it to run on executor thread and you can also use not blocking yeah there is also no blocking yeah but i think that at least in some extensions i know that i run into this with panache somewhere if you now try to run uh some blocking code on event loop thread uh it will automatically throw some extension that you shouldn't block on event loop thread that actually works generally that's a that's a vertex feature that checks if the event loop is blocked and if it's blocked for more than two seconds i think by default then it will it will give you an exception in the law yeah martin's point is a little bit different because you can actually whenever you try to perform some logic you can check whether you're executing on the event loop thread so there is more in quarkus but again this is slightly more advanced topics and you usually shouldn't care that much if you are returning uni or multi from the mutiny which is encouraged uh reactive streams implementation in quarkus you are safe that you will be running on event loop thread okay we are getting to the end so are there any more questions for us in the remaining six seven minutes you can tell you guys uh i'd like to add something uh thank you for this great session uh if you want to and it's all not only for presenters but also for the attendees we have a work adventure platform uh there is session room number six and there you can further discuss your topics around quarkus i will send a link to the chat and it's a easy to use platform i will use your avatar to move on the map and you can interact with different things so please take a look try it and enjoy it so thank you again thank you okay and before we will go i just posted again a link to that Zulip chat where you can catch us even later after the conference if you would like to finish that workshop on yourself and you will have still some questions or in general any questions basically around quarkus