 Then it does some processing of a data. And triggers are nothing but, again, feed works closely with feeds. It says, like, so I tie, it's kind of a tying twine between your action and your feeds. Let's say for this feed, this trigger will be triggered, which will trigger this particular action, all right? So I tie it like it's, these three terms are pretty a bit confusing, but you have to read multiple times About rules, rules are nothing but, like, it's, again, how do I tie my trigger to an action, all right? So I get trigger, I have feeds. So how do I tie my trigger to an action? When you say, like, when I trigger something, some action has to be invoked, right? So that's where we define rules. Rules could be enabled and disabled. Sometimes if you want to disable some rule, I can go and disable the rule and re-enable them. Activation is nothing but your logs of how many, how the function was invoked, what's the output of the function, in any error is there. So all these things get, it gets kind of from your activation of your functions. Yeah. All right, so what are the invocation patterns we have right now? So we have three main invocation patterns. One is asynchronous. Technically, all functions tend to be asynchronous, meaning they have fire and forget. I don't know what happened. I have to go back and visit my activation log to see what exactly happens. And synchronous, I mean, I wait for that response to come to a typical bent kind of interface where I wait for the response to come after I invoke a function. Schedule is something like your current jobs, which gets executed and specified in a lot of time. So these are the right answer three main invocation pattern around functions. So how does OpenList work? So OpenList has these many components, for example, an engine is front-end. So it serves as a rest interface. And then we have a controller. It's a technique which controls everything inside your application. So, and then we have an after engine running, so which seduce the messages to get the action that needs to be improved. And we have the CouchDB, which serves as a place where it controls your authentication information, action information, all these things are stored inside a CouchDB. Technically, you can imagine like, it's the database repository for your OpenList thing. And then invokers, invokers are nothing but a Docker engine. So each node will have one invoker. Each invoker is a Docker container. So for example, for each type of functions, we saw like for Java, JavaScript, Node.js, Python, Go. So we are one invoker for each type of function. And then this invoker takes care of triggering a starting a new container, a Docker container which runs your code and then comes out. So each node will have one invoker. So this is the very high-level view of how OpenList works. Okay, let's quickly see some quick functions just to get a feel of it. So I said, told you like, you can go to this place. So I have a complete tutorial, and I'm not, though it says as Java fast tutorial, but I have basic, basic examples of things how running. So I'm a Java guy. So kind of wrote Java functions. So you can write in any language you wish. So what you want to do quickly is, so it's going to do this function. First, let me see if I have a function. So the very basic command is whisk dash i action list. So this gives you the list of actions that's already there. And the function will be evaluated using the different instances today. So my talk on D-minus 40, so it's still pointing to some value, you know this. So here comes the game. I think the environments today just changed this form. I talked yesterday, so it's updating it once more. So I just have one action that's good. So usually, what I like, you see I see, so this is an HTTP address. So technically when you run, this is for the first time. So what happens is that we'll get another certificate address. So usually to avoid that, since it's my local environment, we need a appended parameter called as dash i. So this is dash dash insecure, kind of stuff. So what I did is like I just made an alias for whisk by always equal to this dash i. So I don't need to type it every time, okay? So let's quickly go and then write our first function. I just make this, I just following this so that like, I'm going to write a very simple function. That's all I need. So I just go there and then say create this action. And you see your action gets given up. I'm hiding you, is that clear? You okay? So what I did is like, I went and created action. If you see it's not a big file, I just say a simple JSON response that's given from this function, basically. So I just create this action. And then I say, okay, create this action. And you saw that this action was created, called as created. Let's verify if it's there. This action list. So I see that this by default is a JS. It gets attached to a node JS at a time, by default. And then it's by default, the default packages list system. So if you want to create a package, then I can attach a package, add the intro package. So how do I invoke? It's pretty simple to invoke. So this is the synchronous model, which I said. So which means that I have to wait for the response to come. Since it's a very simple function, I say give me the response with dash dash result, which means that the command will wait for the response to come. Just a synchronous mode of indication. So there you go. So you get a response here. So in case if you don't read, so the asynchronous mode is like this. I do this. Once I do this, I get an invocation ID. So and then I have to say, risk activation. I say that activation is the log for all your things, activation, result. And then I say the activation ID. Once I say this, I pretty much get the same response. There is also a way by which I can do this risk activation. So it's a long-running thing. Like for usually for a developer and drama, you can just have it polling. So that whenever a new action gets invocated, you see the logs on the pole. So for example, let's say risk action. Let me copy this. And I say invoke this action. And you'll see this action got invoked here. And then gives you an activation ID and then it is starting. So these are pretty useful stuff. So this is two different models I do not have any. I don't have an example for scheduled one. But this is how we invoke asynchronous and synchronous mode in these actions. Let's get back to what we have here. So what are Java actions? Java actions are nothing, it's pretty, again, the same similar action like how we wrote the JavaScript. But it's a traditional Java language, it's a single class, usually a Java source. And then it has a different signature for the main method. So we use the JSON object input and JSON object output as a parameter. So this is a rule for writing a Java function on open disk. So I did a bit of research around two main components. We have something called Spring Cloud Functions, which does the same work. And then the plain old functions, the simple Java function. So the advantages of what I found was like the plain old Java functions were simple Java pojo, single class, and then I have a bunch of methods, which are, right? And it's very simple and straightforward to understand. The only problem is that I found where it's not portable across serverless providers. For example, I could take OpenWiz thing and then go and deploy it on AWS Lambda or Azure functions, right? It's not portable. And then the dependencies need to be bundled together. For example, if my function depends upon, let's say three, four jobs, commons land or commons knocking or something like that, then they have to be bundled along. That's what makes your jar a little bit, right? Right now, if I remember correctly, that the maximum size of an OpenWiz jar is 50 MB. So I cannot have more than that, right? And then, so right now it uses third party Google JSON for OpenWiz Java, which means that I'll show an example right now. My method signature has to use the JSON object, Google JSON library for important output, right, to convert to JSON. So we, our thread has, so we are working towards making defined in a Java model. So we are kind of saying like, how the Java function should be there for OpenWiz. So on the contrary, I tried SpringFloor functions also deploying on OpenWiz and then, they're quite a good advantageous things here, like the popular Spring programming model for you. And then it gives you, it gives you supplies and consumers, the typical Java eight language constructs, right? So it identifies them, if you annotate them as SpringBees, then it takes them as functions and deploy them. And then it has adapters for OpenWiz, KWS, Azure, all this stuff. So it's easy for you to port across, but there are big disadvantages because I found it really heavy for a function environment because I don't need so many Spring dependencies that comes there, right? And then also like the startup time is longer, function should be super fast coming up and down. But because of these dependencies, what's happening is that, it has to wire those dependencies, get those dependencies inside your application while doing the runtime. So it's causing it to be very slow. And then it gives us a sort of thin jar for dependency resolution as we talked about. Customization is not possible because right now it's OpenWiz, I can deploy my own Java and type Docker based runtime and then deploy it there. But with the fee, for example, if you take Azure, I cannot deploy my own Docker image there. So I have to use both Docker image, AWS, means same thing with Azure as well. So that's pretty much a bit of a problem because for Spring Cloud functions, I have to build my own Docker image. And then deploy the Docker image as your runtime, okay? So tooling, so there are WISC, which we already saw, it's a default command line interface that you get with Apache OpenWISC, which is used for doing all sort of interaction with the WISC runtime, OpenWISC, WISC deploy, something which they are building right now. So which helps you to define your function deployment as a YAML file, like how you do for Kubernetes YAML. And then we can just deploy the function. You can define packages names and then function names, main class and all these stuff. So YAML manifest and then it can take the manifest and deploy it, okay? Maven for Java, so I just pushed one Maven archetype and the Maven tooling sample for Java. So you can just use Maven archetype, that's what you'll be using in our example in a few minutes. So this can be used for Java alone to deploy the thing. And then for serverless framework, there's a framework, how many of you have heard of serverless.com? So it's a exclusively serverless framework. So which uses, which is Porto, which has framework or in place for multiple providers as you, AWS, IBM functions and OpenWISC. It is based on Node.js, it gives you templates to create and then it also has a YAML manifest where we need to fill in some details and you can do deploy it across multiple providers. So we also pushed here. So it did not have our OpenWISC Java template, serverless.com and we pushed, from that we pushed for that as well. So now serverless framework also supports OpenWISC Java as well, so you can create that template as well. So quickly on the web action, so this is the most, first thing which any developer would like to do. So even if I had to deploy a Java function or JavaScript function or any kind of a function, I want to know how do I invoke via web, meaning to say I have an HTTP URL and I use any kind of HTTP to just go up, like get, post, put, delete, anything I want and then I want to get it invoked. So for example, what it says is like, so it has an URL and then I can also have the content type by virtue of prefixing the URL. Let's say .json then means my content type will be JSON, application slash JSON. If I do .nastyml, then it means that it's common word, you can nastyml response from the function. And then I can have query parameters, I can have request body as usual with any function, so what happens is naturally the request body and query parameters will be landing as function parameters. And I have a content type that I said now and then it's not what you call it, I think it's a typo there. It's not asynchronous, I need to say, so which means that my result has to be blocked until my response is compact. So sometimes some resources needs authentication, not all functions are open if a function is private package, then I need authentication for it as well. So let's quickly check this. So what I need by parameters is that if you've seen my old example which you wrote just a few minutes ago. So this method doesn't have any parameters. So usually technically what I can do is like I can just say like this. So this perhaps will be a JSON input to a function. What about keypad you can give? You just keypad and you can just pass them as parameters as well. We'll see that in example in a moment. So I'm shifting back to my notes, the tutorial which I wrote. So what I'm going to do is like I said, we need this, so right now this Java Action Act type is a Maven Act type which is not there in Maven Central. So is this clear? So what I have to do is I have to install it locally. I already have it locally, so I'm not going to do that step. So what I'm going to do is like I'm going to create a Java project now. So just say this, this copy and paste this. I say Maven Act type generate this particular artifact and then example I'll show you how to open up this source in a second. So I'm just going to create an artifact called as OpenWist, okay? So here I'm just working out with OpenWist guys to see this type is supposed to Maven Central so that you don't need to install it locally. So it's already available like any other Maven Act type. And it's just a game of stuff here. This Google Dats give the defaults, it lasts for some things, so there's no need to take that to defaults. So if you see this, it's not a big deal. As I told you earlier, this has one dependency. So this Google Dats one dependency is required because right now OpenWist mandates that we have to use the classes from JSON for JSON conversions, so I have to do this. And all of the stuff if you see I have used Maven Shade plugin to kind of make an over jar with all my dependencies bundled inside one single jar. And that's pretty much what it has from form perspective. So if you go to your class, it's a very simple class here for the same. I assume I think this one is. So as I told earlier, so this is not a typical Java main function. So this function is a little bit easy to see it as a JSON object as a return type and then it takes a JSON object as arguments. So which means that I can pass a JSON object, any argument that you pass via this CLI will be converted into JSON and given to it. So you don't need to worry about it. All I have to do is like which, I want to know which object which attribute I can extract inside my class. So in this example, I'm not doing anything very seriously, I just take the JSON object and then I say append and respond and then it's in the JSON path, okay? So let's go build this in deploy. So what I have to do is like, just do this clean package. So you're good. And then to deploy is awesomely so easy. I'll explain these parameters in a second. So I say that I'll create a new action called as a low open-visc, which will take the jar as an input and then the main class, I have to tell you which main class I have to go and call for this function in location. And I can have multiple classes inside my jar. I can say which main class I have to invoke. So okay, there's again another thing which you're working on to see that it can automatically infer this parameter from manifest file, jar manifest. So which is still a work in progress. So this is target to just change this one to quickly go. There was a glitch which my archetypes who have to use this on as an artifact, I think. Is it just a pojo? It's just a pojo, that's it. So you can have any number of pojo. If you see this, this is a function class. If you see it's just a pojo. I don't have anything else inside this. I can invoke. I can even add dependencies and invoke any other stuff like that. Even if you see the small test class which I have to run here. So I just do a simple invocation like this. That's all. So like how it gets involved. So I built a JSON object response. So here I'm building it manually. So if you use WISC CLI, then WISC CLI automatically builds those JSON object based on the parameters. So for each parameter you pass, everything will be a JSON object. So I've rebuilt it. So my target jar, and then there you go. So you get the action created. So how do you verify it? WISC action list. And then since I gave it that jar, WISC will automatically attach a java and type of this. That's what you see here, java. The previous one we did was nojays. But what you're seeing about right now is that we're talking about doing a web action. So what I would technically do for a web action is that it's very simple. So you say web, it goes through. So this is another command you're going to learn now. So right now I have a, let's invoke it first and then we'll go back to it later, converting that into web action. So what I'm going to do, like I'm going to invoke synchronously. I just say WISC result, and you get a response from your, right. How do I convert? So there's a WISC. As you do a WISC create, there is also something called a WISC update. What it means by this is that, let's say I want to update a function. Let's say I already deployed it. I want to use the same name, but a different artifact has to go or different main function has to go. I just say update. So once I do this, this function now, I attached an attribute called as web equal to true, which means that this is now converted into that function, right. So what I can do right now is like WISC, apply action, get the action name. And then if it says dash dash URL, I'll get a WISC URL here to this function, right. So how do I can also do this as well? Summary, right, use a summary of my function as well. These are, I have used multiple commands here. First one is that the update command, which means that I'm going and updating back the function. Let's say I changed my logic of the function. Already I've created the function the same name, just want to go and update it, right. In this case, what I try to do is like I'm updating that next is a parameter called as web equal to true, which means that my action has now become a web action, which means that I get an HTTP URL to invoke it. I can use it, it's irrespective of if you can use any methods, there is no method attachment here, which means that it's just a new URL. I can use get, post, delete, any kind of methods. It's not just, you can use one to get, I cannot use only post. But there are ways by which I can restrict it, but here in this case it's not restricted. This action gets summary, which gives you a summary of your functions. Let's say if I have defined multiple parameters, then my parameters would be like this. See, there are some ways in openness, what we do is let, we define the parameters, default parameters. We need to say like, okay, let's say I give a name. Let's say an example, the function takes a name, and I say by default name should always be centOS. So I can just define that if even if the user doesn't pass it, the centOS is a parameter that will be taken inside, right. So how do I invoke this as, the invocation is, yeah. There's a view, I mean, the parameter, who does Java method it, just with the, it's an object, right. So come over there, it's not this one. But this one, no, that's a sign of signature, right. This parameter is defaults within that. Let's say, for example, I can also have this like a string object, okay. But you won't show it. It won't show it. These are, this, what's shown here is is a default parameters. What if if I don't pass this arcs, what will be my default, right. There'll be cases where, for example, let's simply, I'm just changing it for a name sake. Let's say I have string name, right. And then what if, and then I want to use a name here. What if if I don't pass this parameter name, what will happen to the value of it, right. So that I can define, when I create a function, I can say a parameter default value, and then I say this is a value. And automatically, if I don't pass the value, it takes that value for your function, okay. All right, so how do I invoke this? Use our curl. I don't get, I cannot see the response right here. I have to go and invoke it from a, I have to say what content time I'm expecting it. So I'll say edge is another way. So if I don't specify a content, the last time I invoke, I did not specify content time. So which means that my response doesn't know how to return a response to me. So the next time I invoke, I say that I need JSON type. When I click this.json.xml, or whatever you want to do, when you do that, it just automatically responds in JSON form. So which is obviously my function is JSON function, so it's JSON payload path. So that's the reason why I will fix this. So in other ways, like you can also pass as a header. It's if you request it or saying that the content type is application slash JSON. Then automatically you get a JSON response back. So another super critical stuff which you do always is when I say risk action, I will do this here. So this is highly useful when you debug it, you take an invoke prefix verb dash b, the parameter. So what you see here is that you will see the complete request that happens, right? This is highly useful in many times, because you will be lost seeing like why my action has started turning something, why this is not working. In those cases, it's highly useful that is prefix dash b, so that you get a complete JSON output and you can find out what's wrong with that. It gives you the authorization that gets in and then what's your response code, what's your response headers, user agent. So you get all these details which gets passed, and what's the content type by default, and then set some cookie, I don't know about what's the cookies. For and then it also gives you an activation ID at the end of the day, that's the response. The response body is received with an activation ID, so which means that I can go and look for the logs. So for example, if I go, take this activation ID and then save it, this activation results, then I get the results back. Okay, so any question on action, web action? So let's get back to what you were talking earlier. So we can also change the actions, which means that I can have a series of actions to be called in a sequence. I can say a call actioning, action B, action C, and action D. So I can also have these actions to be changed. There's also a way by which there's also a run time, so sequence is nothing like I have to define it with a different action, which means that it is static. So I can also have to say action one, action two, and action three, it's static. Whereas in conductors, it's a different type of sequence where your run time decides which sequence I need to follow. So this is more dynamic in nature. So there is no input sequence, only the first action takes input. For all of the subsequent actions, the output of the first action serves as an input for the other. They're just like your functions. So let's quickly see this also, training as well. So go back to training example, receive web action. So what you're gonna do is that we're gonna create three, again, what I do for sake of time, I already have them with me. I'm gonna deploy three actions now. So, so the sequence demo, so I'm gonna go for three. So I have three actions and basically one is sorted, one is splitter and one is not the case. So what I basically do is let this pass a comma separator string as a parameter. So it goes to the splitter, it splits it down into small chunks of strings, and pass it to the uppercase which converts that into uppercase and then finally it gives to the sort. So this is a sequence which I'm going to see now. So let's go, let's go to go back to my thing. So I'll just see, I just go to create. So this is a way, this is something new I'm introducing here is how do I create a package? What I'm going to do now is just create a package. Package is nothing but logical grouping of your functions. Nothing, no big deal is done here. If you want to add encapsulate something, you don't want that to be visible temporarily. So if you do then, if you do twist, same thing, FNI, package list, we'll see the package here. So right now it's private by default. So I can also change it to public as well. So that everybody knows it. So now I'm going to do is like I already have this glitter function written. So I'm not going to recreate it again. I just going to go build it and deploy it. So just going to go to my glitter function and then I just keep the test for time sake. So my function is ready. So I'm going to go deploy it here. My function is updated. Then I'll do the same thing for uppercase. I'm not going to use any. So if you see the difference between the earlier action creation and this action creation is that, so we always suffix this with the package name. See here, which means that it gets into that package. So if I do the same package list here, says here, so then if I say action list, you'll see that action is getting inside a package. All right? So this system, Red Hat developers demo and slash glitter on slash glitter. So it gets into that way. Okay? So I'm going to create the uppercase function. This is also done. Then I go to the sort action and then I do a build and I just create the sort action as well. All right? So we're good now. So to create a sequence, what it basically do is like, I create a sequence action. So again, a simple action thing. I just want to just be here. I say, I create action update, then split upper sort. I just leave it like this. And if you see, I'm adding a sequence parameter to this. The sequence parameter, I say, comma, set it a list of functions that needs to be involved. It's typically for the same order in which you give it. In this case, I'm going to go to splitter and then after splitter it goes to uppercase after uppercase it's going to go to the sort. So my action is created. So once my action is created, all I have to do is like, let's invoke it, see how I'm going to do it. So if you see here, I'm just passing a param text. That's what I use inside. So after param, the first parameter, after param is the name of the parameter, which is technically we see that it gives us a JSON attribute. So when I'm getting it out, I have to use the name text to get the attribute value. And then I'm just passing a comma separate of string to be sorted. And then I'm going to expect the response now. So it is the first time it really takes a bit of time to sort it out. Now if you see, I get a result, which is sorted now. So which means here, there's a three sequence of actions getting called. To snow, let's do one thing. So let's quickly activation mode. So it's going to an activation mode to see the sequence of actions getting over. Now if we see, if you see the activation mode, I get the splitter first, and then your uppercase is called, and then your sort is called. So it's a sequence which we define that I have to go in this sequence. So it's being done here as well. And then if we, for this finally the sort split sort of action class where it's kind of collating the response from these three, these are given to you. Okay. So that's about changing. So it also has, I think we saw about in the jargon in the theory slide where we said like, there's an event given capabilities of OpenWisk, which means that somebody can invoke some event and then the result of the event will be a trigger that cause an action. So that's what we do here. So events could be other function, external event kind of feed provider right now. It's supposed GitHub, Slack, and all the evening you can write your own provider as well which sets an event. So we wrote one provider for infinity span cache. So when we said that any entry you put on infinity span cache, so that gets the event gets triggered via the infant panel listener. The listener will then call a trigger, trigger event and then to give it to any function that does some action on it. So we did it that way. So routes, event action in OpenWisk is that it looks a trigger again, I said that rules ties actions to triggers. And trigger there are three types of feeds basically one is polling. Something keeps polling, I have another thing to invoke an action. The other one is a web book. So this is how GitHub and then Slack all works. So I registered a web book with my function and then that gets called whenever something happens there. And persistent connection is what some service you have to start up a service which keeps running always and then it kind of receives an event from the external event source. The moment it receives it's called the REST API that goes and calls your function. This is the pictorial representation of how the trigger works. So from this it's running when it calls the event and then it calls your function. And that's all I have for today. So we can just go here to the same demo and then you can just run yourself the demo to see how it actually works. But thank you.