 Thank you, Richard. Thank you so much. I appreciate that, my friend. Good to see you as usual. Let's get a photo before we get going. The most important thing that I manage to do when I'm in a conference is to capture the fact that I was there because otherwise what's the point? So you stand over there and then the rest of you, when we say open source, you all smile and say open source as well. Okay? Ready? Steady? Open source. Thank you. Money. Good stuff. Hot sauce. Well done. Right on. Thank you very much. So let's see. We have very little time and so much to cover. I didn't realize until just a little while ago that this is a 30 minute talk and normally this talk is a good solid dense end to end wall to wall one hour. So we're going to go very quickly and we're going to cover a lot of stuff. But I want to remind you that you don't need to remember everything that we're going to cover. Just note the repository. Note that GitHub URL there for your own reference and edification for later. Keep that in mind. If you have questions or comments or feedback and you want to talk about what we're going to talk about today and you have ideas, whatever, don't hesitate to find me on the internet. How many of you by show of hands are on Twitter? I'm just curious. Twitter? Twitter? The rest of you get on Twitter. It's a great place to be. It's the new IRC. If you're a developer using open source, then you owe it to yourself to engage with the developers that drive the source that powers your business. And we're all there on Twitter, happy to answer questions. What about email? Email. Email. Anybody? Email. Email. No. Okay. So that's what we had before Slack, right? So find us there if you want. Find me there. I'm happy to engage. A little bit about me. My name is Josh Long. I'm a spring developer advocate on the spring team. I'm an open source contributor and engineer. I have been for now going on almost eight years, the number one top ranked, most prolific, most visible, most widely acclaimed contributor of bugs, of bugs, but still number one, number one, right? Number one contributor for all team members, for all the projects on which I work, more bugs per commit than any other contributor. So that's that, right? There's that at least. And I do my best to engage with the community. I speak to audiences, to conferences, to companies and businesses and organizations. And we talk about how to build better systems in terms of, you know, usually these days, spring and the Cloud Foundry ecosystem. And as part of that, I write books and do training videos and so on. So I just finished my second, the second installment of building microservices with Spring Boot Live Lessons with my friend, the one, the only, the amazing, the inimitable Phil Webb. And I just finished writing a book called Cloud Native Java. And that book, for those of you wondering, for those of you wondering about that book, and in particular, for those of you wondering about the cover to that book, that bird, now anybody who knows anything, knows that the animal on the rally books is the most important part. So that book is a blue-eared kingfisher. It's a bird that is indigenous or, as we say in English, native to the Indonesian Java islands. And birds fly often through the clouds. So it's a bird that is native to Java that flies through the clouds. It's a cloud native Java bird. Thank you. Yes. Thank you. A blue-eared kingfisher, the cloud native Java bird. Very good. And so I work at Pivotal. And this is some amazing artwork by my team member and friend, Ashley McNamara, who is, she has art in her heart and that's awesome. So these Pivotal logos are sort of as if the Simpsons team drew it or something. It's great. So I work at Pivotal and we have a lot of great open source software at Pivotal. We care very much about the open source at Pivotal. But let's be very clear what motivates us, which drives us. The thing that causes me in particular to Spring out of bed is that we care about delivering software and value to production faster and safer whenever possible. And we see that a lot of organizations struggle with this. They want to go faster, but they struggle because they have these large existing monolithic applications. These applications written in yesteryear in a time before the era of cloud computing and the economics of cloud computing were so manifest and so impaired. So they try and take these large applications and decompose them into smaller batches, smaller batches that allow smaller teams to deliver value faster without having so much sort of urban sprawl, without having to worry about the impact of changes to the code base propagating out to large amounts of code. Smaller batches of work that small teams can focus on, they can develop them, test them, deploy them and manage them in production. A small batch of work makes it easier for organizations to go faster. We call these small batches of work microservice. Microservices give you the ability to describe small amounts of functionality and make them easy for small teams to work and operationalize and test and so on. They give you the ability to go faster, but when you move to this architecture, when you move to microservices, you run headlong into two big problems, two big pains. I call them the hemorrhoids of cloud computing. Do you know what a hemorrhoid is, friends? It's a real pain in the cloud. The first hemorrhoid is how quickly from zero to 60 can you stand up a production-worthy service and all that that implies? How quickly can you address heartbeat detection, SSL, security, observability, management, infrastructure, like your environment, your operating system, your RAM, CPU, servers themselves? How quickly can you do all of that for every single new service? Remember, when you move to this approach, you're going to stand up a lot of new services, so that becomes a prohibitive cost unless you can automate it down to zero or codify it. That's the first problem. For this, of course, today we often talk about spring boot as a way to address these concerns in the application tier, and then cloud foundry is a way to address these concerns in the infrastructure and operations tier. They work side by side. They serve each other, one helping the other. The second hemorrhoid is, once you've done this, once you've built a system with lots of small, singly-focused, reusable, independently deployable microservices, you've got things that are talking to each other in a distributed system, possibly over network partitions. You've introduced the complexity of building a distributed system, and in so doing, you've invited much more pain into your life, and if you're not prepared to deal with that complexity, then you're going to fail. So we need to get past all of these pains before we can embrace this architecture. We know that most organizations are not yours, but most organizations, and again, I stress, I know it's not yours. Most organizations have the dreaded wiki page, a wiki page with all the things that you need to do, the 500 easy steps to production. That's not your organization, right? You're continuously delivering value with the best amount, I'm sure, but if you aren't, then you need to get past that wiki page. You need to reduce the cost of standing up a new service and seeing it result in production to almost nothing. It should be immediate so that you can focus on the business differentiating functionality. So we're going to talk about Spring Boot and Cloud Foundry to address the first problem, and then we're going to talk about Spring Cloud to address the complexity and the second one. Now, let's build a new application. I'm going to build a new application here at start.spring.io. This is my second favorite place on the internet. Anybody who knows me knows that my first favorite place on the internet is production. I love production. You should love production. Bring your kids. Bring your family. It's the happiest place on earth. It's better than Disneyland. Go early and go often. The weather is amazing this time of year, but if you're not already in production, then you begin your journey here at start.spring.io. If you want for inspiration in the early morning before your cup of tea or coffee, start.spring.io. If your children are restless and can't sleep, start.spring.io. And if you suffer from indigestion after a long night of alcohol abuse and PHP, start.spring.io. So we're going to build a simple application. I'm not going to spend too long on the application itself, but I want to do is I want to build an application that we can use as something that we can sort of play with, right? So I want to build a service that manages entities of type reservation. We're going to call it the reservation service, and we're going to use some Spring Boots and Spring Cloud support for building web applications. We're going to use the web support here. We're going to use the config client for centralized configuration. We'll use Eureka for service registration and discovery. We'll use Zipkin for distributed tracing. We'll use the rest repository support to build a REST API. We're going to build an application that talks to a database. So we'll use JPA, and of course the question comes up, which database do we want to use? So I'm going to use H2. Now H2 is an in-memory embedded SQL database. Because it's in-memory and embedded, it's going to lose all of its data on every single restart. So every single time we restart that process, all the data will be gone. In this way, it's very similar to MongoDB. It just loses the data all the time for no reason at all. It just loses all the data all the time, right? So there's a lot of similarities there. We're going to use also the actuator for observability and operational concerns, and I think for now that ought to suit us. So let's go ahead and hit generate, and we'll open up this project in our IDE, and it doesn't really all that much matter, if we're honest. It doesn't really all that much matter which IDE we use, right? So I'm going to use IntelliJ, but how many of you are using Eclipse? Right on. Good stuff. Hot sauce works just fine. What about NetBeans? What about NetBeans here? Right on. Good stuff as well. Rock on. What about Emacs? Are you here, sir? Where's the Emacs guy? Every conference I go to, there's one human. Same object identity. Every city, continent, and country, it's the same guy. I ask who uses Emacs, and he raises his hand. He says, I do, and then he leaves. Presumably to troll me in some other city, continent, and country. Anyway, we're going to open up this project in our IDE, and I'm just going to build a simple application. I've already remembered, I've just remembered that I've forgotten to include the Lumbuk annotation compile time processor. So we'll do that first thing, and we'll comment out some of the dependencies that we don't need just yet. Okay, so here we are. We're going to go to Palm.xml. This is our Maven build. Can you see that font in the back, my friends? Do I need to make that larger? Larger. Okay. Good stuff. Let's see. Alt F, settings, font. Okay. There we are, and it's going to say, come on, more bigger. Okay. Very good. Can you see that? Sweet nectar. Good. So let's see. We don't want the config client. We don't hear we good. We don't want that for now. We'll leave those bits off. We're going to get rid of the, we're going to leave everything else I think as is, and we're going to bring in Lumbuk. This is the compile time annotation processor. So there's that. Bring that into the class path, and we're going to build an application here that manages entities. So we're going to call this entity a reservation. It's just going to be any kind of reservation. It's going to be a hotel reservation. It'll be a reservation at a restaurant. It can be whatever you want. We don't care. I don't want to linger too long. So we're going to have a field here, private long ID. I'm going to make this an ID at generate value. This is just an object that will have a value that will be auto incrementing in the database. And we're going to have a field here called reservation name, which will be the name of the reservation that we're going to store in the database as well. And that, my friends, is the essence of what we want. But if I were using traditional Java, I would have to create some getters and setters and constructors and so on. So instead, I'll just use Lumbuk. I'm using Lumbuk here to create the no arguments constructors and all argument constructor and so on. And I'll create one more constructor just for my name here. And what I want to do is I want to save instances of this record in the database. So I'm going to create a repository. I'll say reservation repository extends JPA repository. And it's going to be an entity of type reservation that will manage whose primary keys are type long. So there's that. Now I'm going to save some sample data into the database, right? So sample data, CLR implements command land runner. It's going to be a component that implements command land runner. When Spring starts up, it's going to call this run method passing in the public static void main string arguments array. And then here, we'll just say that we want to inject the reservation repository, okay? And use that as the as a bean that we can use to instantiate some sample records. So we'll say stream of my name is Josh Richard Ashley. I'm not doing it in alphabetical order, but I should have Bridget. Who else? Who else? Oh, James. There we go. That gets us two. That's two names. So that's six. We need at least two more. Abby. There we go. I'm trying to think of names. Names are hard, my friends. Who wants to be my last victim? Miss, what's your name? How do you spell that? Very good. Thank you. That's a nice symmetrical, even number eight records. And we're going to say that for every name we have in the category there, we're going to write it out to the database. So there we are. And we're going to say reservation repository. We're just going to confirm everything's worked as we expect. We're going to say for each system out that print line and we'll print out the data as we see it. So there we go. Those are our records. We're going to run the program and confirm that everything is working as we expect it to. Now, I'm going to have an application, but I want to build a REST API. So I could do this the hard way and build a REST controller, but instead what I want to do is instead I want to take this repository and just annotate it as a REST API. I'll save repository REST resource and then restart the application and we'll see that hopefully spin up. So local host 8080 forward slash reservations. There's our REST API. Hypermedia links. This promotes a design pattern called hypermedia as the engine of application state. It's the idea that every REST resource has different information in the response for the client to be able to further manipulate that resource without any upfront or a priori knowledge. Now, these links are very useful. They give us an idea of what to expect from the service and we can do deep linking and we can do all that stuff. This is a REST API, but am I done? I can do put, post, get, delete, all that stuff. That's all there. But can I actually deploy this to production? I'd say probably not. One of the concerns that we care about when we build a cloud native system is observability. How easily can we see what the system in the application is doing at the node level and at the system level? And to address that here, we're using the actuator. Now, the actuator is a library that gives us the ability to see what is happening on a given node. In order to apply it, I need to disable security for our default sort of scenario here. So I'm going to say management.security.enabled equals false. And actuator is not a new idea. It's inspired by Google who in their Borgman monitoring paper described standardized endpoints that they stand up for every single API, for every single service, no matter what the nature of the service. It's batch or machine learning or artificial intelligence or web or whatever. They have standardized endpoints that centralized monitoring infrastructure can then use to corral into a single pane of glass, that ever important dashboard experience, right? And we have to care about that as well. We could use things like New Relic and App Dynamics and those, of course, are great choices. They work very nicely in Cloud Foundry, but I want my application itself to be able to chime in to say something is wrong, right? And my application knows very well its own state. It's the perfect thing to articulate that state. So we can do that with the actuator. We can say a local host, 8080 forward slash metrics, right? And metrics shows me things like my heap, my uptime, my non-heap, you know, it shows me the environment. There's the environment, right? I got the health endpoint. These are all different indicators that I can use that show me the status of my application. And if you deploy a Spring Boot application to Cloud Foundry and to Pivotal Cloud Foundry, this information is fed into the Apps Manager dashboard. So you get a single pane of glass and it's being driven in part by the platform's awareness of your applications as well as the application's awareness of itself. That's very, very useful. Now, I have this and I want to build a change part to the application. You saw me change configuration in the application by changing these properties here. I specified management that security enabled equals false. I can change other things as well, but this property file is in the application itself. I have to recompile the jar to see this property updated. And that's not a very useful thing if you're building applications that you want to promote from one environment to another. Another option, instead of keeping the values here inside the property value, is to use 12-factor style configuration, right? In this example, 12-factor style configuration, let's see, Maven minus D, skip tests because YOLO, clean install, okay, CD target. 12-factor style configuration would let me run my application and override configuration values as I do it. So, for example, I can say server.port equals 8010 minus jar. And that property that I use there, server.port, I can specify that here as well. But I'm coupling this value to the jar itself if I keep it here. So I'm now overriding it on the running, right? On the 40... Oh, it's already running 8010. 8011. Okay, there's already something on 408010. There you go. So I'm overriding the default value. And this is a good start, but what if I want to centralize my configuration? How do I do that? How do I avoid tediously copying, pasting configuration values from one node to another, one startup script to another? What if I want to do auditing and journaling, see who changed what and when, and if necessary, to roll that configuration back? How do I support that? How do I do security? If I want to support encrypted values, passwords, things like that in my application code, credentials, locators, that kind of stuff, how do I do that? And then finally, how do I do live reconfiguration of the values? For these use cases, what I've got is a good start, but it's not really what we want, is it? It's a good start, but it's not quite there. So instead, what I'm going to do is I'm going to stand up a REST API called the config service. And you can go to start.spring.reo and generate your own config server. Or you can use, preferably, the backing service that Pivotal Cloud Foundry provides you, right? The spring cloud services, backing service on Cloud Foundry. And then you just say CF create service, config service, and bind it to your application. But I've already got it running here in my local machine. And it is pointing to a directory full of get managed configuration property files, right? So config reservation hyphen service dot properties and config application dot property. So let's suppose that I am a microservice and I connect to the config service to draw my configuration. Let's suppose I identify myself as the reservation hyphen service. What would I see? Well, here I would see that there are several keys and values, server dot port, spring cloud stream, you know, bindings, input bindings, that group, message, et cetera. If I change my microservice, the microservice we just built and change it to point to this property file, it should have access to this value, the server dot port, and to this message, right? So let's take advantage of that here. Let's make sure that in our build we have the spring cloud starter config client. We're going to need that, right? So let's add this here. And for, you know, for posterity, we'll bring in this last dependency as well. So, okay, paste, good. Now, in order for this configuration to work, it's going to need a few things. I'm going to need to tell it its name. I'm going to need to give my microservice a name, reservation hyphen service. And then I'm going to tell it where to find the config server, HTTP, localhost, 8888. Now, of course, this is the default value. This value right here, 8888 is the default value on your local machine. So if you are like me and you don't really want to specify this each time on your local machine, just comment it out. It's fine. It'll work in this case because of engineered coincidence. I only show it to you because I'm a giver and I care. But I may forget. So just keep that in the back of your noodle, okay? Now, there we go. Let's take advantage of that message, right? So I'm going to say at rest controller, class message, rest controller. And I'm going to say private final string value and we'll add a constructor value there. I'm going to inject that key, that message key that we had from the config server there. And we're just going to create a rest endpoint that parrots the value there. So public string, read, return this dot value. And this is interesting. I can imagine this being interesting, but I can also imagine wanting to change this message later on. So I'm going to say at refresh scope, I'm going to make the beam reconfigurable. And now when I do this, I can go to local host, 80 or 8,000, four slash message or reservations. There's that. And there's the message, hello world. Now, that's a good message, but it's not great, is it? So I can imagine wanting to go to the config directory here full of my config files and change some of these different values. Now, you can use any text editor you want, but I'm going to use Emacs because I'm not a savage. I'm not. So I'm going to say reservation service dot properties and I'll say hello CF summit 2017 extra exclamation mark, so as to reinforce my credentials and authenticity on Reddit, right? So, okay. Come on. Sorry. I thought I was in that other text editor. So there we go. Get status, get commit minus a minus M YOLO. Okay. Now, if I go to the config server, it's immediately aware of the change text value here right here, but my microservice doesn't know. It doesn't know about the updated value. So let's tell it to see the new value to reconfigure itself based on that change value by using another one of those actuator operational endpoints. We're going to say that we're going to send an empty H to be post to the refresh end point on my microservice, right? So minus D curly bracket, curly bracket. And what I'm going to do is I'm going to play the game that I've never won. It's a game that I play every single time. I'm going to hit enter. I'm going to hit an enter and then as fast as my little fingers will let me, I'm going to hit alt tab and then control R. Okay. So one, two, three, yeah. Son of a gun. It's faster. It got there before I did and I try. I've been at this for years. I've never won. So I've changed the configuration value in situ. I didn't have to reload the service or anything like that. I can now support feature flags, which in turn lends itself to things like A, B testing and generally decoupling the deployment of software from the release of software. So there's that. That's a nice feature. And because I've got this centralized config server, I can require it to do security. I can say that every link in the chain from the app to the config service and from the config service to the config repository should be done over HTTPS and SSL and I can require authentication and all that stuff. And all of this is pre-configured for you and done the right way if you're using the spring cloud services config server on Pivotal Cloud Foundry. So there's one very useful thing. The next thing I care about in a distributed system is making it easy for one service to find another and to work with another. Remember, in a dynamic cloud environment, services are going to come and go based on the demand and the need at any given time. So we need to make it as easy as possible for one service to talk to another. In a dynamic cloud environment, DNS isn't a great fit for several reasons. First of all, most cloud environments have a multi-homed notion of DNS. You have the public DNS versus the private DNS, so that complicates code. Then you have the fact that DNS clients these days aren't very smart. They cache DNS. So if you're using a DNS-based load balancer, it's going to keep the first resolved IP address and then pin subsequent requests to that. You can undo this setting somewhere, but it is kind of tedious. Another thing is that DNS is kind of a simple protocol. It doesn't give me the ability to ask questions. It can tell me, for example, where a service lives, but it can't tell me if that service is alive. That's a problem. Put it another way. Imagine somebody coming to my home. They know where I live, but I may be out to the market. I need to be able to find out if that service is there before I even make a call. Otherwise, I'll sit there in a block waiting for a response I may never get. That's the last thing that we want to do, right? Hopefully, you've all done the right thing. You've all read, internalized, and applied. Michael Mygard's amazing book. Release it. You've done that, right? All of you. Keep it under your pillow, right? You've specified aggressive client-side timeouts. You've restricted your opportunity for failure on the client invocation to a certain bounded window. You've done that, right? And all of your code, everywhere? Any code that you have that uses Java.net URL connection, you've done that. You've made sure to configure timeouts there. Pop quiz. Do you know what the default timeout for that is? It's zero. In perpetuity. It's just going to block forever. Waiting for heat death. So, I don't know about you, but if I've got 100 threads able to handle responses in my web server, and I've got 101 requests, I'm going to block. And I don't want to be blocking, right? So, it's much better to ask the question and then degrade gracefully if I get a bad answer. So, we need more. We need something that gives us the ability to talk about the state of the system. And this is a service registry. I have a service registry running in the background here. I've got it. It's called Netflix Eureka. And this is another one of those things where if you're using Pivotal Cloud Foundry's Spring Cloud Services, you can use the Eureka service broker that's pre-configured for you on Cloud Foundry, or you can run the little local version here. But this is not a production-worthy version. You can even see that Eureka is screaming bloody murder saying that this isn't a highly available setup. It's saying, don't do this, dumb dumb. One instance isn't going to fly, right? This is one of those things that I need, but I don't want to manage myself. So, I have Eureka. I couldn't use anything, right? Spring Cloud doesn't really care. I can talk to all sorts of other different service registries through the Discovery Client Abstraction. And that makes it so I can write my code with against one interface, one API, and not worry about changing it. So, I'm going to use that Discovery Client Abstraction here by using Spring Cloud Starter Eureka, and then I'll opt in to Service Registration and Discovery. I'll say, at unable Discovery Client, and I'll hit go. And what that's going to do is it's going to raise its hand. It's going to raise the hand of this service, and it's going to say, I'm here. If you need me, find me at this host, this IP, this port, et cetera. Good stuff. So, there we are. Now, there's our service. It's now available in the registry. You can see that down here. There's one service. There's another thing you may have noticed, very well done mouseovers. That took time. That took a year. We have very, very smart people on the Spring Team. Doctors, PhDs, people in their previous lives worked in nuclear physics. But it makes me very happy to imagine that someday, somewhere, there was a GitHub issue that said, we need a good mouseover. I think it'll agree they delivered. It still took a year, though. Anyway, so we've got our service. Now, we need to build a client. And we're going to build a client that talks to that. And we're not going to just build any kind of client. We're going to build a reservation hyphen client. And the reservation client will use the config client. It'll use Eureka. It'll use his tricks with circuit breaker. It'll use feign for declarative rest clients. It'll use the rest repository support, web support, actuator for operational concerns. And I think config Eureka, tricks, feign, rest repositories, web, actuator. Oh, Lombok, of course, Lombok, right? And I think that ought to do. Config. Yeah, let's do that. So that's going to be our client. And we're not going to build just any client. We're going to build a edge service, right? When we talk about building services these days, there's all sorts of different clients that will talk to our services. All sorts of different clients that have different security requirements, different form factors, different bandwidth capabilities, different everything. And so we need to accommodate these different clients. The clients are numerous today, right? If you're in the most boring of organizations, you probably still have an HTML5 browser experience, an iOS iPhone or iPad kind of experience, or an Android experience for your client experience, right? Your apps. And that's just the most boring and conservative of sort of like experiences these days. Most organizations have far more. If you go to Singapore, the roads, the very roads themselves have IP addresses. They connect to a cloud and they use that information for data traffic shaping, traffic shaping, right? Not network traffic shaping. I mean actual traffic shaping, all right. So they use the roads themselves that feeds to somebody's service. Same thing for organs. There are people with prosthetic organs in their body that have IP addresses. These things are clients to somebody else's service. So we need to handle all these kinds of concerns rather than retrofitting every single microservice. We can externalize those concerns into a separate client. So I'm going to create a reservation client. We'll call it the spring application, we'll say spring application name equals reservation hyphen client. And what we're going to do is we're going to build an application that talks to our downstream rest service, right? We could do it using Zool. We could proxy requests back and forth using the micro proxy. That would certainly give us one opportunity here. So spring cloud started Zool, right? This is a micro proxy that was developed by Netflix that we make it very easy to use in your application. You just have to say at enable Zool proxy. That's certainly one option. If I have an HTML5 browser client and I want to, you know, proxy requests from the HTML5 browser client to the downstream services and I don't want to have to add access control headers to every single one of my downstream services. A micro proxy like this can be ideal, right? I'm going to need to take advantage of the service registration and discovery of course. So I'll restart this, okay? This is one option. But I want, you know, more often than not, I want to do more sophisticated things. Maybe I want to call the downstream, the downstream service and get the names. Maybe I want to transform the downstream service or enrich it or adapt it or synthesize a new endpoint based on composites, you know, compositing data from different services. So let's imagine I want to create an endpoint that returns just the names Josh and Richard and Ashley and Bridget and James and James and Abby and Chen, right? Let's say I want to do that instead of just returning the data directly, you know, transformed. So in this case, I can create what's called an API adapter, right? So I'm going to say API adapter, rest controller, right? And I'm going to say that this is just going to be an endpoint that uses the downstream service and I could use the spring framework, rest template, right? I can use the spring framework, rest template to make the HTTP call. That's certainly a good idea. But in this case, that's a little verbose. What I want to do is I want to make it easy for my client to talk to the downstream service without writing so much client code. So I'm going to create a client declaratively using something called Netflix Fane, right? And Fane is aware of my downstream service. It's aware of the service registry. So I can just give it the service ID here that we saw register in the registry here, right? We can see that down here, reservation hyphen service. It's aware of that registry. So here we can create an endpoint that returns the hypermedia envelope object. Remember we talked about hypermedia here? This is an envelope object called that resource. It has a payload called the reservation. It has links that describe that payload. So I want to turn that, I want to turn this, I want to tell this client call the endpoint at reservation hyphen service and we'll talk about how it actually figures out which one to call in a second. And then when you get the JSON back, turn the JSON into a collection of reservation DTOs, right? This is the reservation DTOs and we're going to say that we want to make an hbget call. So I'm going to say request mapping method equals get value equals reservations, okay? So there's our our feign client. And the reason we're using feign is because it makes the work of creating a client much simpler. Now of course in English feign means to pretend or to act as, right? To pretend to be. And this is, you know, if you see an animal in the forest, if you see an animal in the forest with its poor head cocked back and you can see its poor little heart beating a to beat the band, you know, just it's just scared. It's got its eyes closed but it's got one eye open and it's hoping you'll pass it by and leave it alone. It's pretending to be dead. It's not actually dead. It's feigning death so that you'll leave it alone. This is the same thing. This is very similar to the way web sphere pretends to be useful. It feigns utility. It's not. It's not. It's dead. It's trying to get you to leave it alone, right? It's scared. So we're going to use feign here to create a client to call our downstream service. And then we're going to create an API adapter endpoint. We're going to say public collection of string names and we're going to return the names here by using our recently created reservation client, right? A reservation reader, okay? And go. So we say reservationreader.read.gitcontent.stream.map and we're just going to take the data and transform it into a collection of into a list, right? Collectores.toList There's our endpoint. Now what happens if we call the downstream service and it's not there, right? We need to have a fallback method, right? We don't want to assume that that service is always going to be there. So we're going to create a fallback method using a circuit breaker. A circuit breaker gives us the ability to protect our downstream service, right? Imagine that this code runs and then it's going to try and dispatch a call to the reservation hyphen service. It's going to try and pick that service by going to the registry using the discovery client abstraction. It's going to find one of them. It may find 10. It has to now make a decision on which node to call. It does this using something called client-side load balancing. It's going to pick an instance and it's going to make the request to that service. And that's going to work in the happy path, isn't it? Look at this. Localhost, reservation names, there's a happy path. But what if there are no downstream services? What if there's no service there to handle the request? What's going to happen? It's essentially the same as load balancing, right? We're going to be dividing by zero, basically. We're going to try and load balance by zero and we all know what zero divided by zero is, right? What is zero divided by zero? Imagine that you have zero cookies and you split them evenly among zero friends. How many cookies does each person get? See, it doesn't make sense and Cookie Monster has said that there are no cookies and you are sad that you have no friends. Don't make Cookie Monster sad. Don't try and divide by zero, my friends. You need to build services that degrade gracefully in the face of service outages and topology changes. That's one of the key aspects of a cloud native system. So we've got now an application. It's going to do the right thing if I kill the downstream service. Now, we can demonstrate that and we can end on time or we can go for another five minutes. When does this thing go? When does this thing finish? When are we supposed to... When does the next talk begin, actually? In 10 minutes. I end in 10 minutes. When do I end? Now, when does the next talk begin? 10 minutes. Okay, we're going to go for a few more minutes here. Well, it's a thing. We've got to go fast. So we've built an application that is robust enough to do the right thing in the face of service outages and topology changes. We can demonstrate that by killing this, like that. And if we make a call, it just gives us the empty array list. So that's protecting our downstream service if something should go wrong. The last thing that we want to do if our downstream service isn't responding is to start hammering it with requests that it can't handle. So that circuit breaker protects it. It gives us time to restart the service. If you're using Cloud Foundry, it'll start the service all day and all night. If it falls down, it'll pick it back up again. You can sleep easily knowing that the platform is wearing the proverbial pager, but it's our job to build systems that do the right thing in the case of service outages and topology changes. Now, I've got an application here and that circuit breaker represents a connection from my client to the downstream service and I can use that status that it is keeping and monitor the downstream service as an optimist. I know that all people will fail me all the time and I cannot trust anybody. That's the optimistic perspective. As an optimist, I know that. The pessimist says that there's nothing I can do about that. I say there's absolutely something I can do that about that. That circuit breaker is smart. It doesn't just degrade into a fallback method. It actually keeps state. It says, oh, these invocations are failing. I'm going to open the circuit breaker. The state is open. Requests aren't being passed through and I can monitor the state of that circuit breaker as a proxy for monitoring that downstream service. So if I go to 8010 histricks.html, this is the histricks dashboard. Another thing that you can pre-configure and reuse on Pivotal Cloud Foundry and the Spring Cloud Services, I can go to the circuit breaker here, the node that has the circuit breaker and I can take that stream and I can paste it into this dashboard. Like so. Now, this circuit breaker stream goes on forever and ever and ever. It has no end. It is infinite. Well, there we go. It is infinite. Come on, browser. Do the right thing. It goes on and on forever and ever and ever. No matter what you do, it will just go on for and it goes on forever and ever. It has no end. It is infinite. It is endless like the skies, like the oceans, like the stars and the bugs in your code. Just infinite, right? So whatever you do, do not, and I cannot underscore this enough, do not curl that endpoint. What we're going to do is we're going to paste that endpoint into this dashboard. And there we are. We're going to make requests on the left. Local host, reservation names. As we make requests on the left, you can see the moving average trending ever upwards, 14, 21, 28, et cetera. It's giving us an idea of what's happening as data flows through that circuit breaker. It gives us not just node by node visibility, but it gives us an idea of the systemic behavior of our system itself, right? Distributed tracing on correlated logging also support this. And these are things that are built into the platform as well. If you're using Apps Manager in Spring Cloud, then these things just work. You can go to the PCF metrics and see this detail, right? So we've talked about building a cloud native system. A cloud native system is four different things. It's agile. It's easy to evolve over time. It's robust in the face of service edges and topology changes. It is observable both at the individual node level and at the system level. And finally, it is elastic. It takes advantage of the elasticity of a cloud platform, something like, of course, Cloud Foundry. I want to thank you very much for your time today. I wish we had more time. I wish we had more time to talk about other things. Did you like what we saw here today? A little bit. I appreciate that. I appreciate that. I hope you liked it. I certainly liked it. I'm wearing a spring t-shirt and spring underwear. Of course, I liked it, but you don't have to take my word for it. Instead, look at the other companies that are using these technologies. There's a small company just down the street from here called Netflix that uses Spring Boot and Spring Cloud at production scale earnestly, right? They're using it in production at scale. There's another company in the east, in the Far East, well, in the east, Far East called China, called Alibaba. They're in China. They're a small company that I believe one day is going to be amazing. They do, right now, they have the largest e-commerce catalog on the planet. It's more than a billion items. They're using Spring Boot and Spring Cloud at production scale. There's another company in China called Baidu. They're a search engine, the third largest search engine in the planet. They are using Cloud Foundry, Spring Boot and Spring Cloud at production scale as well. There's another company even further in the Far East in Japan called Rakuten.com. They're an e-commerce engine. They're using Cloud Foundry and Spring Boot and Spring Cloud at production scale. Yahoo Japan is using Cloud Foundry and they're starting to use Spring Boot as well. So these are organizations that have the money, the mindset, their motivation, and the need to solve these problems. And they still choose to build on the pivotal stack because for them, no matter what else they have on their plate, what matters most to them is getting to production. And that is all that we need to worry about. Thank you so much, my friends. Thank you so much. Have a great day.