 holes or whatever, but then you have this one really old system that has no API whatsoever and for that you can use a bot that basically logs into that, clicks on all the buttons and then returns back to the main process and continues without needing it. So it's used for essentially legacy communication. So rather than come with it, we can basically we have a bunch of tools that allow you to make it much easier to connect to existing RPA tools. So for instance, if you wanted to say this box here which is a robot on it, this will do an RPA thing. We have a tool like an RPA bridge which allows you to really easily connect to the bot that actually does the work. Yeah, I can. No problem. I would suggest... So Selenium, yeah, exactly. Like there's a really great one base in Selenium which is a robot framework. It's completely open source and it's Python based. It's really, really good. I really like it. The downside is that it's... So UiPath is the biggest one. That has a visual component where it has its own IDE and that sort of thing which is kind of irritating. So this is like you're just coding pure Python. You can manage that code any way you like and it's much smaller footprint like UiPath needs to run on Windows, this and that sort of thing. So robot framework I would suggest. Yeah. I have a question so far. Sure. Yeah. So the bot itself is, and this is the case of almost all bots, is a single threaded, one-off run through a front-end application and almost all of the RPA tools have that in mind which is we need to run this one single execution of running through this application and then return the results. Now how that relates to BPMN is that that is a very... It's a single component of your end-to-end process. Most people actually aren't... When, for instance, they want to move away from legacy systems like that but they're still very deeply embedded in the core of their business processes. They can actually abstract them into these little boxes which makes them easier to remove in the future because these boxes don't know anything that happened before or after it. So an old system that would have like a legacy component, you would basically take out any idea that that component needs to talk to another system. Rather, it only talks to the process engine and only the process engine talks to it which essentially separates this from the rest of your architecture and the rest of the services. So once you have these services that are basically independent from each other, you can then sort of close them down, swap them out. You can change versions of just independent parts because nothing needs to know about the next thing just the engine does. And we'll demonstrate this today when we build some stuff. Yeah, don't worry. That'll have to think it's a very visual... We're building models, executing them and stepping through them so you'll see all of this happen. Yeah, sure. Yeah, yeah. It depends on the RP tool. Like an RP tool like, for instance, UiPath, which is the reason we get up because it's the biggest one out there. That needs its own Windows thing and we do have a customer in Germany that has literally thousands of computers just running bots. And then they're all orchestrated because they don't want to remove the legacy system. They just want these bots. But they have to have a single like install like virtual machine for every single bot. You can't even have two bots running on one machine. So it's actually... Yeah, exactly. Because it needs to completely happen visually. But it needs to open up a web browser and it needs to type it. Like, that's what has to actually happen. There's no cheat around that. So for that it needs, first of all, that nothing else is happening on that machine because that would interrupt the thing. Because it's actually... The RP bots are really fragile. If anything changes at all on how the front end looks, it'll break immediately. So it's a complicated thing. Which is a little bit with RPA. So when I initially started off by saying RPA is a nightmare thing that I really hate, it's because I've tried to use it on a bunch of things. And you can get it started real quick and you actually make it do really fun things. And then very quickly it becomes really hard to maintain, which is where the real problem comes. Less true of robot framework though, I think. So if you're... Yeah. Exactly right. It needs an anchor first. So it needs to like, okay, where am I on the page? And then it calculates everything else from that anchor. So if that anchor... If anything changes from that anchor, then everything breaks. And because a single threaded, once it breaks, that's it. Like it's not going to... You don't have a saved state. You could be halfway through in putting stuff and it just can't find a button and it's broken. So it's kind of irritating to fix as well. Yeah. They're basically the same. I think the workflow engines in the past were very user focused, the term workflow engine. They tended to mean document processing, for instance, and they tended to be trying to get user information passed to different systems. Most process orchestration now tends to be a mix of both orchestrating services and orchestrating users. And then a lot of new cases, especially, especially with microservice architectures, it's mostly orchestrating systems and minor services. They're the same conceptually, though. It's just about the sort of who's in the process, essentially. Come on, you can do either or. You have the human workflow as a big part of what we do as well. Alrighty, I did not think I'd get so much out of that slide, but thanks very much. I greatly appreciate it. Okay, so now an agenda. Why not discuss a little more on this side? So the first thing I'm going to do is we're going to discuss the goals of the workshop we've achieved. We're then going to create a cluster, I'll explain what that means later, but basically we're doing everything on our SAS version. I'll explain later that there's two versions you can use. It's an open source tool, so you can have a self-managed version that you can run yourself, but it's way faster just to use the SAS version for this, because it's free, and it basically is the same. So we'll create an account with Commander Web Apps. I'll run through explaining them. We'll then quickly build a process, which is in BPMN. I'll explain how BPMN works. Then we'll add some execution semantics to the model, which means we'll give it the semantics it needs to know how to actually run it. And then we'll actually configure some ways of connecting to external services, and then talk a little bit about orchestrating workers in general. Okay, and all of that is located in these links. So essentially this GitHub repo, which is part of the slides, is where everything you're gonna need today almost is, in terms of the exercises. There's also a bunch of additional exercises that we probably won't cover today, but if you're interested and you wanna do more homework, or you're very, very fast getting through this, there's more exercises to keep you busy around error handling and things like that, also in the repo, we probably won't cover those today. This is where to sign up as well, so these two links are kind of important. Alrighty. All good so far? Fantastic. Okay. So this is basically our goal. This is what I expect after a couple of hours. You, lovely people, will basically understand how to build an executed BPMN model in common days. A BPMN model is the executable description of how your process is executed. So this describes when everything and why everything is executed. So yeah, that is what you will learn. I'm sure you're all very excited about that. We only have, of course, one or two people who know what BPMN is. So let me build some BPMNs for you and explain how it works as a first iteration. And again, if any question is at all, I love interaction and so please ask me things and tell me things and shout nice things if you want. That's also fine. So in a moment we'll be signing up into this thing here. This is the cloud console. This contains two kind of important things which is the clusters and the modeler. I'll talk about the clusters later. That's where the engine is, the front end applications, that sort of thing. We'll get to that in more detail. But first I wanna focus on the modeler. The modeler is an independent application that's used to build BPMN processes. We have here a bunch of little folders. I'm gonna create a new one here called scale. And I'm gonna create a new BPMN model. Are there some templates here? If you wanted to build something kind of complicated or see some patterns, but we're gonna go just from the beginning. Can everyone see that okay? Or is that too small? Yeah. Okay, so here we have our little BPMN model. So this is a start event to the beginning of the process. And in most cases a process follows some kind of task. And tasks can have a bunch of different task types. And mostly they're either going to be user tasks which are things that represent a front end. So that is a user that needs to enter some data. Okay, so in most cases that means that this is now we're getting some front end information that we're showing a user something and they're gonna give it to me back. Then usually we would want to let's say, run some kind of code to do that we have a service task. And then an end event when the process ends. So this would be from user and this is a process data. Alrighty, so now this is our mentioned open standard. This thing and behind the scenes it's generated an executable XML. And in this case what would happen would be if we turn on token simulation we would start the process instance. It would arrive here. Then a user would basically have in front of them they're paying to say, hey you've got work to do from some sort of front end application. Here is your task to complete. So they see that in front of them they claim it, they complete it. And once they complete it, it then goes and it arrives here where it runs some sort of external service or something or makes a REST call or does something technical that doesn't require a human in the process ends. Okay, the most basic possibility to model. This is of course nothing like most cases because why would you need a whole notation for something so uninteresting as this because usually be commanded use when you have a lot of decisions to make. So for instance, depending on the data we get back maybe we don't want to process it. So we have here an exclusive gateway or XOR gateway, depends how you want to describe it. And this basically says we will go one of two ways through the process depending on data. The full name for the symbol is the Database Exclusive Gateway Splitting. Which is why I prefer to call it something a little more simple. And it basically says, let me get to this point we will use some sort of data in the context of the process and decide whether to go this way or this way. And this is the primary function of the engine, right? It doesn't actually do this work, that's a front end. It doesn't do this work, that's some service. What the engine does is it decides what to do next or under what circumstances things should happen. And it can get really complicated but this is the easiest way to do it. So in this case, let's see, is the data nice? The data, nice, for instance. And then if it is, go this way, if not this way. And then we'll just, I don't know what usually happens if data's not nice, be angry. There we go, okay, cool. Now, another little thing about BP-MEN is quite interesting which is BP-MEN is not required to be executable. BP-MEN has this weird thing which was originally designed for analysts. The first version, BP-MEN 1.0, was designed essentially to allow people to design their end-to-end processes and they would give those processes those models to a developer who would then try to build what that's designed to do. BP-MEN 2.0, which has been an ISO standard since 2011, created the executable meta-model behind it which means if a designer gave me this, I don't need to change it in any way. I just need to add semantics to it because it's already executable. And you'll see that in a few moments. So, that's sort of the core of BP-MEN. Why we use BP-MEN in particular because we have this nice ability to say an analyst or a slightly less technical person could actually still build this process and you could actually end up with a pretty well functioning orchestration model without really needing to do too much changes from the original design, which is kind of key. All right, so these are the main symbols we're going to be using today, these are basically these, but I want to just show a little more of BP-MEN. So, the next bit is just sort of a FYI, the kind of weird stuff that can happen in BP-MEN that might be kind of show the value of it. The first thing is there's a bunch of different gateways. So, for instance, we could have an issue where we start this process and we want to run two parallel tracks so we have here getUserData and we also have readActuallyDoWordl. That's the thing people do, right? That's the zeitgeist of the moment. So, we have these things, so this now will say, if we run token simulation again, we'll see that if we start this process, we basically create two instances that run in parallel that are doing two completely different things for the same process, for the same data and the same context, and then someone finishes this one and they end up saying, no, the data's bad, and meanwhile, this one here also runs independently. So, it's quite nice, but then you can also do things like, okay, well, we also have a task at the end here. Let's say, do this, and we can then start merging back into the main flow so I can say, making coffee is something we do when our day is over, and if we've done either of those two, it will basically merge back into this gateway, so you can see that now. So, that goes up here into this thing, we then go straight to process the data, we then move back here, great, it's a little bit slow, but then we can say, well, we only want to have coffee because doing Wordl is sort of a, if we fix this, then we want to reward ourselves with coffee, because that's how my mind works. I can't do anything else that's a little bit of a reward mechanism on this. So, in this case, we see, we do our data, we do our Wordl first, and this is another key component of the workflow engine, holding state, really, really important, being able to say, we are waiting here in this sort of predefined state while this other stuff happens. This is incredibly hard to code in general of just waiting between parallel tracks, but it's really, really simple to do that with BPMM, and it's totally visual. And then you can see that, depending on when this guy gets along, once this chap arrives, it'll merge with the gateway and it'll continue as one. So, it's quite a nice little thing. And BPMM gets even more complicated because there are things that might happen that are, let's say, global, right? Like, let's imagine that you're in work doing your thing, but you're not feeling well, so you wanna go home. This can happen at any time during this process. At any moment, you can just feel like, I'm not really up to this. And so, how would you model that when, and this is key to the context of BPMM, in a distributed system where everything is completely independent, you want a global listener that says, no matter what happens while we're running through these, I want to be listening for an event that could happen at any time. And this, again, in BPMM, is really, really easy. We can just kind of drop a thing called an event-based sub-process, and I can wait for a message that might come in, and this could be not feeling well, and then get soup, and then here. So, what does this mean for our token simulation? It means that when we're doing this process, and we're stepping through all these things, at any point, a message could come in and just say, you know what, I'm not feeling great. And it'll just interrupt everything that's happened, and then can do the process in a different scope. Again, this is something that's quite hard to do in code, but if we have a centralized orchestrator where everything is basically independent from what happens before or after it, you have this power to be able to do this. Okay, any questions or comments about that? Yes, yeah, they will. In this case, they will, they don't have to. If you want, you can also use a non-interrupting one. So this is actually kind of fun, because let's imagine that we're running through process, but now, it's possible that an external service changes some of the data we're working with. And then we can just say, okay, well, we've got a message, let's do this. I mean, it doesn't come in as many times as you want. So this is basically always waiting for a global message that may come in, but it actually won't affect the current state of your process if you don't want it to. But yeah, so you have a choice. Yes, very, very strict. Yeah, so I'll give you an example. So if you look at this start event here, if I try to, this button here converts it to other types of start events, right? And the interesting thing is these are only valid within this context. If I look at this start event as well, I can only get a few different types. So it's actually quite strictly, and you also can't do things like, this is a start event, you can't actually connect anything to it. So you can see that it always will point it up to the direction. So you know, it's quite strictly adhered to. There's also a linting tool that lets you check to make sure that everything is done from a best practice perspective rather than just violating the standard. Alrighty, all good so far? That was a lot of stuff, but as I mentioned, we will mainly be talking about just some basic events today, which as I mentioned, are gonna be the do-to-do, just these folks. The start event, user task, XOR gateway, service task, let's not get soup. And yeah, that's kind of the thing we're gonna be dealing with, just to simplify things. If you are interested, I'm very happy to also maybe help you build some more complicated stuff. Okay, all good so far? Marvelous, so let's return to my slides. Okay, so now I want, I mentioned there was two sort of sections we're gonna talk about. The first one was the modeler, which is this independent thing where you can build different processes. This is the platform itself, so this is where the execution happens. Okay, so let's talk through it a little bit, because this is what we're working with. When I say the first exercise to create a cluster within Communda, what does that mean? It means we're creating the engine that's used to actually step through the process. It's called ZB, it's the name of the engine. It's open source, and it's, the little box is complicated, so I'm gonna slide to describe that, but just, that's the thing. Inside of it, it exports the data. Everything that happens in here, it has an exporter, but just sends all that data out to another source. In our case, we're using Elasticsearch for that. So Elasticsearch is where all the data that is generated by stepping through this process just ends up. And for that, to look into what's happening in our process engine, to see where we are, and that sort of thing, we have, let's see, start with Tasklist, which is a front-end application which we use to claim and complete tasks for users. So that's where those user tasks that we create, that's where they can be found and completed. So we'll be using that. We have Operate, which is actually the admin tool where you can have an overview of your process, see where all the tokens are, that sort of thing. And then Optimize is used for reporting. So you can generate reports based on what's happening in your process and find out common paths to your process and all that sort of fun stuff. All right, and then we have a job worker which is essentially the core component of the whole point of this. This is all in one place. This is where your business logic is. And I'll discuss that a little more. You may not have time to build one, but I'll explain how they work and what you can build with those little job workers. Okay, so that is Command 8, that's our platform thing. On the web model we just saw there. We also have a desktop modeler in case you're wondering if you wanna use that instead. Yeah, yeah, yeah, yeah, absolutely. Optimize is pretty good for that because it has all the data that happened and it's read-only so they can't go and change anything. You can also create shareable reports and Optimize that are constantly being updated by live data. So if you create a report and Optimize and you give a link to somebody and it's like the last 30 days here are the number of, I don't know, instances we ran on this process, that will always be true for whoever's looking at it, for instance. Oh, I see, yeah, that's absolutely the case, yeah. What you would do is you would simply create a cluster that you're testing on and then give Optimize to whoever it is that has the information that they know how to do the audit and they can run through it. I'll be demoing Optimize shortly so you'll see its capabilities. Okay, I need a question. We're getting very dangerously close to doing something soon, everybody, so hold on to your hats. The final thing I wanna talk about is this little box. I can't discuss it in more detail, but it's the engine and I wanna just quickly explain how it works. So basically inside the engine there's at least three brokers clustered. Okay, and these are the brokers that actually step through the process. The reason they exist is because ZB can handle a lot of high throughput scenarios. It can start about a million instances a second depending on how you can scale it up and it does that by basically you will start a ZB cluster and tell it how many engines, minimum of three and what replication factor because what happens if you start a process is if a request comes in to start a process it goes to this gateway that subsequently points out a broker and then a process basically lives here. But it's also a copy of that is then replicated to other nodes. So this is the only one that can actually move the process along for a single process, but if it goes down another node can then take over as leader. It uses like RAF protocol and uses rock ZB as a way of synchronizing the data. This is just a very quick way of describing that it's very, very scalable. This kind of happens without you needing to do anything. So it's, this is just happening in the background when you start up ZB. So in case you have any questions about throughput and that sort of thing that's the basic concept. Not massively important right now but it's kind of a cool thing. Okay. We are about to do something. Amazing. We're going to do exercise one which is the easiest exercise, theoretically. And if you go to that lovely GitHub repo that I pointed out initially just for those who have arrived since if you scan this QR code, this has a link to the slide deck and on the slide deck we have on this slide number four is the link to the GitHub repo. So you'll need that for the rest of the workshop. Wouldn't that be easier? Yeah. Let's see if I can do that. Do, do, do. There we go. Can everyone see that? Oh. For you, you can just drop off the last zero. It'll just work for you. Don't worry about it. So yeah, you can type in a short URL that AT for such PR TVO. Let's see if it actually works. I should have done that beforehand. Yeah, it looks like it works. So once everyone's caught up we can then continue. There you have people arriving. Good stuff. Who would have thought QR codes would go out of fashion so quickly? So once we are linked in there we should, this is the important page where we talk about the things we're gonna be doing. And the very first exercise is really simple. It's just to actually create an account and come under age and create a cluster. It's kind of detailed here with screenshots and everything. The goal is essentially, if we take a look at the console here in clusters, you basically just want to see this thing starting up. They don't actually all have to be healthy yet. It takes like a few minutes, but just have them being built. And it shouldn't take too long, I hope. If there's any problems at all, shout out Amara. That's why she's here. She takes abuse better than I do. I'm very thin skinned. So where are we? So again, that's detailed here. Exercise one, right here. Yeah, exactly. If you guys can go ahead and just follow this link to sign up and then head along and then build. It should create a cluster basically involves exactly one button, which is why hopefully it's quite easy. Because when you go in here, you'll see you won't see any clusters at all. And you'll see create new and you just click on that and the rest just happens. And yeah, and as I said, it just needs to be started up. It should be, because it should go on. This is interesting, isn't it? Why is that happening these days? He's trying to deny and see it's like he's just have a random. Oh yeah, you know what? Let's go. Okay, just type in commounded.com. Never met a really devoric in the wild. I'm excited. It's cool for try free there. Okay, and then create an account. Every other people, isn't it? Anyone else having problems finding the login page? You've drifted into a web browser. I think our website doesn't look far enough. Send them out of your direction, she'll switch out. Are you really blocking JavaScript or something on the page? Seems to be okay, I'm using Firefox as well. How's everybody else doing? Anyone having any problems at all, setting up? No good? Okay, type in the back, okay. Yeah, it'll be in the jerk, isn't it? I do not. There's some other way we can do this. He could sign up from your computer. If it loads on you. Maybe you can access it and you've already signed up some of it, maybe. Yeah, so you need to have signed up first. Certainly. For those who still don't have the slides, this is a lovely short URL which I was inspired to create. Okay, so for those who have completed this little bit, it should be still building. We can actually already skip ahead to the next part, which is gonna be actually building a process. I've got a very simple little example here. We have a delivery service where we have a customer, a restaurant and a driver. And basically we can order some food. So the process of ordering food from the perspective of the delivery service, that's basically it. So imagine what the process might be. You only need to use about three user tasks and at least one extra gateway for this. And I'll just quickly step through some of the UX stuff for the modeler and how to get to us and that sort of thing. So this little paragraph here is what you're gonna model. So let's head here. So we shall model it together since everyone's very nice. So once we're here, the modeler is right up there and it opens up like so as you saw earlier. And after you create a project, you can go in here and this is the diagram I created earlier. Okay, so now let's build, let's talk through our process. So once again when you create stars, there's a bunch of these lovely templates but we're gonna create one from scratch. And then what we should have is just this blank canvas which is a start event. So this is a delivery service. Okay, the start event is gonna start with food is ordered. Okay, what happens next? Any ideas? What would you expect to happen after you go on an app and order some food? If only, I was in fact. I think preparing the food is definitely something that happens. Prepare, so there we go. Yeah, there could be that, yeah. After preparing food, what happens then? So we have a cue mechanism I guess. We could say send to chef potentially. We prepare food then what? That is a marvelous start, yeah. Deliver food and then food has arrived. Now, because of the instructions that we were given, we need at least one extra gateway in here. And an extra gateway usually determines like a point in which something, let's say this is what we would call a happy path. Every time you design a beaten model, you should generally start and just build from your start event to your end event and just say let's just go through the path you would like to go through. And then you start thinking about potential for problems and offshoots, right? So what kind of problems might exist here that we could, that may send us off the happy path? Yeah, that's a great one, yeah. So let's say we send it to the chef and the chef says, you know what, the order, we can't do it because we're out of, I don't know, burgers. What's a common Los Angeles food? Burgers sounds good, right? Sounds great, awesome. So we're out of burgers or whatever, so food not in stock. And then we go here. So what happens after we've sent our order, sent to the chef, the food is not gonna be made, what do you do then? If anything, maybe, huh? Sure, you could, yeah. Let's say two words that aren't real, but there we go. I'm too lazy, yep. Zoom in. Whoa, too much. Okay, there you go. So then we have a bunch of things we have food ordered. Send to chef, the chef might decide on whether they have it in stock or not. If they do, great, we prepare our food and we deliver it. If they don't, we just have to notify the customer that they're going to starve today, which is very sad times for everybody. So now we actually have to choose some task types. For this case, I'm just going to use user tasks for now and everything. So all of these are going to be user focused. I mean, we'll make it more automated to go along. So this would be some stuff. Yes and no. Alrighty. And so for right now, I would very much like you love to be able to build something similar in the modeler. And then you can use token simulation. So happy path is food is to the chef. We prepare the food, food is delivered. The sad circumstances is send to chef, notify the customer. Customer is sad. So I'll give you guys a few minutes to build that. Any questions at all, just let me know to get stuck in any part of that. How's it going with you? Ah, we're alive. You double click on it or you can hit the eat button as well. You're going from up to down. You're modeling things that the modelers like to so bad at like modeling from like up to down because we sort of have this thing where we can design it to sort of pop across which is why when I click on the thing it always pops in front of us. But we see loads of people modeling from to down or whatever because of using other things like people and stuff like that also does the same thing. It's nice. Do you want to check out the gate? Yeah it is. It's an XML file on the end of the day actually. So all of this is totally just a and the XML is also standard. So it's also abide by the standard. So you can actually move from tool to tool. So you can actually model in some other tool if you want. And then you can put it in here. So if you want to actually download this, actually if you click on download right there then you get the XML. Well I think it's the one beside it. How are you following so far Joe? We're going to change the type. What type? Or yeah it's that thing there we change the task type that I'm looking for or an annotation to the task. I want to put the word in. Oh double click or clicky yeah. Yeah, no problem. All right they're not visible though. Let me see one second. Well actually, no they don't because they're only built on the desktop model I think. So the usually what you can do is you can build them from here. And then so usually you don't really need to use this so much. So if you want any of the types you can use these types from here and then drag them to the place you want. For instance like that. So I don't think we have any shortcuts for individual symbols like that. We do have some shortcuts for things like the yeah there's some shortcuts. What is that? Is that actually that actually work? Oh, okay. So that actually might work. So you have, oh it's capturing into working. So you can click L and then you can then search for the task types instead. Okay. Everyone getting okay with that? Are you not looking good? Yeah. Sure. Yeah. So yeah, absolutely. Because the reporting tools we have don't like take a finished process and then put in the reporting tool. Every single thing that happens in the process is exported. And what you can do is you can create an SLA in the reporting tool that was triggered as soon as the SLA is violated, for instance. So even though you wouldn't do it here you can do it then in optimized. You can actually create SLAs via BPMN if you want. That's fine. Yeah. Yeah, you can 100% do that. That's pretty easy. So like a common one is a timed SLA. So like if, let's say this is a delivery service food. So let's say that we need to get this done by a certain time. Yeah, exactly. Which is a a fairly reasonable comment. What you can do is you can have an event or process that basically says, okay, this is a non-interpreting timer. This would send a warning. After like 20 minutes. And so this would be true for the whole process. That as soon as we hit that 20 minutes we get this warning saying, we're still active in this process that's gonna violate the SLA. And maybe after longer than that, let's say it's specific just for delivering the food. Let's say it's just from the point where the delivery happens. You could also say, okay, this task needs to happen within, let's say 20 minutes, or else we will send an apology to the customer. So this is scoped differently. So now the timer basically is, this task here specifically needs to take 20 minutes rather than the whole process. Yeah, that's where Optimize would come in. Yeah, Optimize would be the place you would go for the overall stuff. And maybe I'll try and create a report that does that later on. Okay. Okay, I think most people have got a model, yes. Yeah. Oh, sure. There's a few different ways of doing it. The first way is, so most things you can do from this context pad. So this is an event here. It's a boundary event. What you can do is you can pick that up and drag it and just place it on the boundary. And then let go. And then once it's there, you can decide which type of event it is. Because there's loads of ways of interrupting this process. The timer is an example. A message might come in. There might be an error. So you can then decide on the event. In this case, we went with timer. Maybe we should just add a timer for the exercise. Let's just do that. So say sorry. Okay, yeah, let's just add this as a part of it. This is kind of fun. So that I can show you how to implement the timer and how it works and stuff. Then during this as well. Apparently, okay, Christian. Yeah, exactly. Because you want to trigger it, but you don't want to stop the delivery. You just want to tell someone it's going to be late. If let's say it's too late. This is now invalid. Then we can interrupt it. Then it'll stop doing it. Yeah, exactly. Okay. Now I've both good news and bad news for everybody. The good news is that, hey, you've listened to me for a full hour, which means you get a treat. And that treat involves the QR code, which I'm sorry for people who don't like it. So you can use your phone. This is a little quiz we're going to do. Not about the stuff we just learned. Luckily enough, because if you were just arrived late, it's just a little thing just to do to break up the hours. So I love quizzes. And I created this one for just now. So if you're interested in playing a little quiz, get your phone, scan it. And there might be a prize if I can find something that I can give you a microphone. So, yeah. Okay. So let me just. I mean, I can and I will because I'm a very kind person, even if it's slightly facetious. Okay, one moment. Okay. Okay, one second. We have two blue joined. Good stuff. The shortened URL is here. For those wondering, if you want to use your computers instead, it's shorturl.at forward slash ahpz. And so far we have exactly two people, which is not really much of a competition. So I'm going to wait a little longer for people to join in. So there's a short URL again. Still two? Do people not like quizzes? How is that possible? Oh, certainly. Yeah, there it is. Does that work? Oh, great. Hooray, we have more people joining. Ah, there we go. The barcode is the issue. So is everyone who wants to play ready to go? These are all questions I came up with in the last day or so. So let's get started. If you answer facetious, you get more points. Gavin Newsom was 36 when he became the youngest mayor of which city? What's it Los Angeles, San Francisco, San Diego, or San Jose? These are all the things that Nile has learned over the course of the last 24 hours. Apparently only one person got that one correct. San Jose was apparently a popular option. But don't worry, lots of comebacks possible. Next question. How many time zones does the USA have? Three, four, five, or six? Wow, that is diverse. There are six time zones. For those who are thinking about just four, there's also Hawaii and Alaska have time zones. Okay, question three. According to the most recent census, what percentage of Americans claim Irish heritage? The 10%, 16%, 20% or 25%, it's a cool 20%. Which is I think five times the size of Ireland which is kind of interesting. 31 million people, there's only five in Ireland. Okay, next question. Which Mexican revolutionary invaded the USA in 1916? Is it Pajovia, Himalaspato, Porfidu Diaz, or Francesco Maduro? Big fans of Mexican history here? Hey, apparently so. That's the question most people have gotten correct. Well done. I guess you guys remember those kind of things happening. And the final question. During the war of 1812, Canada was invaded by which country? Was it USA, Great Britain, France, or Russia? I mean, I spoke great in a very unique way. No, the USA invaded Canada, because it's nearby, I guess. Okay, now for the moment of truth. Now you find out who the losers are. Wow, Mark, well done. There we go, you get this, certified, not my microphone. So yeah, thanks for trying everybody. That was good fun. There's more quizzes, don't worry. So you can also, later on you can try even harder. The other one is a much harder quiz. That was the easy one, just to introduce you to the concept, which disappoints me now. I should have realized the bar should have been much lower. Okay, I'll give you lovely people about like five minutes or 10 minutes now just to come down from the high of that quiz and then we'll return back with the next segment. So we're gonna actually make our model executable, and we're gonna actually start doing some process automation. If you have any questions in the meantime, feel free to ask me, I'm right here. So yeah, five minutes, yeah. Okay, folks, we have returned. So we have a lovely picture, but right now all it is is a picture. If you were, for instance, to download this little picture, with this little button up here, you'll see that what we've created is this XML file. Let's see if I open it, that looks like this. And you can see that it's basically just this. It's a serializable XML file that describes everything that's happening on the visual elements here. And in fact, you can even go in and start tweaking this stuff. So if you really like, let's see, where's the good element? There's a big event. Let's just create a very big event. And you can edit that, and there it is, a gigantic big thing. So you can, it's a direct representation, everything about it, where every single part of it is. So, and this is the executable model that we're looking at here. The thing is it needs some additional semantics, obviously. Right now we just have the flow kind of defined, but we need things like, what UI is this gonna point to? What date is it gonna be using this gateway to decide where to go? And that's what we're gonna add right now. And then we're gonna deploy it. So we're gonna start off with creating a very basic form. There's a lot of ways of creating front-end applications. We're gonna do that to now, it's just do the easiest version, which is just to attach a form to this. In a lot of cases, you're actually communicating with an external front-end application that essentially works like this. It's waiting for events to happen in the engine. Those events are like user created a thing. User created, say a user form exists. The thing will then be triggered to create that form then based on that event. And then that'll make a task appear for a user. We'll enter some data, once they click complete, a message goes back to the engine with some data saying that form has been completed. Here's the data you want, move the process up. So that's usually how the architecture works. We're gonna simplify that just for this by just using an embedded form, which isn't usual, but it's very quick. Okay, yes. It's an ISO standard, yeah. Yeah. And it has been since, I think, 2011, sorry, no more. It was originally created by IBM. It was the first version was. Right now it's maintained by the OMG, the object management group, the same people who do UML and a bunch of other stuff. It also has a bunch of other sort of similar standards, one called DMN, which is decision modeling notation, and one awful one called CMM, which is case management modeling notation. All of them follow the same principle of visual description of what's happening, executable metamodel, cook, no problem. Okay, so let's build a form for this thing here. Send a chef probably isn't, is, does chef want to cook this? And we have a yes or no. Okay, so let's go back here. And I'm just gonna go to my, let's go to this. So this is my service thing, and there's the folder where I have it. Up here you probably notice that there's a beach model to the DMN stuff I talked about earlier, which is the decision model notation for rules. And we also have forms. So let's click on form. So this is a very basic form. Chef decides. And we're just gonna have, it's a kind of basic thing. You drag and drop some stuff here. So this is going to be, do you want to cook this? And then we have a text field maybe for the order. And then here is kind of the important part in the part where we started a little bit technical, which is this thing here, the key is the name of a variable that either exists or doesn't, all right? So in the process engine, you can create variables that can be shared among all the different process, so the different tasks. So if I, for instance, put in here a key that says order, when this form shows up, it'll basically look in the context of this process instance and it looks for a variable called order and populate it. And we'll show that later on. And for the same thing, we also have this checkbox and this is gonna be called do you and this would have cook meal. So this would mean that a variable in this case, if this box is ticked, a variable called cook meal will be created when this task is complete. And we can then use that variable later on in the gateway to be able to decide where to go. That's our goal. Okay. So next up, this form is gonna be called cool form. Now it's gonna be called Chef form. And it is now part of our folder here. And I can go in back into my model, select this task. And then if I click on this little button here, it'll show me all the forms that are currently in my scope. In this case, it's just the one. And I want to select that and click import. We then have the form loaded into the semantics of the user task to build them or to, oh sure. So if you select a user task, this little button here. Yeah, so the form already exists. You should see a list of the forms. If a form is already attached to us, you'll probably see a bunch of JSON, the serialized description of the form. And you can remove this and add it again if you like. So you're probably really looking in this folder for the forms, possible forms in a different folder or something else. And I'm gonna try and find out what's going on. That's kind of interesting. Okay, looking good. Oh, actually, you know what? Yeah, go into the, sure. Can you refresh that page? Sure. Could be the problem. See if that works. Okay, cool. Okay, so apparently, refreshing the page works, great. I'll give you, you wait all the time. Yes, no, that's a good idea. No, write that down. Can you add the form builder? Just click on this. It just adds this to the element that's in the drag and drop it. Cool, good. Thanks a lot. I'm also very happy. Any other suggestions people might have? Okay, so that is how to add our, where is my modeler gone? There it is. So that's how to add forms. I would like you lovely people to spend some time now creating one, two, three, these three forms and then attach them. And then once you do that, we'll then work on the gateway and the timer. And then we should have an actual process. I'll be able to build this and step through it and then that sort of thing. So you can decide on what prepare food might need. And if you have any questions, just let me know. This is detailed in the GitHub repo as well. Okay, folks, so we're going to quickly discuss the timer before we go into the gateway because it's actually the easier symbol to implement. So this is a non-interrupting boundary event. And this means that this event is scoped to this one task and it also means it's non-interrupting which means if we use token simulation on this and I'll just pause here and speed it up. So it means that for here, while this task is active, so is the timer and the timer could then be like can trigger some stuff in parallel and not actually affect the current running of this task which is great for SLAs because you don't want to stop anything. You just want to like run something in parallel. And then as soon as the task is complete, the timer basically is forgotten about and it's out of scope and it's gone now. So let's talk about the timer. And more importantly, let's talk about all this weird stuff here. Let's talk about ISO 8601, hooray. It's a great standard for describing time. And I'll describe it. I'll quickly teach you lovely people, ISO 8601. So let's go P1Y, can everyone see that? Let's zoom into this. Let's say 4M, 21D, T, I don't know, 33H, 5M, 22F. Very easy, okay. So we have here P signs of the period. Well, we start the P. We have a timer that will go off in one year, four months, 21 days, 33 hours, five minutes and 20 seconds. We can also, and so this is what this basically is trying to tell us. And what it does is when we arrive at this event, it uses this to just calculate a date in the future that this represents. Okay, but we can make a simpler version of this because we can also say, well, what if we just want something to go off like every five minutes? So we start with P, we don't need a year, a month or a day, so we skip all those and go straight to T. We don't need an hour, so we skip that as well and we put a 5M and that now will trigger every five minutes. Okay, but there's also another weird thing we can do which is this, any idea what that does? Yeah, so they put this in front, it'll now trigger every five minutes. So this is a definitive in five minutes, this timer is fired to put an R in front of us and we can say, let's say any year in five minutes trigger that timer. So this is a weird duration standard that exists. It's pretty okay to implement and if it was just a year, one Y, then it's a trigger in one year. Yes, say it again. Yeah, exactly, yeah. So it won't trigger immediately, it will just trigger the first time that the year expires. Yeah, so as far as this is concerned, 20 minutes is the time we're gonna waste. You can see here that on the, if I select the timer, we have two options, duration or cycle. Cycle is the one that can happen multiple times and duration is like it'll happen once. So what we put in here, what is my value? This will be easier quiz questions, almost perfectly correct except it's 20 minutes, but like I knew, you have the right idea. So exactly PP30M is this lovely weird duration. You can also use chron time as well if you wanna do that. Okay, it is, I'm putting there, but normally you would have a variable. Yeah, it's quite where you would actually put that in there directly. The variable can be a date in the future that you want to go to or it can be this thing here. It can basically, you can put an expression in there and then it can evaluate in real time, which is a more likely scenario. Yeah, some more sense? Yeah, sure. There's loads of ways of dealing with that actually, depending on, you can use message events, for instance, if you're talking about two different processes, there's an event called a message event here and you can basically use this to communicate with other processes. So I can like put this in here, which means that the timer will trigger, but I won't go any further than this event until the other system tells me it's okay. And it'll wait there forever until that happens. Okay, so that is our timer event, PP20M. We probably shouldn't do that for reasons of we don't have 20 minutes to wait, so I'm gonna just drop a two in there. Two minutes will probably do for this little demo. Okay, so that is timer events. Any questions on this? It's possible, one of the questions that sometimes comes up is if you're using an expression in there of a date, it's very possible the date is already in the past, by the time you reach that. That's okay. It basically has any date that is before the current time will be triggered whenever it reaches there, so it'll be triggered automatically. Okay. Now for the fun stuff. The XOR gateway. So after doing this, we should be able to implement this and execute it. So we have a task in here, and this has a specific variable, one called CookMeal, but I've called this the key from the form. And I just need now to use this XOR gateway to decide on where to go based on that. And because this apparently is a fun walkthrough of various open standards, we're using another standard here. You can see that it's called feel, it's called the friendly enough expression language. It's another standard from the OMG. It's specifically designed to be used with BPMN and DMN. And it's intended to be very readable, which makes it really irritating for developers. Examples, let's start with this one. I start with an equals always, and then I have my variable CookMeal. And then if this is true, then I will go in this direction. So does anyone have any specific issues with this notation? Most people get really irritated that this is a single equals when it's trying to actually do that. But in this standard, for some reason, they've thrown out literally hundreds of years of mathematical expression to decide that a single equals is now a comparison. So that's one of those weird things. Another incredibly weird thing is if you're accessing a JSON variable, like let's imagine that we wanted this, this is the first element of an array. I would like to apologize in advance for those. So these are some weird stuff. The reason is, in the very beginning of today, I mentioned this is a standard designed to be worked with by generally people who are not necessarily very technical or are the people who know the process really well but don't need to know the implementation. So Fiel was basically designed as a way of trying to annoy everybody at once and it succeeded. So in this case, CookMeal equals true, which would send us this direction. And CookMeal equals, oops, sorry, equals, pardon me, equals false is this way. Okay, it looks like this. Yeah, pardon me. Oh, sorry, I can't hear you. Oh, false, yeah, just the word false. Sorry, there's actually a lot of doing it if you don't like typing, which is a quite good one. So instead, I can have this thing here that says if it's true, and if I select this sequence flow, I can just select default. So it'll go down here for any other, if no other thing matches, it'll just go this way. So it'll save you literally seconds of typing. Cool. Okay, so this model is now very executed. It has everything it needs. It has forms, it has this thing here, the expressions in the gateway, the timer is pt2m. So now we are going to deploy it and run it. So this is the first time we'll be leaving the modeler and going into the cluster we created in the first exercise. So then click deploy. I'm just gonna make sure I have to give this a name. Oh, there we go. Give it a process name. There we go. And I'm going to deploy. I'm gonna select my cluster, which is Rupert, and deploy. Okay, so the diagram is deployed. What that means now is the engine actually has it, which means I can now start an instance of it. So I'm gonna do that. And I'm going to add just a variable here called order. Pizza, I guess. That's a common food. Okay, so our process has started. So what is, ooh, that's the wrong one. Ah, Rupert. Ah, of course. Don't mind me. Okay, super. So I need to go back to Rupert, there he is. Okay, so here's what we see. We see the applications I discussed earlier. ZB is the engine, which apparently is helping. Operate is the, just as a reminder, is the tool we use for checking out what's going on the process. Task, this is where I'll find my user task. And optimize where I can do reports. So I'm gonna go in first of all to operate. And I'm gonna take a look at what's going on in there. We have, so this is all the processes I currently have running. There's delivery service. So if I go in here, I can see that this is my current instance. I have one right here waiting to go. I can click into it and see the variables, which is the order pizza. Okay, so this is the admin view. And then I can go back and I can now need to complete that task. So for that, I go into task list. And you'll see here, hey, we have our user task we want to complete. So we can claim this. And here is the task that we created. Do you wanna cook this? The order that I sent in initially, I have a checkbox saying do I want to cook it? And who doesn't wanna cook pizza? So let's click complete. So now what happens is that the variables have been sent back to the engine and the engine then moved to the next step, which is the extra gateway. So I would expect that in operate, it's already moved on. It's already moved from here to prepare food, which means they should have another task show up. There it is. This one is a dropdown, prepare food. I've decided the important information is how warm is the food? Is this hot, medium or cold? Let's go with hot and then complete that. And we are then going to move the token then whenever the event shows up, we'll move to deliver food, which will trigger the timer. Okay, so now we have two minutes until this delivery to happen. And in the meantime, we have a task right here. And as a fun little thing, I didn't actually add a front end to this. This is just what happens if you don't actually add a front end. You have a default view that just shows you all the variables that are currently there. You can edit them and you can add new ones just in case you're prototyping some stuff and you wanna just step through the process. So I have my food, which is perfectly fine. Cook meal is true and the order is pizza. And let's see how we are getting on with our console. Let's start with the process maybe. Yes, question? Yeah, it's the one below the task list, just this one here. Yeah, tasks, we're gonna be seeing the tasks and completing them and operate is where you can just sort of observe what's going on and be able to see where your process has gone, the variables and that sort of thing. Okay, now in a moment we should lose our food. We should know because this task will disappear or something. And yeah, let's wait, exciting times. Let's see if the timer works. I need the questions while I wait for the timer to trigger. No, the excitement is just too much. It must be two minutes surely. I don't speak that quickly, do I? Well, we should do that anyway. So the next exercise, of course, is going to be you lovely people doing that exact same thing that I just did, which is implementing the timer, which is pretty straightforward, just put in PT2M. Then you want to, question? Oh, that's not good. Have you started an instance of the process? There we go. Oh, good, no, no, no, no, thanks for the questions, I appreciate it. Hey, look, we now have our token. Thank you for that, that question was perfect. It made, gave you reasons to talk while the thing triggered. So now, because it's non-interrupting, we should see in our task list, we have two tasks, we have say sorry, and we have deliver food. And both are running in parallel, using the same data in the same process instance, and I can complete them then. And let's do that, complete deliver flu food, and then also say sorry, which is the important one. Great, and operate then should eventually figure out what I've done, and the process is complete, okay? So that is stepping through the first process. Any questions about that? All very simple, right? Cool. If anyone has, yeah, get started. Next exercise is making your process executable. The goal is to essentially see this same screen as I've created. Have your, when you're in, operate be able to go from start to the end. Ooh, that's not good. Let me turn off the microphone. Okay, so we're doing well with that one. I'll give you guys either maybe two or three minutes just to step through the process, and then we'll go into implementing something more technical. We're gonna make some rest calls and stuff, send an email or something in the last hour, but until then you got a couple more minutes just to mess around with us. Sure, I have got another quiz for you lovely people to endure. So yeah, you can scan this or you can go to menti.com and type this in if you don't like, or if you want I can create for you a custom small URL. That's the kind of artisan URL making that I'm all about. Okay, so I'll give you guys a few minutes. Oh, who won last time? Sorry, hands up. Who was the victor last time? Mark, that person was left good. No more competition folks. So you'll do very, very well, I'm sure. Okay, so has everyone who wants to join joined? Okay, we have, we have five. Okay, prepare yourselves. These are the harder ones, okay? The first quiz was very easy. So, first question. Terry Davis built a Bible-themed operating system. What was it called? Well, the Eden 3.1, Perligate, Temple OS or Vista. The Bible-themed operating system for at least in 2015. It's open source too, so Temple OS. Well done, one person who did it well there. I think Eden 3.1 is pretty good. And no one won the Vista. Apparently, God did not create Vista. Okay, next up. Oogie won the 2001 Pam Dog Award for his part in which film? Was it Dogman, The Lobster, The Artist or Up? A lot of people went up. Now, all of these films have had winners of the Pam Dog Award. So obviously that probably confused some people. But the 2011 one is very particular. Okay. 305. Simone Biles has won seven Olympic medals. How many are gold? Four, five, six or seven. All over the place again. This is the time zone question. She only has four gold medals. Four or five. This is a question very close to my hotel room. How many flights on average are landed or handled by LAX per year? 400, 800, 1,100. So per day, it's not per year, per day, 1,600. How many flights are handled by LAX? Right now, yes it is 1,600 flights are handled per day which is absolutely wild. And the final question, my favorite question I think is this is a quote, please fill in the missing words. Los Angeles makes the rest of California seem what? Please fill in the missing word from literary writer Jonathan Culler, if you don't know the answer, that's okay, you can type something hilarious. I'm like giving you a prize for best wrong answer. Mary, we have prizes, right? We have a sticker, so there we go. Okay, this is great. LA makes the rest of California seem boring, mundane, moist, great answer. And slow, the correct answer is authentic. So, there we go. The other great quote I found was from Dorothy Parker who said that, well, it's at Los Angeles 72 neighborhoods in search of a city, which I quite liked. Yep, okay, so now for the moment of truth. Who gets that sticker? Whoa, closely fought, but Aaron took it away. Where's Aaron? Well done. Get all stickers. So, well done, congrats, and now the fun ends. I'm gonna give you folks another five minutes, 10 minutes to recompress, and when we get back, we will actually build some technical implementation. Specifically, we're going to make a rest call, deal with the response of that rest call, and then progress our process depending on the response, and we'll also try and send an email as well. We'll be doing that using some inbuilt connectors. Okay, so five minutes to say to enjoy not hearing my voice. Okay, folks, there we go, that's better. I love hearing my voice louder. Okay, the funny thing that brings me all the time. So, we're going to do the final phase of this, which as I mentioned is going to be the execution phase, where we're gonna actually execute things that are like services. Specifically, we're gonna add a very simple weather check. So, we're going to basically, if the weather is gonna be bad, we'll need to inform the person that their food might be delayed due to bad weather. This is inexplicably hard-coded to Berlin weather, so you get to learn what it's like in Berlin around now. And I think it's what time of the day is it? It's like 2 a.m. or something? Yeah, I'll talk to you about it. So, it's nine, nine, that's pretty okay. So, what's it like right now? So, let me go back to the modeler, and I'll just show you. But this is all detailed here in the rest counter section of the read me, but I'll just step through it. So obviously, the place we're gonna keep this is going to be here, right? Because at this point, we'll definitely be making the food. This is the only point. And we want somehow to be able to both start making the food and also be able to send this warning to the user, saying, okay, your food is gonna be ready, but potentially the weather ain't bad. So, how do we do that? Generally speaking, if you need to do anything at the same time or something, more often than not, you wanna use a parallel gateway. And to do that, drag in an XOR or an exclusive gateway, like this one here. And then you can use the little wrench or, is wrench wrench is the right word, isn't it? Yeah, pretty cool. For a parallel gateway. They're also called spanners, but I don't know which one is, which one is UK and which one is American. And the parallel gateway can then head up here, and while you're preparing the food, you can then check the weather. Okay. And let's make even more space. Depending on the output of this request, we either inform the customer or not. So this is another XOR gateway. And either everything's fine, in which case it's all good, or the weather is not so great, in which case inform customer. Okay. So this is our process. So now let's talk about the implementation. Up until now, we've only been doing user tasks, and now we're gonna do a service task, specifically we're gonna use a rest connector. So these are just inbuilt, sort of easy to use, pre-built things that make making a rest call really easy. So you can see here, they just pre-populates the thing here with the requirements to make a rest call. In our case, we have a pre-well detailed here. I have this lovely hard-coded URL that I'm just going to pop right in here. So that's not the important thing. The important thing is the response and how you parse it. And this is where the feel thing comes in. So if I add this, it's my browser. Let's find out what the weather's like back home. Ooh, God only knows, cause that is not pretty. Maybe Opera will do better. Apparently not. Well, where's my pretty XML? Okay, fine. New plan. It is XML. No, it's JSON, isn't it? JSON, yeah. Cool. Ah, man. There we go. Almost great. So we have here, it is currently, the weather is currently partly cloudy. So that's a real shame, but not the worst thing in the world. We have a max temperature and a minimum of 24, 24, which is actually pretty okay. We have to see whether it's cloudy there. Maybe this is tomorrow. But go to the very top, actually. So this is all kept in a thing called data series, which is the object we need to access. And then we need to get the first element of that and then decide based on that. And I'll quickly open up the, we do that using the expression language field, the same one we did with the gateway as well. And this again is detailed here. And I'll just talk through it. So here's one of the things I mentioned before. Let's just open that up. So in this case, body is the response that we're getting. And then from there, we're basically saying, from the body, get this data series object, which is an array in JSON, and just give me the first element. And what that does is it takes whatever element that is, and it'll create variables for each individual primitive object in that. So what we'll see is, we will see the process create a variable called, oh man, this one. A variable called a date with this value, a variable called weather with this value, and so on and so forth. So we'll just take everything in here and then create variables that we can then use, which is why we can, sorry for bouncing around so much. After making this call, we can basically say, go down here to the result variable, and we can put this, it's actually shown here. Oh, real expression, sorry. And that will then create those variables we want. So this will basically say the body of the response, take this data series thing and give me the first element. I know it's not zero, I'm very sorry. I didn't create the standard. It drove me crazy when I was first trying to code with it. And so now we have like four variables, including weather. And now we can go here, and I think this is again detailed in the, we can use a field expression to say, if, so it contains as a function. So we're saying, if the variable weather contains rainy, we will then go up here. Okay, and now let's see if that works. And then here I'll just use the default flow, so that for any other reason it'll go this way. Okay, so let's deploy this. Yikes, could not load cluster. Why would you do that to me cluster? There we go. Back to Rupert, deploy, start an instance, go to task list, which should show up with stuff. And then I'll just prepare that by going to operate. Hey, is that an error? Oh, it's a different thing, that's weird. Oh, delivery service, right. So here we are at the Chef thing. The Chef is very cool about cooking whatever this order is. So now we should have this parallel flow start to happen, right? So what we expect is that we start this, we then go this direction, we then create two instances, two, sorry, two branches. And you can see here that one is going to repair the food, and one is making the rest call. When the rest call is made successfully, you can see here that the weather is not right now rainy, which is lovely, so we've continued this way. Okay. So this is what I would like you lovely people to do. As I mentioned, and then what we'll do next is, after we do this, is we'll use a very similar scenario to send an email to the customer with some details about their order and so on, here or here, or both. So we'll try and do additional implementation of some technical stuff. So right now, you can use that, and let me know how you get on. So this is all detailed again in the GitHub repo, starting there is the subheading right here. Any questions or comments at all? Please just shout at me in general, and I'm very happy to respond. So I just got a good question about what if we wanted to actually, whether it was so bad to just stop, say the food will not be delivered, and you can actually do that by a specific type of end event called a turnit event, which is not here for some reason. Let me just open up and I'll show you what it looks like in the modeler here. So a turnit event would look like this, a sub-parallel. Let's say you have a whole bunch of stuff, and there we go. Okay, so here we have a specific end event. At the moment, end events work basically as consuming tokens, and if there's no other live tokens, those little things in the process, the process ends. So a turnit event basically is if any token reaches here, kill everything else in the scope, just stop everything. So it's a very nice way of just putting an immediate break on things if they reach a certain point. And with the delivery stuff, we don't have it implemented right now for the cloud version, but if you put that there, then it would like say, oh, the weather's bad, we'll tell the customer then stop the chef from cooking and say, don't bother, it's not gonna happen. Yes, there we go. So then you could basically say, this is a job worker that doesn't work. We point it to the cluster, and any time, any process needs to check a celebrity's age, this thing is always listening, specifically for this check celeb age task, right? So let's see if I can actually get this working right now. I haven't really planned on doing that, but let's just see what happens. So if I start this up, what will happen is it starts up with a little spring boot thing, it connects to the cluster, and it's just waiting for work that might happen at any point. So it's not really doing anything. So now let's see if we can start a process instance. It's running on command to age, so let's do that. And I then need to, so we're at some point. So what you guys thinking, because you have to help me here to give me a celebrity name. Otherwise, this is a point of exercise. So here we have enter celebrity name is the first part of the task. So please give me a celebrity who is 50 years old, or you think might be 50? Johnny Depp, okay. How do you spell his name? Johnny, like that? Well, that's good. Okay, let's find out. I'm very excited. So assuming everything works correctly, we can go to operate. So we're at this point here. Hopefully I've created this. It should move on. We have a couple of possibilities here. Either we, they're exactly 50, you win a prize of some kind, or they're not, you lose, or I can't find this, or I misspelled the celebrity basically, or I can't find it for some reason, in which case it throws an error. And we can then, but a specific error that gets caught, a business error we're calling is another technical one. Oh, you lose. Let's see how much you lose by. That's a real shame. Johnny Depp is 59, I'm sorry to say. So there we go, that's a real shame. So there we go. So this is the way that the workers actually tend to be implemented, which is totally external from the service. But it's much harder to do that in a workshop, which is why we do the REST call. So that's kind of how it works. Then on a testing scenario, you would actually test the workers independently and then just do an integration test at the end. When both the model is tested and the workers are tested, you then do the integration test. We have a bunch of, so we actually have a bunch of supported languages for the microservices. We have a template that makes it really easy to subscribe to the topics in Java, JavaScript, and Python and Go. And so then everything else is custom code, whatever you want it to do. You can see in my code, it's a worker that just makes a REST call. It then gets some variables and sends them back. That's all. And then we can also do other fun stuff. Like, I haven't shown Optimize yet. This is the way we've got to continue to do that. So Optimize has been secretly, while this whole thing has been happening, has been getting all the data from all the time you've stepped through the process and Optimize is used to visualize this. So, using the Who's 50 game, because it actually has data, let's see, is it Who's 50 or Game Who's 50? A Game Who's 50, great stuff. When any convention is flawless. That plan, go ahead. Okay, so there's my process. Oh, why is it so annoying? And I can create a report and I can see the most common route through the process, for instance. So, this is only six instances. That's not great. So, I'm gonna edit this and choose the other one. Which one did I choose last? Because one of them has quite a lot of instances, I remember. So I want to see process instances count, 65, that's better. So now I want to see, let's say, flow nodes. Show me heat maps. So this shows that 65 instances started. We had nine times we didn't manage to get it correct. Four winners, very low. And 38 total losers. Now, that's quite nice. It's kind of handy. You can also see things like, instead of count, see duration. So you can see what most time is spent. People like looking at errors, apparently. But then you can do really, really fun stuff. Because then you can actually use the data in the process to create reports. Like, for instance, I can find out count the process instances and then group them by the variable that people guessed. So now I can see that 50 is here. So, like, four people guessed this. And you see the cluster of guesses around 50 here. People were way off at some stages. And you can then even see things like, who are the names of the people who people were guessing? So we see that, who's this? Jennifer Lopez was guessed quite frequently. Brad Pitt. Tom Hanks. Tom Cruz. Johnny Depp, there we go, you weren't the only one. So, so then you can sort of get a lot of information on the reporting side of things as well. Just as a side note. Okay. New page, great. So we have a cool 15 minutes left. And with that, we are going to send an email in a very easy way. And it's going to involve changing our model again. Let's see if I can find it. I took a detour and now all my tabs are a complete mystery to me. There we go. So we're basically going to change this one here. Notify customer is a user task. This is a clear example of something that should be automated. And again, we're going to use a, what's it called? If I scroll down. SendGrid. So SendGrid is just another connector that we have. That you can use quite easily. And we have here, we need an API key, which I'll talk about in a second. And we have a sender, their email address, a receiver email address, subject and so on. So for this particular example, we're going to talk a little bit about security. Because I do, I'm very insecure and that's why I've added the SendGrid key for this thing is right here on slide 17. So you can go and copy this. Now, usually you would not want to put that in here. You probably shouldn't put that in there. It's a key. So what we actually have, if we go to the console here and we have the secret connector secrets. So here you can see that I have a SendGrid key. SendGrid key. Ooh, fancy. So, with either of these, I can then call these at any time I need to. And you can see from the, and you just add them like this. Key would be, yeah, SendGrid scale. And the secret is here, great. And so this can be accessed now during runtime. So if I go back to my model, the way I access it is, actually maybe I'll show you in the, in here. Yeah, there we go. The way I access it is basically saying secrets dot the name of your secret that you want to import. And then you can see the other stuff. So let's see if we can get that working. So I should say secrets dot SendGrid scale, which I think is what I called it. It's literally moments ago and I'm sure that's correct. And name. I wonder if I need to put Naila's email address in there. Probably. Let me just find out one moment. Cause it's her key that I made it set up for me. Are you? Huh? Yeah, for sure. I always do this with a colleague of mine and she does this part usually. So let's see. Ah, go away windows. Okay. So we can all send her an email. I'm sure she'd like to hear from us. So I'm 100% going to do this. So I'm going to send my dear colleague Naila an email. So sender is Nail, the email address is Naila's name, also is Naila, her address is here. Okay. Great. So this is us. This should do the trick. See how responsive my colleague is at what time is it now back home? 10 p.m. She should be awake and doing stuff at 10 p.m. She's either dedicated or she's not. So I'm going to deploy this to Rupert. And then I'm going to start an instance. And I just realized now I have no way of testing this because I don't know if she's got the email or not. So we'll have to deal with that later. But then we can go to our task list. Oh, that's a different task list. Apologies for that. What the hell? Oh, it's Rupert. This is what happens when I just go off the rails a bit and do a random other demo. Let's go to task list again from Rupert. Does the chef want to cook? The chef does not want to cook this. The chef wants to send Naila an email. And so we should be able to see then, oh, there we go. So now it's sending, hopefully, an email. Oh, it's failed. This is almost certainly my fault. Oh, okay. So I messed the secret up, which I think is your fault since I specifically asked you guys since that's the one I typed. So let's do that. That's just complete the task. I hate being an uncompleted task. There we go. Okay, does the chef want to cook this food? The chef does not. Let's hope I can spam my colleague. See, that should move on. Hooray, we are one step closer. Hooray, she did it. So now I'm going to drop Naila's email address into the slide deck so that we can all send her an email. So I'm going to put it beside the send grid thing. And oops, that's not it. I can actually just check the operation should have her email address somewhere in here. That's a variable, maybe. Oh no, it's hard coded, isn't it? Okay, there we go. That's in there. So if you love people who want to go ahead, just find an exercise, send an email to my colleague Naila, and she'll be delighted to hear from you. And you can follow those instructions pretty easily from her Github repo. You can tell her thanks for the exercise that she spent time preparing. Everyone happy enough then? No. Yep. Cool, I'm so glad. There is more to do because the work never ends. You can see that I mentioned the job workers earlier. You can see here that there's the thing I built for the Who50 game. You can build that in the next exercise. And then also the other bonus exercise is error handling where we'll discuss how to throw business errors that can then be caught and then change a process that way. So that's what you could do if you're bored later. And yeah, and I'd like to thank you guys for sticking around for the whole three hours. I greatly appreciate it. And yeah, I hope you enjoyed yourselves. And we have a booth somewhere. Yeah, so if you have any other questions or comments, I'll be there and see all my colleagues. You can come and chat to us and let us know any of their thoughts you have. So I can let you guys get to lunch and enjoy yourselves. Cheerio, thanks.