Transporting Data at Warp Speed: How to Connect Spring Boot Apps Quickly, Powerfully, and Painlessly

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right welcome back everyone i hope you enjoyed the previous talk um up next we have my good friend mark heckler talking about how to connect all your spring boot apps using a variety of different technologies mark is a is a a great developer advocate uh great speaker so stick around for this talk and uh if you have any uh questions about coffee i'm sure he'll be happy to answer them as well uh i'll take it away mark thanks so much and and uh ryan i want everyone to know i did not pay ryan to say all those nice things uh he's just that nice a person and a great human being so you know i'll take that up with him later but uh thanks so much for coming and thanks for joining me today let me go ahead and share so we can get started right away because they tell me i only have like three hours today so that's that's kind of rushed uh so we'll just have to zoom through this i'm kidding we only have like 55 minutes and then a little bit of q a time so let's make the most of it uh and and just great stuff to share today uh i'll be talking about well talking about a little bit but coding primarily uh and discussing how to transport data at warp speed or as i like to say how to connect your spring boot apps quickly powerfully and painlessly because it really can be truly painless as ryan mentioned mark heckler i'm a principal cloud advocate of java and jvm languages at microsoft uh and we'll get into more of the details about me later briefly because we want to save most of the time for the actual good stuff and not me but if you do think of something after the fact that you want to uh comment or share or ask me about that always happens to me two ten minutes after i leave a session i think of the best question or the the comment that i wanted to share that's perfectly fine if you can't catch q a if you forget it don't think about it until after q a by all means please do reach out to me at mark heckler at microsoft.com or better yet on twitter at mk heck because i do check email somewhat regularly but i'm on twitter pretty much all the time so by the way if you do have any questions comments or feedback that you don't want to blast out to the entire world my dms are open so just follow send a dm and i'll i'll catch it as soon as i pop back on there in about three minutes anyway so a bit about me and a very small bit uh i as i mentioned i'm a principal cloud advocate with uh with microsoft i'm an architect and developer by by trade by history i guess you'd say i've also co-authored a couple of books and solo authored the book you're seeing down below i'm really proud of that because it's a spring boot is a great uh great i guess framework uh library ecosystem as a whole you know spring and spring boot and all the various different spring projects and i'm just really uh thrilled to have gotten to write a book about it that i felt like maybe you know helped flesh out some of the information about it so if you want to check it out it's all codes in java and kotlin so yeah join in join in the fun i am also a java champion java 1 rockstar kotlin developer expert groundbreaker ambassador a few other nice honors and awards which i do truly appreciate but still mean i have to get my own coffee so i don't i don't know who i need to see about that but you know here we are uh as far as what i do in my off time the three minutes a day i have off uh kidding but but what i do in my off time to kind of take my brain in a different direction is i am a licensed pilot uh very happy about that because it does does exercise your your mental and physical capabilities in different ways right so yeah i go flying whenever i can uh and uh yeah so it's a lot of fun and you'll see that actually kind of creep into the to the use cases we're gonna discuss and encode today so the plan for today i love this quote by leonard bernstein the the great conductor of the new york phil uh as he once said to achieve great things two things are needed a plan and not quite enough time and and this goes back to the 55 minutes thing so you know we've got a plan and we got not quite enough time so we'll see what we can go with it um so just as a high level here are kind of the things that i want to cover to some degree we're going to start off with http based interactions and we'll not spend a lot of time on those because i think it's kind of table stakes in most cases we've already all had some level of interaction with http based interactions but if not that's fine it's it's not you it's me i'm just assuming that is a foundation upon which to build and i will touch on it briefly if you're coming in very very new to the ecosystem that's perfectly fine happy again to talk about this at length another time and if i skip over something that you need a little more fleshing out that's that's okay we're all at different stages and different uh different tools and and technology so so that's fine uh but we're gonna go from there into reactive streams using project reactor and we're talking we're going to be building some apis using reactive streams then we're going to go and step on into our socket which builds on reactor we're going to be using tcp and websocket discussing some other options you have at your disposal as well and then we're going to talk shift gears a little bit and talk about messaging because messaging is another way that you can pass past information among various different spring boot based applications so we'll be using one of my favorite favorite favorite options which is spring cloud stream and then i'll be using that with rabbit and q initially and then we'll be switching over to azure event hubs using the kafka api to kind of give some variety and show you some different ways of doing things but spring cloud stream makes that super easy and simple and powerful for you with your spring boot applications then we'll summarize i'll show you the repo links and what have you so from there really all that's left to do is code so we've we've spent less than four minutes and we're off to code so that's a good that's an auspicious start so we'll go there all right everyone still good good okay so so we're going to start our journey here and i'm actually going to expand that a little bit because it looks a little small there on the screen so maybe that'll help uh yeah so this you probably might recognize this by now this is a spring initializer whether you go here to start building your spring boot based applications or whether you go take another route that's perfectly fine i like the initializer because it gives some really neat capabilities primary among them is if you want to explore your project it will actually let you sift through your project that it's creating on your behalf and check out your dependencies and whatnot before you actually download the zip file unzip it and get started now the spring initializers we probably all know doesn't generate code for you other than the main application classmate method but what it does do is it creates helps you create based on your specifications the project so we're going to specify a few things for our project and get started and i'm going to i guess let me let me back up just a little bit and give you the domain we're going to be using today as ryan knows i love coffee and as you pointed out but as you also all know uh by now if you didn't before i also love flying and and i used to do a lot of demos with coffee and and you know some people are loving it because some people love coffee and some people inexplicably don't love coffee but but i thought you know it would be really nice to maybe shift gears a little bit and maybe show something with actual live data feeding in so i actually have a device here in my my home office that will it has rather large antenna outside the house actually that pulls in uh aircraft flight information as aircraft or in flight here in the us they have a thing called adsb automatic dependent surveillance broadcast output and that adsb out will send information position information uh of a plane when it gets in my area i can see that and there are ways to mask that and whatnot but generally speaking at least location information is provided because that way controllers and people that in the flight centers can see airplanes and make sure they maintain separation between them which is generally perceived as a very good thing right you don't want two planes trying to inhabit the same space at the same time so i actually can pull in this data and i built an application that creates an api it's a very simple api that pulls and shares aircraft via http at http endpoint called aircraft and that shares it via our socket endpoint called ac stream and i won't go too much further into that it's not necessary for the point of today's information but i do want to show some of the data that comes in so you have a call sign for the aircraft a swap code which is a transponder code the unique transponder code that's assigned to an aircraft for that particular flight or portion of that flight an aircraft registration number the flight number itself and that's usually for commercial flights like american airlines united delta what have you uh the route that that flight is taking dallas to to houston to chicago to jfk in new york or what have you uh you have the type of aircraft the category of aircraft you have altitude heading and air speed uh the vertical rate so whether it's climbing and descending and by how much this the selected altitude the target altitude perhaps a flight is targeted for 39 000 feet but it's just taken off so it's only at 3 500 feet at this point in time and by the way in u.s it's altitude and feet uh parametric pressure and inches of mercury um and and distances in in statute miles and nautical miles for speed but it is what it is right uh so we have our position report the latitude and longitude and and more stuff that we really don't necessarily care about but but it is all there so i'm going to be skinning this down i'm going to go ahead and close this out because what i did in order to kind of maximize resource capabilities is i created a spring native application exposing this endpoint for us to use and as you can tell though the startup time is just terrible it's it's .277 seconds just horrible right uh so i have it running in a in a container container and everything's happily moving along and it's just waiting for us to query it and use that that api which we we should get started doing right so i'm going to be creating multiple applications multiple spring boot applications just to kind of show how they can communicate and pass data around between them at at just excellent performance just as we say transporting data at warp speed so i'm going to keep this is as simple and and generic as i can so as far as the construct so i can focus on the things that i really want to focus on today because again we only have a short time together unlimited time afterwards so again if you have questions comments or feedback ping me afterward but but our time together here is short so i'm going to create a maven project using java or java project using maven uh but you know choose uh feel free to choose whatever language and build project build system you'd prefer i'm just going to again keep it simple so today version of boot which is the current version is 2.5.4 i'm going to just change the group to the hecklers.com hecklers.com because why not that's my domain and rather than create a client and a server and another service i'm just going to call these uh these various services thing one thing two and thing three i don't know if anyone remembers their childhood fondly with the dr seuss books and all that uh but there was one uh children's book that had thing one and thing two and they were just couple a couple of characters who always seem to be getting into mischief and hopefully our applications today won't get into mischief but you know we're gonna create thing one thing two i'm gonna create thing three because i think dr seuss showed us an appalling lack of vision and didn't continue to build out things so yeah we're going to go with that i'm going to use jar for the packaging because after all why wouldn't you and i'm going to use a current lts version for a little bit longer of java which is java 11 but again use what makes you happy i'm going to just choose a few dependencies here so i'm going to bring in the reactive web dependency and r socket if i can type our socket that's not a great start right and lombok because i'm a lazy developer lazy good not lazy bad i don't like to write a lot of boilerplate that's one of the things that most people including me love about spring you don't have to write all that boilerplate and lombok actually helps you with your your data classes and things like that you're logging so we'll go with that we'll start off with that i'm just going to generate the project and we'll drop that onto the desktop and i'll call that thing one and i'm just going to go ahead in the interest of time create thing two and thing three i'm going to add a couple of dependencies to to thing two and thing three uh so we have cloud stream this is spring cloud stream and it even tells you when you're selecting the dependencies that uh that hey you know this is the framework for building highly scalable event driven microservices connected with shared messaging systems however they require a binder spring cloud stream requires a binder such as kafka or evident queue solus pub sub plus event hubs what have you so we're going to choose that but it's telling us right up front that you know our work here is not done we actually need to add some kind of a binder and i'm going to start off with rabbit and cue and that will get us uh you know a good start so we'll we'll do that i'm going to save thing two and then i'm going to also just change this to uh thing three so i'll generate and you know what i think that just dropped that in the wrong spot it did so we'll just go back and we'll change uh thing two there we go that way we just keep all of our things in one place so i'm going to show in finder and move that over so we can see that and there we have our desktop and i'm just going to unzip thing one thing one project oh come on there we go all right and we'll open that in our favorite ide netbeans kidding nothing against netbeans nothing against any other id you know eclipse and and intellij and vs code and adam all of them are great i typically use intellij as my daily driver but you know again use what makes you happy uh use vim if you want just please don't use emacs have some self-respect okay so uh we'll start off here and i'm going to open up my palm uh yeah everything looks good right this is exactly what we expected to see so that's off to off to a great start and i'm going to open my application properties now i'm going to be running this you know what before i get into building out thing one oh let's just build thing one why not so i'm going to start off with a defining a server port for my project and as you can see spring boot defaults to a server port of 8080. now since we're going to be creating multiple spring boot applications we don't want them all to try to seize that default port that would be awkward so we're going to just redefine this to server port 90 90. so we don't have any port conflicts we don't like port conflicts and i don't know why intellij is is doing this uh once in a while i i think because i i know the folks at jetbrains and i think they're just giving me grief it's it's probably the mark special mark edition uh but for some reason sometimes it doesn't find certain java language constructs like you know string there we go okay so we're good i'm going to just create a a lombok data class which is similar to a kotlin data class or a record or things like that if you're familiar with those i'm going to call this aircraft cleverly enough and i'm going to create some fields here so our call sign registration number we'll just shorten it to reg flight number and type and those are the things that we care about or some things that we care about in terms of an aircraft position report i also am very interested in determining or finding out the the aircraft's altitude heading and speed and then we probably by all means want to get the position of the aircraft itself so lat and lawn it is and then i'm going to just set this to jason into our property so we can ignore anything that we don't uh recognize now to kick things off again i'm going to keep this very simple i'm going to start off just by creating a web client bean so we can um so we can access our backend plane finder service that provides us our data feed so i'm going to return a client dot create we're going to point to http colon slash local host 7634 is where i have it running actually 7634 and then i'm going to create a rest controller here and we'll call this our thing three now thing one right am i in thing one i'm in thing one good i get going so fast sometimes i just jump ahead a couple steps and that usually doesn't end well so we'll start with this and i'm going to define a get mapping and we'll return um let's start off let's start off real how much time do we have not a lot of time so we'll we'll kind of jump straight into this and i mentioned that we have the ability to return uh return normal constructs and i guess i let me back up a little bit from the for the outline in an http based api typically you will return a thing an object of type t uh typically you know via json sometimes xml you know there there's some holdouts uh but you'll return a thing and even taking it a step down let's just go down to the to the method level itself when you return a value from a method typically you return an object of type t what happens if you need more than one right if you have some kind of a a number of those objects well typically you typically you return an iterable of type t so a small number of of things or maybe a lot of things maybe it's just a huge number of things 500 5000 of those things um but it's it's typically within a blocking api and when you're returning one or eight or 30 things that's not necessarily a big deal when you return several hundred or thousands of things that can be a very big deal if you're having to block and wait for that to come back before anything is returned the reactive streams initiative kind of tackled that because a lot of the issues in terms of inter-application communication uh are are because of the because the communication the sticking of the communication so if an application requests something from another service and has to wait and wait and wait and just block until it gets that response it's not terribly efficient in terms of resources the reactive streams initiative uh recognizes that that the biggest hang up is in those interactions so their active shims initiative defined four interfaces uh you have the the the publisher which is the thing that produces values the subscriber which is the thing that consumes those values a subscription which is a contract entered into between a subscriber and a publisher and then you have a processor which actually incorporates both subscriber because it receives values manipulates them in some ways and then acts as a publisher by sending them out to any subscribers to it so with a and of course the reactive streams initiative allowed different implementations verifiable via a technology compatibility kit a tck so that if if i create an implementation and you create an implementation we can use the tck to verify how compliant we are with the underlying specification which is great because then that fosters interoperability and incompatibility so you know there are a few different uh libraries that implement the reactive streams specification project reactor is foremost among them it's used in several open source and commercial offerings uh arguably the leader uh although again very good options out there as well uh but reactor uh specialized the publisher into two different things kind of corresponding with the uh the typical blocking responses that i mentioned earlier so in instead of just a publisher which can return zero to an infinite number of values uh a in reactor speak you have a mono which can return zero or one value no more than one which is parallel to that object of type t if you will uh and then you can have a flux which is a publisher which can return zero to n values and that may be the eight or ten or fifty values or it may be an indefinite an indeterminate number of values over indefinite amount of time you could have a a sporadic publisher that can publish uh once every 30 to 50 seconds for 20 years and that's perfectly valid as is a publisher that produces eight values within eight seconds so we're going to again kind of skip ahead just in the interest of time if we have more time i'll double back and maybe expand on this but what i want to do to start off with is is let's just start with a flux of aircraft we're going to return a flux of aircraft and we'll call this a request uh we'll call this now let's let's let's back up just a little bit no no not that import cell request um response so we're going to just um issue a request get a single item in a single response i'm simplifying this a little bit but again we'll jump forward as we go so i'm going to first inject my web client here so we can use that this is a reactive web client and i'm going to use lombok to just create a constructor which includes a parameter one parameter for each member variable that's an all args constructor so we can use that here so i'm going to return our client.get.retrieve.body to flux because we're going to be querying for all kinds of aircraft from our web client so we're going to be returning uh a flux of type aircraft and then i'm just going to i'm not going to block first because this isn't a blocking api that's how you would go back to an http based api i'm just going to grab the next one and we'll return that so i'm going to start that off and we'll just see what we get actually i need to uh specify here we'll do request response and i'll restart that once it starts oops okay and that was fairly quick so let's uh let's go ahead and restart that yeah 1.4 seconds and i thought i clicked that maybe i did not okay so let's go back here all right so i'm just going to use httpi that's my my favorite http http based tool sort of like curl but for humans and i'm going to point to request response and of course the first time through the pipe it just is oh oops let's see what do they do here always good you can always tell when it's a live demo because things don't work perfectly the first time 404 not found forget oh always helps when you have the correct endpoint specified which i did not so let's try that one more time hopefully with better results that looks a lot happier don't you think okay so we have the call sign here we have the the heading the heading is 252 so it's roughly south to southwest the latitude and longitude the speed is 321 321 knots and it's a cr30j juliet so we have a small business jet here or a small jet that we're is flying along and we've got that position so that's a single request returning a single response i'm going to just show you a little bit more here so we're going to change that to a flux so we'll get back all those aircraft position reports and we'll go ahead and restart that and just i'm just doing this kind of makes making sure that we're getting the data we think we should get from our plane feeder i should or plane finder i should go over and look at that and yes you see we're getting all kinds of data being fed we just filtered out one so let's go ahead and and let's let's try to um let's try to do this here let's see so colon 9090 slash wreck response actually i should change that to for truth in advertising so it's request stream and that becomes important later so we see that we're getting quite a few different aircraft here right that looks pretty good there's an american airlines flight uh it's an airbus 3 a319 and we're off and running so this is a typical um uh well it's a it's a it's a reactor or a reactive streams api that we've built here because we're returning a publisher in this case we're previously returning a mono now we're returning a flux but they're both types of publishers right so let's take this a little bit further and let's get into using our socket now our socket's important because reactive streams apis are great but when you cross the network boundary i guess i should back up and just say one more thing one of the advantages of something like reactive streams versus just asynchronous programming is yes you can get asynchronicity you can get a non-blocking api so that if you have a client that's requesting something it's not just waiting waiting waiting for the resp the providing service to get back with it with its its dump of results what you can do in an asynchronous api of course is you can just say hey give me your results and i'm going to do other stuff until you issue a callback and at that point then i'll process those results which you know has a few problems one is it's not terribly readable it's not great and maintainable i mean callback hell is a term that was coined for a reason but the the biggest or one of the biggest problems is it has no flow control right so asynchronous processing asynchronous interactions probably are okay if you have a few different data points coming back but what happens if you say give me all of your x and there are 3 million x and that providing service dutifully collects them all and then sends them downstream and if you can't process that from the requesting application that requesting application just falls over right so what we want to do is avoid that and the reactive streams initiative actually the reactive stream specification indicates that you can provide back pressure which allows a consuming service to say look i know i can't handle 3 million responses so just give me your first 50 or your first 100 or whatever the number is and once i process those i'll request more and that works okay except we're still basing this on an http underpinning and it's at its most basic level however our socket solves that right because our socket is is transport independent it's it's protocol independent so our socket is built on top of by default things like tcp or websocket aeron is supported i believe grpc is either supported or will be very soon i need to check on that but it gives you a lot of flexibility and power to to propagate that back pressure across the network boundary so that gives you again a lot more flexibility a lot more power so i'm just going to change this to a controller and we're going to implement an r socket api here so when it changes to a controller we're going to change this to message mapping nope message mapping command intellij and there we go and then i'm going to uh let's see uh yeah that's fine but what we're going to do uh typically with a with an r socket interaction is you'll receive some data and you'll send some data back so what i'm going to be doing here is receiving some kind of a value i'm going just to set a mono of type instant because i like a good time stamp i think that is really useful it gives you some information about when the interaction begins and we're going to start off by taking that mono and we'll do on next so we'll grab the mono and we'll take this timestamp and i just like to print this out so we can see what we have i also like clarity especially in demos so i'm going to just stick a clock in there so we can kind of keep things keep things straight in our demo here today and then i'm going to use a then mini operation here on our mono coming in and then mini takes a publisher we just happen to have a publisher here that we've gotten by calling our client and retrieving a flux which is a publisher and there we have it so this is really as as hard as it gets in in terms of supplying uh and creating an r socket um connection or connection capability the other thing that we do need to do is uh we do need to provide this as a way uh we need to enable this to act as an r socket server it's really tough you just take this and you add an r socket server port and we'll say this is 1991 i like to keep things together for simplicity and manageability and that's it because springboot's auto configuration jumps into being at that point because spring boot your spring boot application says look our socket is on the class path you defined a server r socket server port chances are you want to this application act as an r socket server so we'll do that we'll get that started and then i'm going to just shift this over and we're going to open our thing 2 and get started with that so i'm going to open our second project thing 2 and we'll get thing two in there and talking to thing one look at that it even went right where i wanted to go that's good so intellij gives me a hard time sometimes and it really helps me out at others that's why i love it keeps me honest all right so we'll close that we'll go to our palm we'll go to our palm and i was just bragging on it i should have known better uh okay so there we'll go to our application properties i'm going to or i would set the server port to 8080 but as you can see that's the default so i don't really need to do that i'll just close that up and then i'm going to go to my application main application class and let's let's lay down some code so i'm going to once again create our aircraft class and private string call sign reg flight fly no flight number and type of aircraft and then we want our altitude altitude heading and airspeed right speed and we also want our latitude and longitude all right so now i'm going to again keep this pretty simple i'm just going to create a component and we're going to call this class our thing two component naming is hard and i'm going to just create a post construct method so we can just do a request ah we'll do a request stream because we're getting back a stream of data right and of course we need to somehow reach out to our our socket server now i always use these terms with a little hesitation because i'm creating in effect in our socket client here and thing one is both an r socket client reaching out to my plane finder app my data feed and it's an r socket server for other applications but when you're talking r socket client and server are somewhat misnomers because obviously to begin with you need an application to listen for connection requests and that's fine that's great and you have to have other applications which initially act as clients out and say hey i want a connection and that's also great but once that connection is established the difference difference between client and server effectively evaporate right because either can initiate conversations initiate monologues uh they they can they they're effectively peers they're on pure standing so that gives a lot again a lot of flexibility but initially one has to act as a server listing for connection request someone has to actually make those requests so we're going to use this opportunity to create a bean to provide an r socket requester now i'm going to i call this method requester now i do want to say that again this is part of spring boots auto configuration since our socket is on our class path and we want to create an r socket requester beam we're going to be using as part of that auto configuration spring boot says look our socket's on the class path i'm going to inject an r socket requester builder into your application for you to use we're going to use that now to create a tcp connection to local host and the port is six three five why is that seven six three five because here for thing one we said that it would be an r socket server come on you can do it there we go uh oh actually i'm glad i double checked that it's 1991. so this is where we're pointing to to connect to this r socket server now i'm going to in my component use that and i'm going to inject our r socket requester again using lombok to provide my constructor and do constructor injection as you should and we're going to just use that requester just to to see what we can turn up so grab some data so i'm going to point this to oh i need to change this to request stream and then before i restart everything i'm going to well i'll go ahead and and do this because the other thing that i want to do is anytime you have an r socket server when you typically will have clients that will connect and then disconnect and that can result in some kind sometimes a kind of a messy stack trace that shows hey you know something disconnected is everything okay here so what i want to do is just to create a hook here on error dropped i'm going to take the error and i'm not going to really do anything with it i'm just going to say client disconnected goodbye goodbye and that just cleans things up a little bit i'll go ahead and restart this it just makes a little cleaner in our logs who needs to see the stack trace when it's a normal orderly disconnect and i'm going to point now that i've defined a message mapping of request stream or rec stream i'm going to point to that for my route here from my thing to client and i'm going to as i mentioned send data i'm just going to send a timestamp so that i can see when i'm issuing this request and then i'm going to retrieve a flux now this we're saying provides a flux of aircraft or a publisher of an unknown number of aircraft and i'm going to retrieve a flux of type aircraft this is a publisher as i mentioned and with publishers there are two kinds of publishers there are cold publishers which don't do any work until someone subscribed to them and then there are hot publishers which will the neighbors are getting ready there are hot publishers which are constantly producing data the problem with hot publishers sometimes they they actually do have use cases but in most cases if no one's listening all you're doing with a hot publisher is consuming resources so you can consume a lot of resources and nobody's connected no one cares so in most cases you typically think of a publisher and you should consider publishers unless told otherwise and you know if you've discovered otherwise that they are cold publishers that they actually start consuming resources and producing values when the initial subscription is made so we're going to subscribe here and each thing coming back is an aircraft so we're just going to to kick that out here and we're going to print that i like to again just put something in there to make this a little more visible and that way we can see what's going on and let's do that so we're going to go ahead and restart this and we'll see what we get doing well on time we have 20 minutes we've got tons of stuff to cover no problem right okay so we see that we we've actually received in thing one we have our timestamp so we know that we're getting the request coming in and we're seeing here going back a lot of aircraft right so this is good this is exactly what we would expect to see now there are four interaction models in our socket and i've just covered kind of sort of a couple of them the request response and that mirrors an http based interaction where you issue a request you get a response you have a request stream which you issue a request you get a lot of uh values coming back uh the difference between that and http based requests is that they can be a lot of values over just an indeterminate amount of time and it yeah i mean i know there are ways that you can get around some things with http but they are they are definitely workarounds right so we've covered the request response request stream interaction models in our socket there's one called a fire and forget which lets you just send out a piece of data you don't care you don't want a response you don't wait for a response you don't listen for a response and that's perfectly valid too but the other one that i think is particularly powerful is one called let's see we'll call this our buy directional channel and this is our request stream oops request request stream oh boy typing of all days all right so so we're going to set up our bi-directional channel here we'll call this channel channel cleverly enough we're going to return a flux of aircraft as you might expect we'll call this method channel we're going to get something else now if it's a bi-directional channel we're let's let's up the stakes a little let's receive a flux as well so we're going to get a flux of weather observations here and i haven't created that yet but we'll do that now why not so i'm going to skip down here let's just create a another domain class called weather and what is important to know about weather well for one we're going to have to get an observation we need to know when that when that observation was taken and we also need to know what the observation itself actually is right so i'm going to just do something i'm not terribly proud i'm going to copy paste for later oh that looks happier all right so i'm going to take that weather flux coming in and i'm just going to do something just i like to do unsubscribe so we can see this so we take our sub sub and let's just uh indicate that we're subscribed here subscribe to weather and then let's when we get a value for weather let's do something with that so let's do this and i'm optimistic right so i'm going to assume that we're going to get some sunshine because sunshine's better to fly in than terribly wet nasty weather days so we'll take that and then i'm going to switch to a different map i'm going to take our weather value and then i'm going to go to my client i'm going to do a get i'm going to retreat i'm going to convert the body to a flux once again aircraft class and well actually that's pretty much it all right and let's see so let's clean that up and make that happier except it's not let's see so don't subscribe we'll clean that up now before i go back and do anything more i actually kind of skipped over this part because if you notice we're still using our reactive web client to go out to our plane finder data feed and and we're still using basically an http based interaction but but here we're actually using our sockets so don't you think we should probably clean that up a bit i think that would be nice right so let's get rid of that and let's use here let's create an r socket requester and again we have our socket requester builder automatically injected into our application by spring boot thanks to our class path right what's on our class path so i'm going to return builder.tcp and i'm going to point that to localhost and this one is running on 7635 and then i'm going to instead of injecting web client i'm going to inject our r socket requester here and we'll use that so a little bit of changes in order instead of a client get retrieve we'll just do a requester.route and once again i'm going i'm going to pass this or point this to ac stream stream that's my endpoint in my plane finder i'm going to pass a timestamp for the data i'm going to change this from body to flux to retrieve flux and we're off and running i'm going to do the same thing on this one should have done this before but it's kind of instructive to see it actually so ac stream if you don't typo and we'll point this we'll provide the data of a timestamp and then retrieve flux and we're off and running so i'm going to restart this and we'll go back over and instead of using our request stream i'm going to create another method here and we'll just do a channel method channel and we'll use our requester.route and the route here in this case is channel as we can see on this side and thing one will provide data i'm going to provide my timestamp here and retrieve a flux of type aircraft oh actually you know what i'm not going to just provide our time stamp because i'm expecting a flux of weather here so let's give it exactly what it expects a flux of weather i'm going to create a pulse here just to do some weather generation i like real data i really do but sometimes just in the interest of time you kind of have to to make it up as you go weather is one of those things that i think people make up as they go anyway right so i'm going to create a list of strings and we'll call this oh there we go there we go and we'll call this our observation list equals list.of and we'll start off with sky's clear visibility 10 statute miles that's a good observation right that's a good good weather forecast or weather reading uh and then we'll say that we have broken at zero nine zero that's nine thousand feet visibility eight statute miles that's that's not too bad and now if i can type broken and then let's say we have overcast at um at 0 3 so that's 300 feet that's terrible for the visibility of half statute mile and then just for fun i like to insert some randomness into things because randomness is fun at times right anybody watch loki so i'm going to take our observation list and i'm going to get a value i'm going to use my random number generator here and i'm going to bound that based on the size of our observation list and then i'm going to retrieve the flux from there so that's not terrible i don't think so we've retrieved the flux and i'm going to subscribe i'm going to take an aircraft each aircraft i'm just going to print that out and let's see so let's grab an aircraft and we'll use this one in this case plus ac and let's run it what could possibly go wrong now the nice thing is because i actually did make things where we've got the nice clean disconnect that when we decide to disconnect it'll be cleaner except i obviously have something wrong here let's see could not resolve method parameter oh let's see here um oh well i did kind of shortcut things didn't i yeah so i need to uh i need to provide a weather a flux of weather objects right so we need to have those so i need to in this case doing new weather see this is what happens when you get on a tear and you don't think where you are so i'm going to use my time stamp and then the observation and that all looks should look pretty good let's find out okay there's that there's that there's that there's that oh uh yeah so that's a map and then all right well i'm getting ahead of myself here so i'm just going to stop that and start here because i'm obviously off on my paren so i've got my interval i'm going to map that to flux.interval oh sorry to a new weather and i'm going to do an instant.now and obslist.getrandom.nextent of obslist.size and i'm gonna have to maximize this so i can see what i'm doing there we go and uh ah there we go data there we go except i'm not really sure why this is doing that there we go all right so that's works out and off we go so let's try that again still good on time okay and while that is restarting actually it's there we go so we have weather and we're getting back aircraft and then when i disconnect it's a nice clean disconnect now in order to push this on we have 10 minutes we've got plenty of time here so in order to push this onto thing 3 let's go ahead and create thing three and i'm going to unzip that and thing three i'm going to be using spring cloud stream to receive this data from thing two and spring cloud stream uh uses built-in constructs the language uh of of supplier and function and consumer we're really only concerned since this is a consumer this is kind of the end of the line for this we're really only concerned with the consumer side so let's go ahead and go to our pom pom and everything's fine there but we'll come back to that in our application properties and our application class so the first thing i'm going to do is just create my data class aircraft private oops private string call sign reg flight flight number and type private integer altitude heading heading speed and private private double double double flat lawn i need to slow down my typing now i'm going to just create a configuration class configuration class and this will be our thing three config and i'm just going to create a bean here and you don't have to do this i just like to keep things separately so my separate so my bean will be a consumer of type aircraft as you might imagine i'll just call this being logit there we go and i'm just going to return and this is aircraft and i'm i'm just going to print this out once again airplane and we'll grab an airplane and this is our consumer and we're going to this is our consumer bean and with spring cloud stream we can take this and define well the first thing i need to do is set my server port to this case 7070 so we have no support conflict and i'm going to define my spring cloud stream bindings bindings and i'm going to set my uh my uh consumer being here to log it and it's an input channel and it's channel zero so there's only one in this particular case and i'm going to set the destination to a channel called aircraft aircraft now i'm not going to have multiple consumers here or multiple instances of this but just as a good habit to get into you should define a consumer group so you can implement the competing consumer pattern should you need to and scale out we won't need to for this demo but again it's a good habit to get into so i'm going to go ahead and start that and then in thing two i need to be able to pass that data as it comes in out to our thing three and since we have spring cloud stream and rabbit r class file primarily spring cloud stream really we can also we have the ability to inject a beam that's automatically created for us which is a stream bridge and this is just a very nice abstraction that's built in and for your benefit for your use and we're going to take each one of these once we retrieve the flux of aircraft and we're going to do on next and we'll take each aircraft and we'll use our stream bridge to send that aircraft to an output binding we'll just call this send ac it's an output channel the first output channel zero and you can refer to these any way you want to i just like to follow a consistent convention per spring cloud stream but do what makes you happy we're going to send that and then i'm going to take this value and we're going to define that output channel here with a spring cloud stream binding dot destination and once again we're going to point this to aircraft so let's restart this thing three is listening thing two is starting and thing two will pull thing one for data and it will send it via spring cloud stream using rabbit to thing three so now this is good right this is this is all right this is great stuff but what i'm going to do now is take it up a notch because as you know azure has event hubs and event hubs allow you to use various different capabilities but i like to use the event tabs with the kafka api it's very simply done so i have some environment variables that point to my event hubs instance running out in azure and i'm going to take the same applications i have here and i'm just going to um just build them from the command line here so let's see i want to go to thing two right and maven clean package and we'll do the same thing for it's not there oh yeah thing three and we'll get those going meanwhile every time we've been pulling this it's been pulling our spring native application running out here just listening for response or requests and providing the responses uh so we've got thing three up and ready to go let's do a java dash jar target thing three let's run that so that's up and running let's go ahead and do the same thing for thing two jar target thing two and let's see what we get so yeah we're providing the data we see that we're pulling it here uh from our initial data feed and let's see if i switch this to so that's thing one so we're getting that and actually oh yeah i think when i'm actually yeah i'm logging it good it's staying there for a minute i wasn't logging it so that is working so this is our data feed this is our thing one this is thing two and this is thing three now i'm going to go ahead and stop this because uh we have just barely enough time to show you something that i didn't get a chance to show you earlier which is something i think is really really really cool so if you remember i mentioned that that our socket is transport independent protocol independent so right now as you can remember you might remember i'm running this using tcp so let me see if i can there we go so i'm running this using tcp and of course here on thing one i'm using tcp to connect to my data feed and that's fine that works works a treat but what happens if we want to change this how hard is it to change to using a websocket let's say for instance instead of tcp well it's really super difficult right i'm going to go into thing one and i'm going to change my our socket server transport to websocket and then i'm going to restart now this changes our server transport to web websocket but if you remember we're still using our socket requester client here to return a a requester based on tcp for our data feed so we're actually using both here in thing one we're using tcp for the connection to our data feed we're using websocket for our connection or you know for any connections that come in the requests that come in from other applications other services like this so the thing too i'm just going to just leave that just for a reference later for you if you'd like i'm going to change this to websocket i'm going to point this to http colon slash localhost colon 1991 and then i'm going to wrap that and restart it oh oops i don't want to restart it here because i'm actually running it through event hub so that's not i want to make sure i feed data to event hub so i can pull it from event hubs so let's go here and this is thing two so i'm going to um now let's see i made some changes some even clean package just to make sure everything is nice and tidy thing three is still running so it's still waiting patiently give me data i need data we rebuild thing two and we restart thing two and there we go i mean it really is that simple uh but with spring boots out of configuration and the thought and care that went into building out reactor and then r socket on top of reactor and by the way reactor is is a project led by by the spring team as is our socket but it's certainly not only i mean you've got a lot of contributions and community involvement and and commercial and open source products built on both of those uh and offerings so it's it's a very much community driven uh opportunity an option so please do get involved and of course again i wrap it up here with the event hubs just showing that when you really need massive scalability in terms of message passing there there's really that's the best place to go so with that i'm going to switch back over to my last slide and let's run that so let's see if i can do this powerpoint yeah powerpoint has this bad habit of going all the way back fortunately i only have about six slides so that helps all right so thanks for coming today if you want to know more please do watch and start the repo at well my github account mk heck warp speed super simple to remember mk heck warp speed so go there for today's code uh watch it start and updates will be fed in there over time uh other recommended sessions well we have several that were recorded already and then one that's upcoming that's actually some azure spring cloud information with some panel discussion with some customers great stuff because that's an awesome awesome product again built on spring cloud thanks so much for attending and please do stick around in the q and a session and happy to happy to chat with you there so go spring one wow what another amazing presentation by mark uh mind blown um i love his style presentation always great information um and uh with that i'm gonna tell you all to head over to the slack channel and chat with mark some more ask questions that's the end of my duties today thanks for sticking with me this morning uh nate is gonna be your mc for the rest of the afternoon and have a nice rest of your spring one you
Info
Channel: SpringDeveloper
Views: 819
Rating: 5 out of 5
Keywords: Data/Databases, Reactive, Serverless/Microservices
Id: WJuMkgxDyEA
Channel Id: undefined
Length: 57min 16sec (3436 seconds)
Published: Wed Sep 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.