 This session is Reactive Systems with Eglips WorkX and Red Hat OpenShift. This session demonstrates how the combination of WorkX and OpenShift makes a development, deployment and management of microservices burn glass. It's a slideless session, pure live coding. Okay, so, yeah, no slides. That's my third presentation here. You have seen yesterday and this morning lots of slides so it's time to see some code, right? It's time to see what we can really do with Vertex and how does the combination with OpenShift will really change how you are building Reactive Systems. That means distributed systems that will be responsive, elastic, resilient and all based on asynchronous message spacing. So I will start by... So I will be here because I need to code. So I will start by creating a new module. I'm going to use the Vertex Maven plugin to build my Vertex application. It's not mandatory. You can use whatever you want. It's just convenient. So, let's go. I fill this super phone. Yes, shopping back in. Oh, yeah, and I forgot to say I'm going to fix the world, the first world problem we have is how you manage your shopping list. Right. We all have this issue. You think that you are the only one to write on this shopping list, but actually no. You are probably the only one that reads this shopping list when you go to the grocery store. And to build this system, we are going to build a couple of microservices to try to see everything straight together. So here is my Maven product. Nothing very interesting here. I will use the Vertex Maven plugin setup goal that will add it to this bomb, a bit of Vertex flavor. There it is. Well, let's take some risk. It's a live coding session. So let's use the latest development version of Vertex. This will be fine. We have the Vertex bomb. We have a couple of dependencies. We are going to add some dependencies. So what do I need? I will need a Vertex web to build a REST API. I won't use it right away, but that would avoid I will use a Vertex Redis client, because you probably need some data source at some point. Because we are running on the cloud, I want to use Vertex Service Discovery. There it is. What do I have? It's Service Discovery for Kubernetes, because OpenShift is a layer on top of Kubernetes. So I will use this and you will see why. I should not forget SLF4j, SLF4j API and E. That should be fine. Let's see, maybe I will have some. This is the Vertex Maven plugin here. It's already configured. I just want to add one small configuration. So it will be much more fun for me. I will enable the redeployed data source. All right. Okay, now I just... Oops, not here. I need one other property. It's a Vertex Vertical. That will be the entry point of our module of our microservices. Me.demo.shop... My shopping... My shopping... And yes. Okay. And now I go here and I will just create this file. This java file of new... So it's a Vertical. A Vertical is just a Vertex component. And Java, you just do extend abstract vertical. It has a start-stop method, but I just need a start here. And what I will do is that I will create a router. Okay. And oh. Java 8. Yes. Okay. IntelliJ. And this router will let me do things like get on slash handler c.response not a... Hello. Hello. Okay. Once I have a router, I need an HTTP server. Fortunately, Vertex provides an HTTP server. Every time that there is a request, the handler we will pass here will be called and we will dispatch a request. We want the request to be dispatched to the router. So we just do router accept and we will listen on the one on 8080 port. Okay. So let's try this and let's see if it works or not. Vertex run... Oh, sorry. For that compile. If I don't compile, that's not going to work. Compile. Yes. So the Vertex Maven plugin will... In that case, won't even package the application, you will just say, oh, that's your vertical and we'll just start it and see if it works. So if I go there, no. I should have hello. Great. That's not a shopping list. So my shopping list will have a very simple model. It will be a map. The key will be the product and the value will be the integer which is the quantity of this product I need to buy. I don't care about the order, so I will just create an hash map. Okay. And now I need a couple of other routes here. For example, if I do slash shopping, I want to have the shopping list. Shopping list. Okay. Now if I do a post on the same URL, I want something to do this dot add to list. Something like that. And if I delete something, so I will use a pass parameter to detect which product I want to delete. So pass parameter and Vertex Web, just colon and the name of the parameter and I will do this dot... Oh, colon. Delete. Delete from list. So here you see that there is some redeploy going on, but obviously it doesn't compile, so it won't redeploy anything at that point. So let's write this one. So my shopping list, I will just do get the response and with the JSON representation of my list and for this, Vertex provided JSON utility where I just do encode list. That's all. Add to list? Add to list won't be much more complicated, right? Add to list will just do... Well, I need the body. Oh, I need the body. So I need to do something first here. I need to configure the router with a new handler, which is the body handler because by default, Vertex for performance reason is not passing the body. If you want to pass a body, you just need to add this line. And that's all. And once you have this, get body as JSON. That's my body, JSON. The product name will be, well, let's say in the name field of my JSON body, okay? And the quantity will be in the quantity, and if omitted, then I will just say one, okay? And then, well, then I just need to add that to my list. That's the same quantity. Fine. What do I do then? Then, well, that would be nice to display the list, so I will just call, get shopping list, passing the request context, and I'm done. So where is the last one? Delete from list, okay. So delete from list has a pass parameter, which is name. So I will extract it. Pass parameter name, okay? And I will just do list.remove, this name, and then just say, well, get shopping list. That's all. That's all I need. So now it's combining here, and if I go there, I don't have anything in my shopping list. So let's try to add some stuff. Let me go there. So I will use some HTTP stuff. HTTP, yeah, perfect. I need more than one beer. It's my third session. Come on, I need at least 24 beer, right? Rest of not found because, yeah, yeah. I forgot one thing. Shopping. And this is my current shopping list. And if I go back here and do that, yeah, I have my shopping list. Let's add some coffee too. It's my third session. I just drank a coffee, but yeah, let's say just one coffee. See? Fine, it works. And let's say the delete command, does that work? So I will just do a delete, and I will delete the coffee, maybe too much coffee today. Fine, we have just beer, and if I go back here, fine. Okay, so now I would like to have this, but on open shift, right, on your cloud. So in this first module, I will use docker build, just that you understand already how it works. I will, so the first thing to understand is the vertex may even plug in. If I do this, it's going to build a fadjar, containing vertex, all these dependencies that I've declared, build that, and this is a runnable jar that I just have to do java.jar. To deploy it on open shift, I will use a docker file, or actually I will just copy it because there is nothing interesting in the docker file at this point. I will command that. Oops, no. The content will have been much better. I'll just name. So it's a very simple docker file. I'll start from a java image, or providing java. I copy the fadjar that has been built to this directory here. I export the code 8080, and then to launch it, I just do that. This part is kind of tricky because vertex by default is trying to write things in the current working directory, which is not allowed in open shift, and actually we should not do that. So what I just say is like, well, your cache, do it in slash 10. Anyway, it's immutable infrastructure. As soon as we kill you, you're lost, though. I want one docker here. Actually, I don't even have docker on my Mac. What I will do is that I will send this to open shift, and open shift will build this for me. So I have a script for that. So what it is doing is that it's creating a build object on open shift here. So this is my open shift. This is a project where we have stuff but we will explain it. This is this one here. This build, so how does that work? The commands that I've launched take the whole project, send it to open shift, and say, well, start the build, and open shift, look at that. Oh, there is a dockerfire. I know what to do with the dockerfire. We'll build a docker container. Run the docker build for me. So it's running on open shift. Do all the things, so the from, the work, the expose, et cetera, create the docker container, and then my script is also going to create a bunch of objects. The first one you will create is a deployment config, which is kind of a manager that will make sure that we have one instance of our application. The second thing is, well, the instance of my application, here it's a pod. They call that pod. So here we have it. And we also need a service. This service will expose a feature created by my container to the other people, to the other components of my system, and normally inside open shift, and as I wanted to have access from outside, I also created a route that, here we have yellow. And if I go to shopping, well, my shopping is empty. So let's add some stuff here. So it's already running on open shift. Now I will send something about to this URL here. Name equals beer quantity 2. It is, and now up here, I have my beer. So now my shopping is on open shift. It's already on open shift. So what can we do with that? Well, something nice with open shift is that we have this button here that will let us scale up and scale down. Let's go to second instance. It is, we have two instances now. Two instances, that's cool. Only two instances? Let's try to invoke it. Oh, empty, beer, empty. We have the problem with shopping list, a split shopping list. We have two versions of the shopping list, mine and the one from my wife, and they never match. You know this problem, right? So we need to fix that. To fix that we will add some data source that we will share. So I will change my code here to use some Redis, a Redis client. Well, I'm on the cloud, I don't where is my Redis client. I didn't install it, it's running. The only thing I know is that it's named Redis. Okay, so let's take that and let's try to discover where it is. Okay, to do that, Vertexcom with service discovery is built in. I will create a service discovery, it's asynchronous. Here it is, I have a service discovery object. I want a Redis data source. Redis data source dot get with this client, which will deal with that. I pass the discovery parameter, okay. I need some filter. Filter is filtering on records, which is a representation of a service. And what I know, its name is Redis. Okay, Redis, that should be fine. And once I have this, well, let me check if I have a service or not that is matching. Here I say, oh no, no service. So I cannot really start because the service is not there. Or if I have it, then I have my Redis client here. Once I have my Redis client, which is going to be a field, this will be a field, okay. Oops, yes, check. This one. Now I have my Redis client, which is connected to my data source that is called Redis. Well, wherever it is, I don't care. Just discover it. And once I have this, I will start the HTTP server. Okay, now I need to remove my list to read and write inside this Redis client. So don't worry, the Redis is very easy to use. To delete, I will need a constant first. So Redis, if you don't know it, it's a key value distributed store. And the key where I will write my shopping list will be named shopping. So that will be my key. And here I will do Redis.hderl. The key, the name. I don't care about the result. And I will just do this. That's what I have to do. All the interactions, because its vertex are synchronous. Here to add to list, we need to replace this path, right? Um, hash. Key. Or as I said, it's a name. So the API is a bit annoying because quantity has to be a string. It's our API that is like that. So I will do integer.toString quantity. Then I will have some result. I don't care about the result here. And then I just do this. Again, it's going to be asynchronous but completely non-blocking. And here, or here, it's even easier. But give me all that I have. This is going to be an asynchronous result. If I don't have anything that means something really bad happened, so if something really bad happened, I would just do routineContext.fail with the calls. And if I have something, I would just do routineContext.response.and. And my JSON. So my result. And that's all. Now, normally, all my code is nominated to Redis. I wrote, what, 10 lines? Let's redeploy that. I'm executing the same code so that we'll rebuild here locally the projects and everything back. Every object that has already been created because OpenShift implement in the idempotency won't be recreated because they exist already. So it should be fine. Let's have a look at what's going on here. It's probably a build that has been started. Yes. Oops. Shopping completed. So okay. Okay, what it is doing here is that I have two instances and now it's doing a rolling update. It's starting the new instances. And one is ready. Ready. We will define that. Then it's turn off the other one and then start the new one. So it's really doing a rolling update. And now if I have this. Oh, yeah. Not on localhosts, usually. So it's empty because, well, my Redis database is empty. So now I'm going to add stuff again. Here is my beer. Back. So what we have, let me check if everyone got the same one. Yes. Everyone got the same one. I see that you may not believe me here. So let me add something. Here, I will add a header that I will call hicks served by. And I will write the name of the pod that is serving the request. Host name. Okay. I'm also going to do something is that when we do the rolling update, there is some dorm time. Why? Because it doesn't know when the pod is ready. When are we ready to serve request. So we are going to change that too. And before we're deploying, I will just say, remember, I have my slash to just say hello. I will go to my deployment coughing. I will say add health checks. Open shift at two types of health checks. Readiness probe that are used to be sure that we are still alive. So readiness probe. Well, that's very simple. It will try the rolling updates, but won't turn off the first pods until the first one here is ready. So to create that, it's fine. The default configuration is fine. And live next probe. Open shift will ping this politically. And if you don't reply, say, wow, you're dead. And then you will kill your container and restart. So it's a resilience pattern built in. We will try this. So now I have my two health checks, probes, and I will deploy here. Same thing again. So normally no one, I will emit my request. I should have this header that say each serve by pod one, pod two. And we will see that he's implementing a lot balance. What I have, the URL I have is the URL of my service. I don't care how many instances I have behind. He's implementing the rolling update for me. So if you were in my relative landscape talk, it's really the message. When sending a message to this URL, but behind this URL, it's not one guy. It can have one, two, three, four, ten guys. And he will do that for me. I don't know which one is going to serve my request. And that's why I've added this header to show you which one. So go back here. Okay, it's already done. Ooh, that was fast. So normally we should have seen some not ready. We will see that later. And now, if I go back here, I do my shopping. AirCody needs to e. AirCody needs to e. AirCody needs to e. There is a lot bouncer built in. I didn't have done anything, right? So I have my two instances. So if I have much more loads, then I can just create new instances and so on. One thing that is nice, too, is that I can go to my pod here. This one, for example, I have the logs. So the logs that we've seen here is that it's dealing with Kubernetes to retrieve all the services. We can go to the terminal. Yes, we have a terminal. What do we do in a terminal? We do PS. We found, oh, this process looks cool, right? Boom. Let's kill it. Disconnected. But OpenShift monitors that for me, and it already recreated it. So if I go there, you see container restarts. So it found that I've killed the process because I have this LiveNet probe, and it said, while you're dead, I restart you. That's a resilience pattern, too. I didn't do anything, right? I just deploy things, do a script that you will have access to it, so don't worry. And you will see there's colors and stuff like that. It's because I'm getting old. And it restarted. So that's pretty cool. Okay. That's my shopping list, but no, someone told me, that would be cool that in your shopping list you have the product, the quantity, and the total price. And for this, I will need a price service. So fortunately, I've already deployed price or service that I found on the shelf. I didn't implement it. It seems very randomly, but is here. Okay. That's its price or service. And let's try to use it. So I'm going to do something different. Instead of using a docker here, I'm going to use the Fabricate Maven plugin. So I already prepared that because that's a lot of XML. The Fabricate Maven plugin will do everything that I was doing with docker for me. And actually, it's not doing the docker thing. It's using the source-to-image, which is a much better way. So it's sending the filejar to OpenShift and package that inside the image. And all the image that uses S2I source-to-image will look all the same. That's all. Nothing else is different here. Oh, it works. This plugin knows that I'm going to use the Vertex Maven plugin. Detect it. And because of that, it knows that it's going to be on this part. And so on. So they are combined all together. But I need to write my cool service that I will do. So call my pricer and my first service to get this shopping list with more details. But for this, it could be a bit complicated, right? Because I need to call a first service. Then from this, I need to call my pricer. My pricer needs to know the name and then get me the price. So it's such a lot of service to orchestrate. And I must be non-blocking because this Vertex. Oh, does that work? Well, that works with callbacks or with every Java. And look what I did. I added that to my package. Because all the Vertex API, we have the Erics Java binding out of the box. We will see why we have this. I need my start method as usual. I will do a router. But this time, look, I will select this Erics Java router. I will have a single route on slash where I will do this get shopping list. Let's create it. And now I need my pricer service and my shopping backend service. So I will need some services covering. Again, I use the Erics version of it. Create. Oops. And now I need my two services. But I want to do that in parallel. I don't want to have one service and then, oh, let's look at the other one. I will lose time for that. I just want to emit. Give me this and give me this and one you have both called me. We can do that. But to do that, we will use Erics Java. So I will just do. So in that case, it's HTTP endpoint. I will start with Web Client, which is my HTTP client for Vertex. Discovery. I have to write my filter. The first one is my shopping backend. So I know the name again. Obviously I do on the name but you have other possibilities. You can do on whatever, what can, anything. That's all. I don't have to put a callback here because this is returning a single. So this is an observable of one element. We will see why we do that. I will copy this because I need the price of service too. Let's call it a skew. So I have these two singles which are more or less the actions to retrieve it. So now I will just do what I call me when you have both. And when you have both, execute this. Oops. Obviously I'm not at the right. So shopping is going to be so all the results of my single, so the value will be passed in this thing. So x will be my shopping service and y will be my price service. OK. And one of that, I will create my HTTP server as we did because we have retrieved the two services. We are fine. We can actually start. OK. Always on the same port. We can always open on the same port because we don't care. We are running inside container so everyone is listening on these things. And what? Oh yeah. Again, this is returning a single. It won't execute anything if I don't subscribe to it because I need to observe. So I need to subscribe it. I don't care about the results so I will just say I don't. So now let's check if we have something. To deploy here, I will just do fabricate deploy. I'm not in the right project so it doesn't work. Of course. So it's going to do a lot of things extracting the metadata from my project because it knows that it's vertex doing everything, compiling, packaging and so on for me. Send everything to OpenShift Image and done. Okay. That should be fine. Yes. So if we go back here write it. Ooh, it's there. And that should be fine. So this is the service that I've exposed and we create a root because everything you do by script you can also do them using simply this. And does this work? I shouldn't have a sketch ready. Let's have a look at what it is doing. Okay. Let's wait a minute and see what it is doing. I'm running a bit out of time so I won't write this method. I will just comment it. So what we are doing oops. In this method is that we are cooling or shipping backend so it's what I'm doing here with the web client I'm using. I retrieve the result so this again I use the array Java for that so I do a health send, I get a single of a QTP response of a buffer then when I have the result this method is called here I retrieve the body of the JSON object and what I do here is that for each M3 of my shopping list I'm cooling the price of service and this will be very simple because of array Java but nothing is very complicated I just do observable from my body then for each M3 retrieve the price which is a method that I've implemented that just do the computation of the price and return of a single as it's a single I just have to do observable and when I'm done then I subscribe to it for each line, for each service I just write the line and because it's a bounded stream I will have this last event call which is, well, you're done so why I'm able to do that because I'm using a chunk HTTP response which means that the response will be sent chunk by chunk and when I'm done I'm done so I just want to be sure that this is running here so let's try with this try to see with this if it's working not, oh it's not compiling ah yeah, so if it's not compiling it doesn't work, copy paste issue okay it should be fine hopefully, so we're doing the same thing one thing that we could have done I won't have time is the price here may be a bit too slow and I want to protect me to being slow and for this I could have used a circuit breaker, that's proposed a circuit breaker for that I won't have time to show you but the only thing that we could have done is rub this inside a circuit breaker using the circuit breaker and reach the PI so I hope that this time no, still not, you don't want to say anything ooh, that's not okay, so that if I move this here that will be much better let's try this is not too slow even if I'm deploying on a cloud it's quite fast, right, so it's not something where you will have to wait 5 minutes to get the result so here, yes, I'm running OpenShift on my machine in mini shift but even if you use OpenShift online it's not that slow so it will probably take 1 minute to update and to run and to build because vertex artifacts are very very small when vertex is small the API we use are small so it's going to be relatively fast let's wait running so this is Kubernetes okay, want to show anything yes, that might be okay oh, and the price is set 0 interesting, let's add another item here that would be very cool if BNR would be free and the price is just doing some random things I need coffee so I'm adding coffee and now, yes the coffee is more expensive than beer I love this country this is great, wow so what is cool here is that look at the number of services I have I have my backend service that was the rest API I don't care, I have 2 instances from the other side, I just discover the service, I don't care who I'm calling I'm just sending requests as messaging and one I have my shopping list I'm calling another service but it's kind of complicated because you have to emit one request so if you try to do that with HTTP clients I don't know the thread, here I don't and to avoid the callback error I just use every Java I have one thing to have it will be very very fast, don't worry that's much better than that we're deploying like that we're deploying this one so then with the war vertex ecosystem you can build much more resilience but you have elasticity built in and oh, it works it's because the combination of the resilience and the deployment facilities from OpenShift with the power to build reactive systems from vertex and it's a usability to use every Java, it's a facility to use every Java to write nice code even if it's completely asynchronous while you start having kind of a cool system let's hope that it works here starting again so we didn't see much in this because while it's one hour all the source code is going to be online on a GitHub repository so I will tweet it probably tonight or tomorrow morning so if you're interested you can just run, you will have all the instructions and you follow it and once it is deployed now I should be able to do thank you, thank you for your attention and obviously as you can see I'm a web developer, right so if you want to contact me if you have questions that's my main address Twitter under and follow the vertex project I have much more things to show to you Claude, not Claude and so on so feel free to try let me know if you have questions do I have time for questions? 10 minutes for questions, yes here Eclipse, vertex is an Eclipse project Eclipse is a software foundation hosting a set of projects we are not part of the Eclipse IDE I'm actually not using the Eclipse IDE I'm a really good Eclipse citizen but well we are an Eclipse project and we are part of the runtime project at Eclipse that's why another question, if you want to let's take OS, right? OS 2 so if you do that, vertex web has everything under OS 2 so we provide you a configuration for most of the OS 2 provider so Facebook, Google, Key Clock and so on and so on if you want to do some other stuff what I did here in my route here I can add a previous handler that will be called so because it's a chain of handler that will say I want to be sure that it's secured and then you can write your own hot provider doing whatever you want don't implement your own security mechanism because well security is complicated, use something that works you can redirect if it's not authenticated it's a login page and if it's authenticated then you can show my shopping list but you know my shopping list is not really well there is not much privacy in my shopping list another question thank you very much and let me know if you have another question I will be around, I'm around tomorrow too so thank you second the schedule for writing talks has been published so check it to know what's going on today at 6am and tonight we have a social event in a flyer club so if any one of you would like to get a ticket I think that some free tickets are still available in main entrance so you can check it out thanks sorry yesterday when you asked me about the sticker I didn't know much about but very nice thank you we have stickers here so if you want to take all the stickers we don't want to have more stickers I got plenty more take all the stickers it's a big sticker it's button per person so only 700 person could be the person there so only with the button it's button it's also a house button it's very very small very very big low res projector yeah I was about to tune it it's not perfect but at least I was seeing stuff on my screen not everything yesterday it was no it's here but I'm not sure because it's a mess but you can see it it was a total mess from the beginning I think it was it was a mess and how was it? I'm not sure but it was a nice beer but it was a nice beer here you have the same sticker that's great good I recommend 1450 as an optimum so it would be 4x3 and on the right no, on the LGD I don't know what's the maximum no no 1400 on the left now it's on the left I think it's on the right I think it's on the left it's on the right it's on the left it's on the right it's not sitting that's your credit card it's on the right it's on the left it was a little bit on the left