Spring Cloud Function: Write Once, Run Anywhere (For Real!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
my name is dr. Kazuki and function today before I get into any details how many of you were in my presentation yesterday very good so I guess you want to know more right so for those of you who were there yesterday some of the stuff that I'll be talking now may be repetitive because yesterday we talked about spring cloud stream and eventing and how spring cloud functions or functional programming can help you now we actually get into the internals of spring cloud function as a project as a framework kind of a another deep dive sort of a session I don't know how much of a details I can cover but I'll try to do as much as I can I have like running like a plan but with the demos but however many we can hit we'll see again as yesterday few slides and then we'll start coding for those of you who were not there yesterday again my name is Alexa horochowski I've been with spraying twice once in 2008 I joined SpringSource then I left in 2012 during that time I work in spring integration as an engineer and how many we using spring integration very good and I came back about three years later to give it all to the same team and now I'm leading spring cloud stream and spring cloud functional project Dave sires here the founder of sprint loss function project and the founder of many other projects in spring so I'm kind of a have a big shoes to fill but hopefully I'm doing the good job quickly about myself I'm originally from the most famous country in the planet when I guess Ukraine exactly came to United States in 91 and now I'm living in France don't ask why so alright let's begin so spring clock function this is kind of a quick agenda what we're going to be talking about so yeah my microphone so why functions and why sprint what functions water sprinkler functions and how we use sprinkler functions so why functions well the better question is why not right so think about what function like this three strategies actually give you and look back at your like try to analyze your requirements the months that you work on the ones you're working on currently or may work I mean this stranger faces you mean whenever you but whatever you do in your programming world you always either produce data consume data or produce and consume consume and produce data right is there any other use cases right so if you really abstract yourself far enough then pretty much everything that you work on can be mapped to either supplier function or consumer right and that brings a very interesting paradigm because now those are the interfaces that come with Java right so and not now and not only you can implement them you can just throw lambda that looks like a function supplier consumer and that will work as well so the bottom line is that these are pure Java interfaces they don't require a spring they don't require anything you can implement your function functional requirement and then you start looking at the frameworks and that's really the value proposition of a spring claude function which we'll discuss in details in a few minutes is that if you have a function I can do a lot of things with it okay so if in other words it's almost like a canonical or uniformed programming model that it gives you so Y spring close function well before we get into white spring cloud function let's figure out what is spring cloud function and what does it give you so I just mentioned that it kind of gives the additional value so what those values are again it promotes the implementation of business logic as functions primarily supplier function and consumer as I already mentioned that gives you a uniform programming model and some of the new features that we been adding in the past six months is transparent ad conversion and I kind of alluded to that yesterday I'll demo today which basically means that your function may have function poacher poacher and you may provide especially when it comes to remoting streaming type of environments where you transmit your object in the form of a JSON or something will do the conversion for you so you don't have to do all the boilerplate code so you can keep your function domain-specific function composition which is an awesome feature because I keep saying I think right-side that but there is no such a thing as a complex problem every problem complex problem is just an array of simple problems so they have to parse that out like this and again with function composition you kind of can do that now because you can implement you individual requirements as functions you can test them as such you don't need spring for that you don't need anything for that right and then something like sprinkler function will allow you to compose them chain and whatever board you want to use and now you're essentially creating a synthetic function that is a composition of several functions and we will see that in a few minutes what's also interesting is that there is different style of functions we yesterday we talked about you know streaming event processing as well as simple event processing and a streaming event processing involves streams like flux or something like that right so what if you have a function that is imperative another function is a stream function can you compose them in a real world no because function and then function and then function requires type compatibility right but sprinkler function you can and we'll see that in a few minutes what else poacher function that's a new feature so basically duck typing if it looks smells like a function it's a function right so in other words while we're promoting or trying to say this and implement everything as a function that doesn't necessarily means you have to say my function implements function if you follow the convention which function means that if it's ad functional interface essentially if it's a class with the one public method that lets say returns value and takes value both treat it as a function ret this is again new feature was primarily driven by riff which is basically functions with multiple inputs multiple outputs I showed a little bit of it yesterday we'll dig in a bit more today deployment of packaged function another great feature of spring cloud function so we can literally deploy if you have a jar that has a function we can deploy it in other words we don't have to pull your function out create a new project or whatever all need to do just create a new project with function deployer when a class path and point to your jar and will deploy it will load it into well I'm skipping too much ahead right now and last but not least integration with service platforms like a table yes I sure and open whisk and so on as you can see there's a lot to unpack here so in one hour I'll see how much I can accomplish but I'll be hanging around throughout the day so you can catch me and drill me for more okay let's slide before we get into coding so when you're working with spring close function you there's only really two interfaces two strategies that you have to be familiar with the the first one is the function catalog which is like the primary place where the functions how you interact with functions you get them out of a function catalog okay it essentially acts as a function registry it wraps functions and to add additional features such as composition tap conversion and so on so forth right and another one is a function orchestration which is you may not always need to interact with it because it's kind of for the edge cases where you want to be able to but the bottom line is like let's not even discuss the educators right now the bottom line is function function registration is the way to register function in function catalog and it encapsulates all the information about the function and the reason why it's important because again everything internally within Spring cloth function we try to stay uniform so in other words when you dealing with a simple function like function being as we'll see in a second we internally will still wrap it in the function registration so everything internally is a function registration because it's an object that contains all its a like matter information about the function the target the input types output types how many inputs how many outputs and what have you so and a lot of times it's used for manual registration of a function however I can't come up right now with the case when you want to do that but anyway so all right now as I said yesterday I don't wait till the very end for questions I prefer them in context so please raise your arm I'm scanning so all right so again just a save time I prepared a few things but we'll code some things in advance as I go along so what we're looking at by the right guys on the back can you see the code all right so we have a simple spring board app there's nothing new here we're creating application contracts we're getting function catalog so again it has spring Clause function context on the class path okay so that's a context will bring core and then you get everything so and now you can that's what that's how you're gonna get function catalog so function catalog is going to be registered through order configuration so you don't have to do anything for that and now I'm doing function lookup I'm providing an empty string kind of starting from very scratch and executing this function now this may be confusing but if you look at my configuration and believe me it's still in the configuration right now that's available to the spring but configuration I only have this function upper case so it is the only being of type function in my configuration right remember how I said yesterday we try to limit configuration as much as we can so the boot mentality is we have an opinion right as long as we can if you agree with our opinion and go ahead and run with it if you don't as long as we provide ways for you to back out we're still friends right so our opinion if you only have a single function you really don't have to provide me with the name because I can discover that because my opinion is that I think you intend to use it right so I can look it up as a as a empty string we probably should have all right the method just do a lookup with nothing but if I run it we got hello okay now obviously if I do uppercase hmmm it will do the same okay yes yeah auto-configuration it is injected so remember we live in the spring boot world okay which means that whenever you throw something in a class path there is a boot magic right so there is some other configuration that comes with when you add sprinkle out function context to the class path something happens right yeah but the function catalog was already part of the application context right so anybody won't ask a question I kind of expect that there is a question looming here let me try to lead you to the question so go ahead um well we're getting into sort of a performance of initialization application context that's really topic in and of itself meaning that it depends on how complex your application context is but there is another feature of spring cloud function specifically but not sprinklered function but rather spring core is the functional Beanery registration which is kind of out of scope for this presentation but in other words you can there are ways to if you need to improve initialization time application context for whatever reason then write a function will be no registration that's the feature of spring yeah right so but I mean again the question on the faster like what is fast what is not like how much is fast yes well that's close to the question I would say so first of all this function is a bean right so the registry itself in this particular cases application context bean factory right and the question I was kind of leading to so Kay if the bean factory has a beam of type uppercase can I just simply do this can I do this why not it's a beam do you think it will work let's try and of course it's gonna work right so why don't you thunk ssin catalog then well because I'm giving you the simplest of cases right there's really nothing for this specific function for the way I'm invoking it there is nothing absolutely that the function catalog will do for me here right but it provides that uniformity right but we're gonna get in a I'm gonna get into the type conversion case and that's where things become a little more interesting so let's well before we get there let's introduce another function public funk funk okay so and again try to look it up by default name so to speak I got null pointer exception when I try to see a function apply because what this had returned null and if I look at the message here it says looking a function with except found more than one function being factory upper case in hello if you did not intend to use function ignore this message but if you did this is something one of the issue we kind of discovered yesterday because we try to use this as a feature but sometimes when you have a complex project configuration you may have some beam that is of type function you never intended to use it but anyway or some beans of that function so at this point of time prior to let's say yesterday we were throw exception but right now we just ignores it so that's what you call presentation driven development huh Stack Overflow during development yes all right anyway so now at this point of time I'll be basically so basically what I have right now I have multiple functions and now I have a tie which means I have to break it so now I have to explicitly specify whether I want to do the echo or upper case right but again as you can see at this point of time we're only dealing with the simple functions and you could technically get it as a beam from the function catalog but let's start getting into the weeds streaming functions we didn't talk much about them yesterday but reactor which is being talked on in the next room reactive is a big thing right now not necessarily because a new cool toy but rather because it allows you to it may be complex to grasp at the beginning but it allows you to solve certain use cases that would be very hard to do with imperative style programming right so like for example yesterday trying to find a good function okay let's just get into the aggregator so aggregator is a function and again like yesterday I already have like let's say you know let me step back for a second one of the benefit of function that I did not mention again is the because they're pure Java functions doesn't require anything it gives you the interesting way of distributing your teams I mean yes the work with sprinkler stream functions and spring portfolio you have to be familiar you have to be knowledgeable you have to be experienced with it right but to write a function all you need to know is Java true so in other words you within the organization you may have an army of junior developers who say listen maybe it's going to be a long road for them to learn some of these new technologies but at least for the time being they can get their feet wet by writing functions that will be then shipped to you and you can include that package in the jar file you can include it in the class path and and you can start using them but when you're configuring your application so it's almost like you have roles where you have a developer of the function then you have application developer that will configure will create an application using the functions that would deploy developed by other developers so in this case I kind of emulated that so I have another project which isn't on this class path and this project provides a static class called function Lib and this function Lib defines some of the complex functions that I'm going to be using today so in this case I can define function like I did here inline or I can basically say here's my bean of type of this type which is blocks integer blocks integer and instead of just implementing it here I just say will give me that one okay we can do new class whatever so it's called aggregator so I'm gonna so I'm going to do the and so now I'm gonna invoke it and I have a method here that will generate where is it already go Oh generate flux a long comment is so this method will basically keep providing keep incrementing an integer and so on continuously never ends so provides me with a stream but let's look at for a second what this aggregator actually does what they will do and this is what gets in the complexity and this is important again because again you have a very complex problem here you're trying to say I want to receive a bunch of different events I want to accumulate them in this particular case in a five-second intervals and then I want to perform some kind of evaluation on them in this particular case I'm only filtering the even numbers throwing away the odd numbers and then I'm reducing it combining all the numbers that are counting all the numbers and so on and so forth so again trivial use case but hopefully demonstrates the complexity of the problems and you can only imagine what you can do with that right so and in this particular case while I'm invoking the function I'm passing the stream not individual elements not individual data so okay so let's execute this well aggregate all right well sometimes I like to look at the errors too and that they help you actually it's like one of the spring thing like a special in spring core and we kind of got infected birds in spring integration I'm trying to mimic let in sprinklers function with these explicit messages that tell you what's wrong and how you can fix it and so on so anyway so let's run it I have a little system that are the print lines so we're going to be seeing some numbers on it on so the message the integers are going to be produced every 200 milliseconds right but we should see the output every 5 seconds buffering buffering buffering buffering demo gods all right oh the process terminated it's a it's a very common reactive mistake flux reactive is a synchronous so my problem just exited so the old Java trick alright now we're going to block there and around 2:00 I love when the audience I didn't purpose I'll be like Trump always right no no no sorry sorry sorry sorry sorry why is it like when you're on stage you doing this bonehead mistakes okay through the Chari there we go so and hopefully the numbers that are going to come up are going to be all even numbers because we're only adding even numbers so so all of a sudden here's an example of a complex function so now you see complex' function so this function is a flux function the previous function was just the pure imperative function right but what if we do this right and this is where I started getting into the value of the function catalog and I'll explain to you in a second why this is important so let's change this function we know that upper case is flat string string right I'm sorry function string string it's an imperative function right but what if I do this do you think there's going to work the answer is it will work so in other words you have imperative functions but you can invoke it as a reactive now okay cool why is this important well variety of reasons so let's do this so now you saw the the part of the function catalog all right so we have uppercase and I have this I also have this upper reactive uppercase which is the equivalent version of the uppercase but in the reactive version right so the reason why this is important is the ability to invoke nonreactive function as a reactive function because let's look at this one I'm gonna do the reactive uppercase which is by this time already a reactive function so this one will obviously work okay but now we're getting into the cool part I'm gonna say combine it with the echo function right so now I use the pipe symbol to compose two functions together so again look at this as more overcome two complex problems I mean one complex problem cross the port so I implemented tested and package two of them independently now I brought them together into basically one sort of a synthetic function right so let's run it and now we got both echo and hello and if I decide to do the opposite echo and then hello that will work as well so in other words it's very easy for us to look at the imperative function as a reactive function and in fact the previous version of print log function would always convert everything to react your reaction was mortal canonical model but we quickly realize and that in other applications and other systems that are using spring and spring load function it's not always the friendliest way to interact so we said listen if the function is imperative you should always be forget imperative if you should always be able to interact with function as is as well as these additional features right so any questions so far yes we're getting there so the question is about multi-input multi-output so we are getting there there is demo coming up like in five minutes any other questions yes type safety hmm trying to interpret the question um yeah yeah I mean if so okay all right let me do let me kind of deviate a little bit and hope we'll debt will answer your question so so here's the class I'm going to uncomment it is a person right okay so and now I have a function or is it so here's a function that I'm going to use as you can see the function signature is now this is another simple string string the function takes a domain object so it's called uppercase person so let's go back to the simple world and I'm going to say when I look up uppercase person okay and what do you expect it happen let's see if I try to invoke it like well nothing chick the geyser so we got an exception let's look at what the exception is right so it says basically clear to me that it's a message conversion exception well it's not just clear it immediately clear to everybody right because again our opinion that when people communicate power models right they send JSON right again not requirement but that's our opinion which means our default content-type right now when it comes to tag conversion is application JSON what just happened is that I've sent a string to a function but now it's a Repton through function catalog right so which means there's those additional features the the during the invocation it sees that the type the input type of the function is person what I have here is string all right let's see if I can convert it and it goes through the registered message converters based on the content type known at the time and at the time since I did not provide anything it says its application Jason it applies application JSON message converter and at this point of time it bombs out right okay now if you say that if you have some kind of way of converting this to a person you can register your own message converter with the bean factory and say and provide applicator through application properties or by sending a message with a content type header say food bar I mean foo slash bar that's gonna be my content type and at that point of time if you implement that message converter that is recognizes this content type it's gonna and this this particular code will work so message conversion I don't want to say it's an extension point of spring clause function because it's an extension point of spring Clause spring spring yeah so our spring messaging so anyway yeah I do what's in the classpath oh you mean which message converters well the classpath is the class well this particular project is not a cleanest project enabled it's a demo from the yesterday and everything but I mean there is things there and plus all the j-unit stuff so it looks like a lot but yeah messaging well that message convertor is the one that brings Jackson so in other words if you decide to implement a different message convertor that JSON message camera that does JSON or whatever then you can use so in other words yes we provide that by default you're right but I know you want to change that so I know and I'm considering you say Juicin is faster is that the thing anyway so let's I have I kind of anticipated that this gonna come up one way or the other so so let's send this okay again I'm still sending a string but what does my string look like right now something that message converter can probably understand right say if I try to execute it right now right so go back to your question because I kind of whoa yeah yes but okay now so now with this here's what's happening I don't care about having compatibility because it's either for me to care about typing compatibility and at that point of time I have to say that your functions have to be that compatible when you compose them or because of this message conversion feature because of the type conversion feature I'm saying I really don't care about type compatibility because even when you compose functions right let's say I do this echo doesn't care what type of string you're going to send right so it's gonna output the same string right but this guy does but in this point of time is going to say I'm receiving a string as a part of the composition right and yeah right yeah it is a trade-off so in other words the trade-off is either I'm going to disallow typing compatibility what I'm going to delegate it to the wrong time now the benefit of this trade-off is you probably discovered these exceptions not at runtime but at the development time which is still at runtime but during the development and you will register the appropriate message converter so by the time it gets to production the possibility of this type of error occurring still possible but not probable okay questions alright alright poacher Fashion Week we'll talk about the poacher function so let's look at this guy so we have my function that's a class so as you can see does it is it a function well not in a literal sense but it is right because it resembles the function has a single public method takes something produces something so it could just as well be a function and you only do just change this method to apply right but I don't have to I can keep it sort of like a domain-specific and so on so now I'm gonna have where is it well I just do it so I'm gonna say public my function my function return new my function and now I'm gonna say that it's a bean okay and I'm gonna do look up on what does it do just that goes okay but here's the thing look how I'm retrieving it you may implement it as a poacher but within a framework to me it's a function so and we got everything working right and I can still combine it with okay basically compose it so that's another sort of a really cool feature of yes city you know a being a figuration for my function is right here it's basically have a class somewhere you just say return new my function it's a bean yes yeah I I mean if it's if they're not private not hidden and why shouldn't it I mean yeah house how can spring spring color function know that this should be looked at as a function well no but that's a great question so let's kind of try to solve this problem together so how can we determine that this is a function we introspect it right and we're basically saying does it really look like a function in other words a function supply our consumer they have certain characteristics right when you say it functional interface like in Java notation it's it it's it's pretty strict it tells you how it's supposed to be right so we're basically saying you said you have a beam and you're trying to retrieve it as a function all right well I'm gonna say okay well does this beam has a method that kind of looks like a function and that to me basically saying listen does it have a method that has a single input parameter and a single output parameter well return of it return value right if it does I'm going to say that looks like a function but if let's say I define was let's try it man what happened well because this is really not a functional interface anymore because it doesn't look at the contract that function provides you I mean if defines it basically says that it basically says one public method one input return value that's it right at least in this case it's a known name in my particular case I had a single class that had one public method so I was able to say a cable I can treat this as a function it is not a function but I can treat this as a function and function catalog provides the wrapper just like for the type conversion and everything else to treat this as a function because internally I invoke it to be a reflection anyway so yeah if it that here's to the functional interface but in my current situation it does not because it has to public method which means I have to say which one do you want I have a tie just like when I had two functions to be in function two functional being so look at the exception message says discovered to a method that would qualify as functional and it tells you which method I discovered so again exception message kind of tells you what just happened if I change the second I don't know let's try actually didn't try we've got a test case for that all right well something to work on good question yes I'm not sure and we passing all we're getting there we get it okay I know this is just my implementation I put everything in it it's it it's a demo friendly function it could be a class somewhere I just didn't want to jump from one package to another okay so I guess we're gonna straight into the multi-input multi-output all right so multi-input multi-output now we just introduced this feature into sprinkler function and why why we introduced it because primarily from the community was especially on a streaming side of the community we were getting requests where people want to be able to either merge certain streams you know multiple menu to one or a typical Big Data use case one-to-many reading from the bucket full of data and you want to say orders go here accounts go there and so on and so forth so let's look at one of those types of use cases so here's the that second case where single input multiple output so here's the function that takes I'm going to use the same integer generator here's the function that takes a stream of integers and will output two streams of integers even and odd a very sort of a classic demo now how do we know how do we communicate multiple inputs and multiple outputs we had a lot of debates on how to do that right and there's still a lot of work in progress but what we kind of agreed on is to have this canonical representation of multiple inputs and multiple outputs now unfortunately Java doesn't do a very good job in giving you a collection type classes that allow you to know both cardinality and type okay for example CUDA communicate multiple inputs as a time collection or array of course I can but how do I know when I introspect the function the signature right how do I know how many inputs you're actually going to have and that's fine maybe in a specific case or sprinklered function it doesn't really matter but for those of you who were in a spring cloud stream presentation should understand it really matters to me there because my bindings are triggered by knowing how many inputs or how many outputs I have if I can have that information I can't use your function right and if but even if I let's say good use collection or array and say ok that problem is solve at leas right that still doesn't solve the other problem which is the type how can you communicate multiple types through a collection you can't right so in Java I personally never had this thing called tuples right but since we already committed very early to project reactor it's a dependency of spring odd function core so we kind of stuck with it right and obviously since we have a huge investment in project reactor project reactor provides us with tuples up to tuple 8 okay so if you have a requirement for more than eight inputs or outputs I'm gonna kill story for you but thank you so but I mean honestly in all fairness I mean if you do have a requirement for more than eight I would love to hear that because that's gotta be something extremely extremely complex so anyway so so we decided to use tuples and 2po salami so if you look at here I can clearly want to introspect the function I have utility class for that but when I introspect this function I can say I clearly see that this function has two outputs and the types of these outputs are string and string right so I have that information extractable from reading the function signature now does it mean that you have to use tuples not necessarily at this point at the time of me talking yes because that's the only way we expose it but step on to lose one of our cuddling guys open an issue and we're already sort of a halfway there with the poacher functions and and few other things in the buy function where we will support different programming model and again the poacher function that you saw today is kind of a signal in that direction in other words if we come up with a different way of communicating multiple-input multiple-output function okay then we can use it but what's interesting is that the internal model is going to remain the reactive tuples why because like in other words whatever you define let's say there's another way of doing it right but we internally going to convert it through this function catalog procedure to tuples because I don't want to write different invocation models for each of different types of functions so it's like bring everything to the canonical but give you flexibility to the as a user but internally I'm going to bring everything as this right but again if you sew another one of the area we're looking at is the carriage function which is let's say function that takes let's say flux string and returns function that takes flux string that returns function it takes one string so now actually tomorrow we're gonna be talking about kafka streams and we saw B is going to be showing you that I can't convince myself that this is readable especially if you get beyond two inputs or two outputs right so will we support it probably yes but for example depending on which type who you talk in a community for some people who's been living the functional world for the person you know five six years oh yeah that's simple for someone like myself I'm like no it's not so but the bottom line is that we will provide that support to kind of satisfy both sides of the community but for now we kind of request and kindly embrace those tuples and again it kind of gives this linear away so I mean at least from readability perspective it's very readable and like I said as long as you know and we know that it's always going to be in the classpath it's not too much to ask anyway I hope I can be instrument if I didn't sorry so so and here's my function so let's not worry what it does here with project reactor because it's irrelevant right it's just an implementation details remember that the developer who writes the function he has to he or she has to worry about this me in sprinkler function I only have to worry about signature if you made a mistake there if there's a bug inside of you implementation well you'll deal with that not me okay so that's kind of I mean I'm not joking this is sort of a separation of concerns so I care about only this part because that gives me all the information I need to know how to properly invoke this function people so in this function basically what is going to do just too quickly it's going to start receiving the stream that I'm providing and then it's going to start looking into the stream and say I'm going to produce two new streams and put even numbers here and odd numbers there and output and and basically give you back two streams now in the pure functional world it may not be the most interesting thing to do but for those of you who were at Spring Club stream presentation yesterday and I'm going to publish the demos next week and I will write a blog and everything you understand that these streams that were produced were immediately bound to destinations and put on and and the the the data was put on the queue so as soon as I started the project it bound to an input queue it created two output queues and data start getting there right and all you had is just a function and if time allows with but unlikely we can do this demo again so all right multiple input multiple output so let's see how it's going to work okay so the name of the function will be router right yeah it's a router and again I call the router because it receives single thing and then routes to different streams to data okay so I'm gonna where's my router imagine the amount of cut and pasting I would have to do if it was carries function okay catalog look up now it will require a little bit of a setup so let's just I have it stashed here all right let's quickly review what we're doing here so we looked up the function in catalog the type of the function is flux integer and then tuple to flux integer flux integer right so single stream in single stream out and then we're basically applying the generated flux that generator that's going to generate integer every two seconds to two milliseconds and then we're going to have two streams we're going to subscribe and just log the output to the console okay and here got two single input multiple output does that answer your question good and the same goes the opposite direction so there are test cases if you go into spring close function context sprinkler function context module of spring close function basically start looking there is a test case test cases that multi basically everything that starts with the multi there is tons of test cases for multiple inputs multiple outputs and combination of both questions yes again every I'm gonna like have this saw every time of somebody asked performance questions it's really almost impossible to answer on the surface because there's so many ways I mean so many things that could influence your performance I need to know your hardware need to know yourself I need to know so many things to be able to even begin to solve the performance problem but most importantly I need to know what the SLA is first because without knowing where you want to be I don't know whether it's fast or slow well project reactor when it does reactor processing and this is kind of again outside of scope of this presentation depending on what the type of reactor stream you build and that's again that's the implementation of the function itself depending on how you build the stream yes of course multi-threading could be involved right but then again this is not something we control what I can tell you is that there are no threads from me invoking the function and anywhere inside of the sprinkle out function of function catalog in other words there's no we don't create any new threads but your user code can and giving the project a synchronous nature of the project reactor depending on what your pipeline looks like there could be additional threads created okay okay all right so we touch on the function arity oh there's another cool thing I can show you in the surrealist platforms there was again Socceroo flow driven development that turned into github issue they turn into a function routing function so the complaint was that all great we can do these things but every time I need to be able to map this function or this function or this function it's a process to go through the UI to map and remap and this initialism so the question was can we have a single function that we're always going to map to and that function acts as a delegate so it's not the router that I have right now it's kind of the inverse where I have a function already part of the function catalog always there and all all it does it's going to determine based on information that you provided what you really want to do like you didn't really want to talk to me you tell me who you want to talk to another connection to the person right so routing functions responsibility is to tell to delegate you to an actual function you want to talk to okay so again as I said routing function is always there it's available to you so and you can look it up by simply doing this okay so you can look up routing function and let's execute exactly the same code this multi-input multi-output and see what's going to happen you got exception all right so writing function doesn't really no it should work because I'll yeah it says it's a bug it should work so I'm making myself a note to look into that later but let's get into something more simple okay I still expect exception but a different one alright exception again this this so by the previous pond Dave should work too because it should have just told me that it shouldn't attempt to interpret the input rather say listen I can't determine what do you want to do so the Madeira message says failed to establish route since neither were provided sprinkle our function definition as message header or as application property right basically I just invoke spring invoked routing functions but I didn't tell you what I really want to talk to it okay and again let's just follow the directions of the error message I'm going to copy this property I'm going to and I'm going to say uppercase that's really what I want to talk to right so now it works right so what I haven't touched on yes questions some just raise our no okay em all right there is a list of things okay so now this is static right this is one per spring good application not a very convenient way to route function right so let's take it one step further and again the same upper case but I'm gonna do it like this okay so obviously I have to provide the message but right now I'm gonna say builder dot with payload hello set header I'm sorry not cut the time what am i doing Jesus Christ yeah quickly for those of you who may have used sprinkler function before we have we used to have the property called function that name it still exists it's going to delegate it's going to turn there's a environment post processor that will turn it into function definition the real reason is the definition is more representative of what we're really doing because right now when you're building a single function ok function name but if you're doing function pipe function by function you're actually defining a function so it kind of makes more sense so and again also because sprinkler function just kind of brings that uniformity that we use across multiple cloud projects so just a quick note all right so ok no oh this is one thing I wish people would standardize on the Builder API some people have built everyone have get so apply quickly on a message so I'm not really sending the message somewhere whatever like I said yesterday message is just a structure that allows me to not only communicate the actual payload but some meta information so and internally we look inside and say listen if it's a message good we're going to try to see if we can pull some other data if it's a poacher it's a poacher but again I'm sending a message my uppercase is a string again that conversion we're going to say you're sending me a message I have a string I'm going to say okay well you and that that's a convention that actually driven from spring integration from wild wild back we're going to say okay well if you have a poacher as an input parameter declared and you come in as a message we're going to assume it's a payload so we're gonna extract the payload compare the types if types are compatible we're going to invoke if not we're going to convert and then invoke and that's it so but in this case I am becoming more dynamic because I'm providing this function property on the pyramid search basis which means on a second message or subsequent message I can provide call a different function or specify a different function and we're still working right so no not alternative yeah so and the other thing is that if we go back to the error message I'm forcing the error message because I forgot the exact name with the property I want to cut and paste when you have messages or not doesn't really matter you have we have this thing called spell spring expression language which just a code snippets that you can execute and as long as this so there's a property called sprinkler function routing expression as long as it returned basically it returns a string value it should return a string value and a string value should correspond to a function name that you want to take in the book so basically I can change this and without getting into the complex expressions all I have to do is provide this property wrap upper case and the proper valid expression literal expression and but again for those of you who familiar with spell you can the sky's the limit you can include a very complex spell as long as it relates to something that is a function within function catalog everything will work and again it's very important it's like a lot of these requirements are driven by the frameworks that you sprinkle odd function so streaming use case was one of them alright guys I have like six minutes left so I'm going to show you one other feature of spring close function which I believe is extremely valuable and again I those demos are a bit more simpler because they're a preset so function deployment is something I did not show yesterday because it was outside of scope of sprinkle out stream but it is kind of relevant to understand how you can interact with sprinkler function and what value what additional value it brings to you so let's say you already saw how you can implement classes beans and so on and so forth but let's say you have a package a jar or exploded archive package and that package has a function notice how I'm not saying providing you with any details of what does it mean has a function because we support variety of different paradigms it could be just a class function and you can point to a class it could be a full-blown spring boot configuration it could be full-blown spring configuration non boot it could be some other configuration in other words if we can extract your function based on limited Directors from you and load it into our function catalog so basically in you have a package which will start will identify a separate class loader so there's no tight collusion and whatever so you can have the entire application with its own class path and everything and it contains the function and we're going to load this function to our function catalog properly handle the class loader issues and invoke this function so let's look at some of these examples so again for more you can look at the spring Club function deployer module and but I have a bunch of different applications here for variety of different test cases so the first I'm going to look at is deploying class this is the simplest scenario you have non spring non function nothing you just simply have an application to do to do it's called deploy class so simple as your so where is it okay here we go so I'll show you the code real quick this is it that's the entire jar right no spring nothing okay so what I'm doing here is it's already packaged in the jar I did it before the presentation I'm simply specifying spring cloth function location property and sprinkle of function function class property okay and I'm gonna run it and it's upper casing hello okay and the other level of extreme is a full-blown boot app which where are we so deploy boot app let's look at this one so deploy Buddha app notice how we do not specify location I mean which we specify location but we don't specify function class because at this point of time in this particular boot app there's a spring configuration functions are going to be loaded into spring application context however it may or may not have its own function catalog but remember that function catalog where that application will sit in a different class lower so we cannot really cast that catalog to our crop function catalog but we can extract the function and load it remember how I told you about function registration I can pull the function out loaded into the function catalog and again I may be giving you more details because the bottom line is that there is an application somewhere over there that's been deployed and deploy I recognize it pull the function and allow you to use that function as it was as if it was a local function so I mean the function is the same upper case but let's boot up let's look at what's going on here so as a per case function but as you can see in this particular case as a full-blown spring boot configuration and it has a function declared as a bean and in my demo I'm doing the same thing just saying here's a location and then remember I'm still doing function catalog get bean function catalog lookup function and again this is again another beauty of sprinkler function not even spring cloth function because whatever is there remember there is aside from two class loaders between a diploid jar and local deployment there is still the same JVM which means certain classes are still shared and that's where the true value of having functions as Java strategies really resonates because I may not be able to cast it to exactly the function implementation that you have there because of the class loader differences but I can always cast it to a function and invoke it as such okay so let's run it and that's it and I have seven six five four three two guys thank you very much I hope you enjoyed it I'll be hanging out there and [Applause] you
Info
Channel: SpringDeveloper
Views: 8,924
Rating: 4.8558559 out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud
Id: 2beLo7nWeoo
Channel Id: undefined
Length: 70min 2sec (4202 seconds)
Published: Wed Oct 16 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.