 I have to create the slides. Okay, you have one minute for that. So yeah, hi everyone. Welcome for yet another visual meetup for the Java user group. So today is a very special day for us. You can see that Nilesh and myself have a background of VoxDays. And the reason is that today was supposed to be VoxDays Singapore 2020. We had to cancel it because of the coronavirus, but we hope to do it again next year. And we thought we should celebrate by having at least one of our guest speakers, Josh Long, for a virtual meetup. So Josh came twice to Singapore for VoxDays. He's a Java champion, wrote many books. He is one of the faces of the Spring Framework and keeps traveling the world to do some like demos and spreading the world about spring booths and that kind of stuff. Okay, thank you, Josh. Well, thank you. Is it my time? Can I? Should I go? Is anybody else? Okay, let me get going then. Close that. Okay. All right. So let me show my screen, my friends. Sorry about this. All righty, my friends. Good stuff. Thank you so much for being here. Let me see if I can move this out of the way. There you go. Thank you so much for coming. I know that it's early in the morning for you. I'm glad that you are all here and that you could join us. Obviously, weird time in history. I really wish I could have been at VoxDays Singapore. That's one of my all-time favorite experiences. Not just because I love Michael and the rest of the team there, but also because of the food. And so I'm sad and, you know, I'm sad experientially and also, you know, my stomach is sad. So just very sad in all sorts of ways. I can't be there in person, but at least we get to hang out together and do this. We don't have a lot of time. So as always, I'm going to encourage you, please take note of this presentation, the slide. This is arguably the most important slide that you're going to see in this, in this presentation of ours. It contains all of the code. It contains the coordinates. It contains information about me. My name is Josh Long. I am a spring developer. I'm the first spring developer. I've been there for 10 years now. I am a Kotlin Google developer expert. Whatever they call it these days. I'm a Java champion. And of course I'm at your service. So if you have any questions, comments, feedback, whatever, don't hesitate to reach out to me. There's my coordinates, my email, my Twitter, at Starbucks Man on Twitter, my emails, Josh at JoshLong.com. And I'd love to talk. I'd love to be able to collaborate with you and answer questions and whatever. And if I don't know, and that's very often the case, then I talk to people who are smarter than I am. People like Michael, people like the spring team, people who will probably know the answer. And so that's my superpowers. I know who knows, right? Even if I don't know, I do know who knows. So that's what I can do for you. A little bit about me. I work on the spring team. As I said, 10 years now I do training videos. These are online. You can find a number of them online. You know, videos on spring and reactive programming and security and building HTTP, REST APIs and continuous delivery and all sorts of stuff there, right? These are on Safari. You can find them. If Safari is kind of a prefix, buffet style subscription. So you pay one flat rate per month and you can then watch all the videos. It's kind of like Netflix, except that you don't get a stupider. So that's nice. I also have a book called Cloud Native Java that I wrote a few years ago that's all about how to build applications that survive and thrive in the cloud using Spring Boot, Spring Cloud and Cloud Foundry. The book is available in a number of different languages. And I know that you and in Singapore speak all sorts of different languages. Of note, of merit, of relevance here is the bird. Now, a lot of people don't know this, but they ask what is that bird? And when we were developing the book, when we put together the book, there was a bit of a delay. The delay was not a big deal. It was just a little bit late. It was not such a big deal, but it was about a year that we had to spend extra to be able to release this book in form. And what we eventually settled upon was a bird for the cover called a blue-eared kingfisher. Now, this is near you. It's not where you are, but it's very near you. This bird harks from the Indonesian Java island. So it's a bird that is native to or indigenous to the Indonesian Java islands. And it's a bird that is, you know, that is native to the Java islands and birds, of course, they fly. So this is a bird that flies often through the clouds. So it's a cloud native Java bird. It's a bird that's, yeah, whatever. Anyway, moving on. There's that. I have a podcast. And this podcast is every Friday, lots of different stuff, lots of different. It's just me talking to people that are smarter than I am, right? And that's a very low bar, right? It's not hard to find people that know more than I do. And so I figured, gosh, wouldn't it be swell if I could just turn on the microphone and connect you, dear listener, with all these amazing people that I have the privilege of interacting with on my day-to-day basis, right? So this is just every Friday anywhere you listen to podcasts. And I know that a lot of you have a lot more free time of late, you know, what was the lack of a commute and things like that. So please, you know, subscribe wherever, wherever you listen to podcasts, you can find me there. I also have a blog I do every Tuesday. It's called This Week in Spring. It's just me recapping all the latest and greatest in the spring ecosystem. I've been doing that for every January, every Tuesday since January 2011. I haven't missed one in almost a decade, right? So the very beginning of January 2011. So find that there. It's just a recap of all the news, blogs, articles, videos, whatever, all that good stuff. And of course, I have a video cast series, a screen cast series that I do on YouTube. It's called Spring Tips. It's a playlist and the spring source developer YouTube channel. And you can find all sorts of good stuff there. There's 70, 80, almost 80 videos now on different topics. Okay. And that's basically it. So now we're going to actually focus on what we want to focus on, which is, you know, building applications today, destined for a cloud provider in particular, Azure, right? So we're going to use Azure, Microsoft Azure. Now, Spring is nothing if not flexible. We are very, very keen on making sure that Spring works as well as it can on any given cloud provider, any target cloud provider. And so Spring has, you know, the genesis of Spring Cloud, people may not realize this, was a set of connectors that actually allowed you to write a Spring application that could then talk to backing infrastructure, things like your databases and your message queues and your caches and so on in a generic way. So it was a set of bindings for databases and queues and all that kind of stuff that you could then dependency inject into your application. And this is one of the benefits of Spring, right? It's a dependency injection framework. And so you can write code that is insulated from the particular details of the resource initialization and acquisition pattern behind any particular thing. So you could write an application that, talk to ajabx.sql.datasource on your local machine for development and then talk to a ajabx.sql.datasource that was bound to JNDI in your application server if you wanted to. And then you could talk to, you know, if you're using an application server, I don't know who does that anymore, but that was one of the original use cases, right? And then nowadays, just as easily, you can write code that depends on ajabx.sql.datasource and that talks to something, you know, managed wholesale and discovered by talking to a cloud platform, something like Microsoft Azure. So the original use cases were very much about connecting Spring applications to cloud infrastructure. And then we took a few years, let's say four or five years to make Spring cloud the best framework. We expanded it greatly to make it the best framework for building applications that run in the cloud. So this is not the same thing, right? This is, I want to write applications that are cloud native, that take advantage of horizontal scale, that are agile, that are easily redeployed and, you know, recreated, that are continuously delivered, right? Small, singly focused, independently deployable, reusable, bounded context or microservices, right? So this is the thing that most defines, I think, today, what people think of when they think of Spring cloud is a set of primitives to support patterns. Now, these patterns happened in the original sort of days to be dependent on different open source projects, but it wasn't really dependent on individual cloud platforms. And eventually, a few years ago, let's say four years ago, three years ago, people started using Spring cloud and it became very popular. And then suddenly, the Spring ecosystem wanted to talk to different cloud providers in the way that we supported with that original, those original sort of connectors. So not only can we now build applications that are cloud native that run well in an elastic, cloudy-like environment, but now there's been a number of different cloud vendors that have helped us develop the best experience for Spring developers on their respective platforms. So obviously, there's Spring cloud for AWS. That's an option. That's actually the least well-developed implementation that we have. And the reason is because just not that many people want to use it, right? And the people from AWS don't really give us as much help as perhaps some of the others do. So it's just not as progressed as some of the others. Then there's Google cloud. There's Spring cloud for Google cloud or Google or GCP, right? So Spring cloud GCP is a whole project that's co-developed by Google engineers and by the Spring team, right? So we're happy to help. We obviously are very happy to help and do all that kind of stuff, but we can't take the lead on all the stuff because it's just too much. So the Spring cloud for Google cloud, huge offering, right? Spring cloud for Aliyun, right? Aliyun is the Alibaba cloud. It's a bit like their AWS to Alibaba's Amazon, right? They have a Spring cloud offering that's amazing as well. So really, really interesting offering, but then one of my favorite ones, one of the ones that's become most promising is the Spring cloud for Azure integration, right? Spring cloud for Azure is interesting for a couple of reasons. First, this is all coincident. It's all sort of happening at the same time as Microsoft has become very, very good about open source. They've become a legitimate concern in the open source space and not a concern in a bad way, but a going concern, right? A legitimate name, right? And so it's just been very interesting to watch these amazing efforts that are coming out of Microsoft and all the open source stuff that they're doing, not the least of which, of course, was hiring a bunch of people to work on Java at Microsoft to make that a better experience. So really, I've just been super impressed. All of us in the Spring team, I think, have been super impressed with what has been happening with Microsoft over the years. And so when they wanted to work on Spring cloud for Azure, we were very excited to help them. I, myself, have spent time in Redmond, Washington, which is a state that's about 1,000 miles north of where I live in San Francisco. Maybe it's a little bit less or a little bit more, I don't know, but very quick plane ride. That's about that way. It's like an hour and a half, right? Maybe two hours. And I spent my time with leadership there, and I spent a lot of time actually with engineers in Shanghai, in China, right? There's a large Microsoft installation there in China. So just really incredible engineers worldwide that are working on making Spring cloud for Azure a really compelling story. So today, I cannot hope in the meager time that we have allotted to show you everything that's possible. There's nothing, there's no way I can do that, even if I wanted to. We're going to just look at a small sampling of features, but I want you to know that they have thought of everything. So if you want to do Active Directory with Spring Security, you can do that. You've got reactive and non-reactive spring data implementations that talk to both Azure Cosmos DB and to Microsoft SQL Server, right? That's already done for you, right? There's integrations for, gosh, I mean just everything. If you want to do distributed tracing, if you want to do monitoring, if you want to do metrics collection, if you want to do MongoDB or Cassandra or Graf Gremlin, Graf Steel style interactions, all that is supported in terms of a respective Spring API. So they've actually provided integrations that work in a natural way for Spring developers. Really, really amazing experience. So all of that I thought was really cool in and of itself, but then they reached out to us and said, hey, as the number two cloud platform, Azure is by any measure, they're the number two, maybe even one day number one, but they're certainly the number two largest cloud platform, the infrastructure as a service offering out there. And with Spring being the number one, most widely used sort of de facto standard in the Java JVM ecosystem, wouldn't it be great if we could mix and marry some of these strengths or respective strengths to build the best sort of offering for Spring developers on Azure. And so we created something called Azure Spring Cloud. Now, Azure Spring Cloud is, you just go to your account, you can create a new one, for example, and you fill out the information and it spins up in Azure Kubernetes service-based platform as a service. Now, don't worry, I can see some of you looking for your escape hatch button, trying to run away from the talk. There's no YAML, it's fine, you can still be productive. It's a really, really nice experience. You just use Azure Spring Cloud and you can build a jar and then deploy it to that, right? And it automatically understands things like service registry. So if you want a Spring Cloud, a Spring Cloud based service registry, it'll automatically configure that for you. If you want to use centralized configuration, but Spring Cloud config server, it'll automatically give you one of those as well. If you want to automatically integrate tracing, distribute tracing for your service calls from one node to another, it'll give you that as well. So it's pretty trivial to do this and to just deploy dot jars. So there's no Docker containers, there's no manifests or deployment descriptors or any of that kind of stuff. You just give it a dot jar, a Spring Boot so-called fat jar and deploy it to the platform. And you'll have a URL with the services up and running load balanced in no time, okay? So that's a whole other thing. We could definitely talk about that at length, but I'm going to focus on just writing code that talks to Azure Backing Services. Because for me, the most compelling opportunity here is to be able to use all this amazing stuff that Azure offers, right? The backing services, all these things that you can see sort of outlined here, that's compelling to me. That's what's super interesting. Obviously Azure Spring Cloud, the ability to run your application in a very convenient, very reliable way. Obviously super interesting in and of itself. And hey, just being honest here, if you use Azure Spring Cloud, we make money too. So I love that, but let's face facts, not everybody's going to use that, right? And so what I want you to understand is that if you're running on top of a zero Kubernetes, if you're just using one of their WebRunner things that they have, you can do that too. It's just the integrations of all this backing services that stand on their own. They're really, really compelling. So in order to demonstrate all this, I'm going to go ahead and build a new application. We're going to go to my second favorite place on the internet. Obviously my first place has always been and will always be production. This is start.spring. I'm going to build an application. Unfortunately, I can't use the latest and greatest 2.3.0 yet. Some of the things I want to show you today aren't quite yet upgraded. Actually, a few of them are. So I actually did give a go. I did give using 2.3.0 a shot. And I was pretty close, but I was like, you know, people aren't going to upgrade to this tomorrow anyway. And spring boot 2.3.0 just came out like a week ago, maybe two weeks ago. It's really, really new. So I love 2.3. You should use 2.3.0. And there's a couple of reasons that you should use 2.3.0. First and foremost is that when you use spring boot 2.3.0, what you get is native Docker image generation support. So I won't belabor that point. But what you need to know is that now you can take a spring boot application and then do Maven spring hyphen boot colon build hyphen image and it'll generate a Docker image that you can then publish to Kubernetes or to Docker compose or to your local Docker image. You know, just your local Docker daemon or whatever, right? If you're using Mesa or whatever, you can do that. And of course you can deploy to Cloud Foundry and to Azure and all that stuff, right? So lots of different options there for your Docker image. And the thing is that's really good. The thing that's so compelling about that is that we're not, you know, the wisdom that's required to operationalize a job application that has been accrued by the spring team over many years. That wisdom is baked into that container. You see, we participate, we helped co-found something called the build spec, the build pack spec, right? This is a cloud native computing foundation specification. And the whole idea is that you give this build pack an artifact be it a .jar or .exe or .python application or Ruby application or Go binary or whatever, you give that application to the build pack and it'll create a file system that has everything required to run that application, including a JDK for a Java application, maybe a Tomcat if using a .war, you know, web application archive. So all this stuff that you need to be able to certain to operationalize that application, it gets done for you in a consistent way. So now you have cookie cutter sort of deployments to production. You can give it a .jar and you get the same thing on the other side of the line every single time. So you're not wasting time with snowflake configurations and trying to figure out why this one little switch matters more than that. And you don't have to learn all the stuff for each new application. Remember, the key to velocity here is consistency. You want the ability to be able to get something into production and then cycle on that to rinse and repeat as quickly as possible. That gives you agility and that's key when you move to microservices. Indeed, that's I think the most compelling feature. That's one of the things I love about that. And I encourage you to wait for, I think, Michael didn't say next week. There's somebody going to be talking about that. Yeah, that's correct. Next Thursday. Can you mention the name? Yeah. Sergei Almar. So he'll be talking about 2, 3, 0. So Sergei Almar is amazing. I'll be, I'll probably try and watch that one as well, especially if it's this time of day. He's awesome. So I look forward to that one. I don't want to steal the fender. The other thing that's nice about 2.3, and this isn't strictly speaking a thing that comes with 2.3. It's a thing that you can do with 2.3 that happens to work best with 2.3 is native images, right? So we have this thing called in the ecosystem, the Java ecosystem. There's been a lot of interest, a lot of fascination around this new thing called Growl, G-R-A-A-L. Growl is a C1 just-in-time compiler replacement that has been developed by Oracle Labs. It's a separate project than Oracle's Java team. But they are, you know, two sides of the same coin, right? One is generate, one, the original goal that C1 replacement was to build a better just-in-time compiler. And that just-in-time compiler is hotspot, right? That's the old one. That's a tangled code of spaghetti C++ code. So the team eventually sought to build a Java-first, Java-native C1 replacement. So you can actually use OpenGDK and just swap out the Growl hotspot instance. Or you can just download Growl's OpenGDK distribution, which has that as an option, right? As a default. So that's really compelling in and of itself. And you gain a lot. You gain like 10% in some applications. You know, less memory, less delays and all that stuff. Already compelling in and of itself. But what most people talk about when they think about Growl is not that. They think perhaps of the polyglot runtime. So you can actually run Python apps and JavaScript apps and Java apps and R apps in the same JVM. That's interesting in and of itself. But that's not also the most popular thing. What they most often talk about these days, it seems, at least to my eyes anyway, is the native image support. So Growl has figured out, hey, it's pretty interesting that we can figure out when to inline this Java code and turn it into native code. When we can turn it into machine code that actually executes really quickly. What if we just did that proactively ahead of time, right? What if we turned the whole application from a interpreted Java application into a compiled Java application into a, with, with, with bytecode into a native application. We did that all before you ever ran it. Right. So that's what this native image builder does is it, it turns your job application into a native image, an architecture specific image. But in order to do that, you need to tell about, you need to tell it about all the opportunities that you have for doing anything dynamics. If you want to load a class from a file system, if you want to reload a class or do a proxy or anything like that, any kind of reflection, any of that stuff needs to be made clear up front. If you're willing to do that, then Growl can turn your job application into a native image that boots up in fractions, you know, orders of magnitude faster than what you were dealing with before. And it can take tens of megabytes of RAM and memory instead of hundreds as your typical job application will do. Even Hello World is going to take more than 100 megs of RAM. If you're going to run it for a long enough time. Okay. So we're going to, you know, I'm not going to show you all of this because again, I've got a spring tips video on this. You can watch Growl native images, right? What's that? There's this video. And there's also a blog that accompanies it. Oh, I guess they're redeploying Spring. Yeah. That's awkward. That'll come back in a second and you can watch it, but there's a video and a blog there that details everything I'm showing you in depth. And the reason I'm not going to show you everything right now is because it takes a considerable amount of time. But what you need to understand is that I've taken two applications, two bread and butter kinds of applications. One's a traditional spring data, JPA and hibernate application that uses Apache Tomcat and servlets. And I compiled it into a Growl image. Now the feature that we released is called the spring Growl feature. The spring Growl feature is a Java agent that runs alongside your application, monitoring any time you do anything kind of tricky with your application such as proxies and reflection. And it captures all that and logs it and creates the configuration for you so that you can then pass all that configuration to the Growl compiler to have it do a good job of converting your code into a native image. That takes a long time. It took 10 minutes for this servlet application and for this, you know, spring data JPA servlet application, right? So I'm not going to show you, I'm not going to stay here waiting 10 minutes for a compiler. I've already done it and you can watch me do it in the video. But here's the application. Okay. I mean, that one took that one started up in 0.886 seconds. That's because I had to wait for network IO. There you go. That's much more typical 0.196 seconds to start up this application, right? Local host reservations. There's my data for my endpoint. Okay. So that's a traditional Tomcat application in, what did I say? What did we say? It was 0.35 seconds. There you go. 0.19. So, you know, less than 0.2 seconds, one fifth of a second to start up the application and have it online. And if you look at the memory footprint from this thing over time, it's not going to seesaw. It's not going to zigzag very much. It'll just be pretty reliable, pretty low for the entire life of its behavior. That's awesome. You can also look at reactive applications. And I think I've even addressed this group on reactive programming before. I've got a reactive application. Again, a typical bread and butter spring data, a reactive R2BC talking to a SQL database, just like the traditional application does. But it's also using, it's also got a web endpoint. So here I've got the application. And by the way, these things are huge, right? They're much bigger than the fad jars because they have their own runtime. These are not Java applications anymore. They're native code. They're native code. They're native code. They're actually JDK, but they embed their own virtual machine, if you will, their own runtime called substrate VM. So this is a 90 megabyte application. But here, if I run that, okay, slow on the first go 0.4 1 seconds. That's a long time. I don't know why the first goes always so slow, but there you go. 0.096 seconds. Right? So less than one tenth of a second. And that's pretty typical. And here's that endpoint with an extra record, right? So you can see it's different. So very, very, very quick experience. I, again, I won't get into this for too long. I encourage you to check out this great thread by my friend and fellow developer advocate that he works for Azure. Julian Dubois, he talks about using Spring Boot's Grau VM image support to work in tandem with Azure functions, right? Okay, so that's a very cool use case. You can build native images that respond to whatever you wanna do in Azure functions using Spring Cloud function. So check that out, okay? Okay, now, let's us get underway. We're gonna use 2.27. Having said all that, having talked up the opportunity here with Spring Boot 2.3, I have to regretfully use 2.7 for the moment, but again, it's getting better. Just check back in a week, it might even be better by then. What we're gonna do is we're gonna build in an application here, I'm gonna use Java 11. And I'm gonna add some dependencies, okay? So I'm gonna bring in the Azure Spring bomb, that's the bill of materials, right? I'm gonna bring in the Azure storage support, I'm gonna bring in JDBC, I'm gonna bring in LumBuck, which is a compile time annotation processor that makes life just a little bit less verbose if you're using Java. And I'm gonna bring in the web support, okay? So I've got Azure support, I've got storage, I've got JDBC, oh, I want Microsoft SQL Server as well. So you can see here on the start.spring.io, we've already got a number, a handful of complement of the Azure dependencies here for you to use. But, but, but, but, but, not all of them. And that's because it would be an exhausted, to be exhausted, we'd have to have dozens and dozens of checkboxes. So what's most important is that you get this support dependency here, that'll bring in the Maven Bill of Materials dependency that then in turn, you can use to import without qualification, almost all of your dependencies. Save for one, I'm gonna show you one, I'm gonna actually have to manually add dependencies to my build, which, you know, I can hear you gasp, to be able to make this application work today. So let's hit generate, and go to the downloads directory here. Okay, uoazur.zip, that'll start up in my IDE. Doesn't all that much matter what IDE you're using, obviously. And if you're unfamiliar with Spring, then what you need to know is that we care about integration, we care about being open. So, you know, we don't want our experience, you know, we don't want your productivity experience to be contingent on some IDE tooling, right? So, everything I'm gonna show you here can work with Eclipse or NetBeans or the open source community edition of IntelliJ, or whatever, okay? Now, I've got a number of different dependencies here that I need that I've got already in my class path, but I'm gonna add a few more, okay? I need just a few more. So what I'm gonna do is I'm gonna cheat a little bit, I'm gonna copy and paste, if you will, to bring all those dependencies in, okay? So, forgive me for a second. All right, let's see, pasting. Okay, good. So there's my dependencies, some of them are duplicated, right? You can see I've got the Azure Spring Boot Starter. Obviously, that's a common dependency. Don't need that, it's already there once. Anytime there's a yellow highlight there, that means it's duplicated in the declaration. Not strictly speaking a problem, it's just a warning, right? There's the Azure Storage Spring Boot Starter, I want that, but I've already got it twice, don't need it again. Don't need the Azure Spring Boot web support. Sorry, the Spring Boot web support, don't need the JDBC support. Again, duplicate, duplicate, duplicate. And there we go, that seems to be better. So now, the only things that are different is I've added this, this is a Microsoft Azure Spring Cloud Stream Binding, okay? For Azure Service Bus, which we're gonna look at today. I was gonna show you the native API, and in previous versions of this talk, I've actually shown the native API for Azure Service Bus, which doesn't look, it's weird. Azure Service Bus has some of the most brilliant people in the industry, because my background is messaging, so I love Azure Service Bus. It's got some of the most brilliant people in the industry working on it. Clement Vasters is, for example, one of the people that helped to build it, and it looks and feels very much like AMQP, and I think you can even use it like AMQP or JMS. But I figured I would just show the native API, because otherwise you'd just be watching an AMQP demo. But recently, they've been watching, they've been, sorry, they've been building a Service Bus binding for Spring Cloud Stream. So I'm gonna show you that today, but that's not yet part of the release train, and there's a couple of reasons for that, I think. I'm conjecturing. I think that the dependencies here, right now, are Spring Boot dependencies, whereas this is very clearly in the Spring Cloud train. So at some point, there's gonna be an aggregate, I hope, Spring Cloud Bill of Materials thing, that's my hope, my goal, I would love to see that. And then that'll bring in all the Spring Boot stuff and all the Spring Cloud stuff, right? Okay, so we've got that, we've got the storage dependency here, we've got the core Spring Boot startup. That is actually, we've done it, it's implied. This is implied by all the other ones, but never hurts to have it. We've got Microsoft SQL Server, our dependency there, and then that's about it. The other thing that you need is the dependency management section, right? That's done for you by the Spring Boot, the Spring Initializer starts at Spring but after that, I think we're all, we're okay, we've got, I'm gonna be using Cosmos DB here, but I'm gonna use the MongoDB driver, that's one of the nice things about Cosmos DB, okay? So the other thing we're gonna need is some configuration and this is, I think, the best and worst part of Azure for me, okay? And what I mean by that is every single thing in Azure has its own configuration, its own connection strings, its own way of saying, hey, you're gonna connect to this thing. It'd be nice if that was just done for me, you know? If I could authenticate one and then, you know, not have service-specific usernames and passwords, right? If you use, if you use AWS, they have a very, very, very verbose security model that relies on permissions and roles and entitlements and all this kind of stuff. It's exhaustive, but it is exhausting as well, right? It can be very tiresome to try and figure all that out. So I think that's a little overbearing for the average use cases, you know, it's locked down to the point where you can, you can't be productive unless you spend weeks trying to automate the security, right? On the other end of the spectrum is something like Google Cloud, which you've got one authentication. If you log in once, then suddenly everything's available to you, right? There's no, it's, you can lock things down, but by default, things are just nice and easy and easy to use and you have to connect it just once. You connect to Google Cloud and everything that Google Cloud that has to offer is available to you and you don't have to authenticate or send passwords and museums and all that stuff. But on the other hand, they have a much smaller set of stuff, right? Google Cloud is a very small curated list of services whereas AWS and Azure are much more in the, here's everything you could possibly want, kind of the end of the continuum, right? So what I've had to do is I've had to provide configuration, connection strings, and this is stuff that I have in my local environment. I'm not gonna show you these connection strings in my property file. You might accidentally see some of them as we look at some of the screens today, as we look at some of the screens in the portal, but you know, I don't wanna give them away if I don't have to. These portals, this portal is how I'm gonna drive everything, but keep in mind, Microsoft Azure can be very easily manipulated if you use Terraform, if you use the native CLI, there's a very nice CLI that you can use for Azure Sprincite as well as for all the other Azure infrastructure. So whatever suits your fancy, right? Whatever works for you. Okay, now let's talk about some of the common use cases here. Obviously we're gonna start with a low hanging fruit, the kind of stuff that is fairly familiar to everybody, right? So let's talk about talking to Microsoft SQL Server. I've got a Microsoft SQL Server instance over here, so if I go over here, you go to SQL databases and you can configure SQL database, then actually that's configuring a SQL database, then you have to configure the database instance. You have a SQL server, then you have the database, and you have to configure the credentials and all that stuff, right? You have to configure that when it launches so that you can then log in to that using the information that you've been given, right? So if I look here, do I have, that's my database. One thing you're gonna need to remember is to set the server firewall or rather if you're doing it on your local machine, as I am, make sure you set up a rule to exempt a particular IP address. Because again, here by default it's locked down, for better or for worse, I understand why it's just a little off-putting if you're trying to get started quickly. And then otherwise, you've just got something there. You've already got an instance and you can talk to it. You can configure your SQL clients to work with it and so on. There's a query editor here. You would need the password, so I'm not gonna, do I have the password? It's easy for me to get that password. I have the password, but suffice it to say, I've got a table in there, which has a, it's called customers. It's a single table called customers that has three rows in it. So it's customers with an ID and a name. So what I'm gonna do is I'm gonna create a simple application that talks to that. And again, nothing fancy here. Very just, very straightforward stuff. You've seen this kind of stuff before. I'm saying connect to Azure, connect to Microsoft SQL Server using Azure and using JDBC. Again, if you've ever used any kind of JDBC infrastructure, then this is not particularly surprising, right? I'm sure you've seen this before. I don't know why I'm showing you SQL Server instead of Postgres. I suspect more people are using Postgres, but, and I love Postgres, and you can get Postgres in MySQL on Microsoft Azure, but Microsoft SQL Server, it holds a special place in my heart, right? It's short and sweet. It's like, it's legendary. That thing has been around forever. And sure, you can run it for yourself, but wouldn't you rather that Microsoft, who of course built it, do that for you, right? Or at least they took over it since CyBase, right? So it's a fully managed thing. How cool is that, right? You don't see that kind of solution in other contexts. Imagine buying a car that you can drive as fast as you would like and on which the manufacturer will guarantee you any and all maintenance and repair, right? That's what you're getting here. Even if the car is hit with an asteroid, they're gonna make sure you're okay, right? This is why running Microsoft SQL Server on Microsoft Azure is so appealing to me. The drudgery of ownership is removed, right? This is why a lot of people rent houses instead of buying homes, even though, lucratively, financially, it's a much better deal to buy a home. They just don't wanna deal with the upkeep. They don't wanna have to clean the hedges or cut the hedges and drain the pipes and so on. So the burden of ownership is gone. And obviously SQL Server in its own right is amazing. It's been around since 1989, right? So it's probably older than a lot of people in this audience, it's routinely ranked up there with the likes of Oracle's database and PostgreSQL is being among the most feature-filled databases out there. It's been built over decades to serve enterprise use cases and it's even got things that other databases, including the venomable PostgreSQL sometimes lack, right? PostgreSQL only recently had a really good story for transparent data encryption. But of course, that was one of those things that's built into SQL Server for decades, right? Just really, really amazing. So SQL Server, of course, has its background, its origins as an enterprise-grade database that run on one operating system, which was, who can guess? I can't see any hands, but if any of you suggested Windows, eh, you're wrong, right? It's actually OS2. So it actually worked on OS2 first and then Microsoft joined Ashton Tate, was it? I think Ashton, something in Sybase in the late 1980s to create a variant of Sybase SQL Server that worked on IBM's OS2 that was jointly developed by Microsoft at the time. The first version of Microsoft SQL Server that we know of today, and that served as Microsoft's entry into the enterprise-level database market, competing against Oracle and IBM and other databases, came out at version 6.0 and it was designed for Microsoft Windows NT. So again, long history, just a really amazing thing. And as a person that has been in a lot of startups, I've always said, gosh, I wish I could have access to a, like a SQL Server license, right? I wanna be able to use this in my database. If you're a small company and you can use my SQL or PostgreSQL, of course you're gonna do that, right? But there are some things I've always just said, gosh, I wish I had access to that thing. So now I really like that I can just use this just there, right? So let's go ahead and build an application that talks to SQL Server. I won't spend a lot of time here because it's a trivial toy demo, but customer. Private string, we're gonna create a string. We have a string column and an integer ID of primary key. And the ID here is an, it's just a, I don't even think we have to do that, right? Yeah, let's just do this, just do a DTO kind of thing. And I'm gonna create a required arts constructor and create some getters for the object as well. They're using mum buck. So there you go, that's the essence of what I'm trying to express here. What I need to be able to see that in action is to create a listener, an event listener. So SQL Server demo, okay? And I'm gonna create an event listener, application, ready, event, class, public void, go SQL Server, go, right? There you go. And add component and so on. So now I'm going to, in order to be able to make this work, I'm going to use the venerable JDBC template, right? From spring. This template is a, it's been around forever. It's been around for like 18 years, right? It's one of those things that everybody in spring is used at some point or another. It's super useful. And one of the things that made so convenient was making, talking to JDBC, less painful, way less painful, right? So select all from customers is the table. By the way, you can do this if you want DBO.customers, right? You can do that if you wanna do that, but you know, why would you, right? Okay. And what I'm gonna do is I'm gonna take each row that comes back and map it into a custom object and then just work with it, right? So log it out, customer, okay? Good stuff. So there's this. That'll give me a collection of objects. Let's see here. Customers, good, new customer. And RS.getInteger is ID, RS.getStringName and voila. That's the entire thing, okay? That's the entire SQL Server demo. Make the font a little bit smaller there. There you go. When the Spring application context starts up, it's gonna see this. Spring boots automatically gonna, it's gonna hydrate a connection for me to my SQL Server instance there. And we're good to go. Let's do that. Run. Oh, I didn't print anything out. I got the database name. I got the data, but I didn't visit each record. So let's do that quickly here. It is so cool that I can just use, I can pay as I wanna go and use my access SQL Server. That means it's just accessible to any startup. If one of the world's best databases, by far, you can just now use it. That's, to me, that's super cool. There you go. There's three records from SQL Server. Not a big, not a fancy thing. I just want you to know how easy it is to do. The next thing I wanna show is, of course, you know, we've got SQL, but you know, I already mentioned, and it feels a pity to not show Cosmos DB. So Cosmos DB is a really, really interesting piece of technology. Cosmos DB was a, it is a database that was designed recently, right? And a lot of people originally were a little put off by the fact that it supports so many different protocols. How could something support so many different protocols and APIs and be good at any of them? And it turns out, yeah, actually, it is really, really good. Microsoft SQL Server is a great database, but yes, you could have run that yourself. You could have run that on your own local machine at your own data center. You don't need Microsoft to do that. But in order to get some of the scale and some of the guarantees that Azure Cosmos DB gives you, you need something, you need somebody to operationalize that in the data center. That's where Microsoft's Cosmos DB can be very interesting. I always say, and of course, you know, apologies to President John F. Kennedy that you should ask not what you can do for your platform, but what your platform can do for you. Azure can do a lot here. You don't need to look too much further than Microsoft's Azure Cosmos DB. Cosmos DB refers to a suite of technologies, of course. It describes a single product that can be used in multiple ways. It's a single, multimodal, multi-paradigm database that supports SQL queries, graph data access, Cassandra documents, you know, documents, sorry, columnar kind of data and so on. According to the product page, you know, Cosmos DB was built from the ground up with global distribution and horizontal scale at its core. It guarantees single digit millisecond read and write latencies at the 99th percentile and guarantees 99.999 high availability with multi-homing anywhere in the world, all backed by, of course, Microsoft's industry leading and comprehensive service level agreement. In Cosmos DB internally, Cosmos DB stores items in containers, so this is a very similar to collections and sorry, sorry, very similar to documents and collections in MongoDB. You don't necessarily deal with items or containers as the concepts, but they are serviced in the language of the data model that you're using to consume the data. And in the portal as well, so when you're creating things like that, you'll have to deal with it, right? Containers are grouped into databases, which are sort of like a namespace that are above containers. And containers can enforce unique key constraints to ensure the integrity of the data, but containers can also do so much more. You can ask each container for, for example, a feed of what's changed. You can use that, for example, for change data capture schemes where you use the deltas of the changes to then do CQRS, things like that, right? Really, really interesting possibilities. You can put time to live values, caching values for data in the containers so that Cosmos DB will automatically expand existing records after a certain period. You could also override the time to live for specific individual items as well. And so all that is super cool. It's schema-less, that's the thing. It supports multiple kinds of schema, but it itself is fundamentally schema-less. So keep that in mind when using it, right? Keep it in mind because some important ramifications come out of that if you're not prepared. Cosmos DB supports a lot of different ways to talk to it. You can actually use the REST API if you want, or you can use a SQL-like database driver. I could actually do another JDBC demo talking to Cosmos DB if I want to. But instead, what I'm gonna use is I'm gonna use a MongoDB-like API. You can also use the Cassandra API if I wanna talk to it as tables, talk to it in terms of containers and rows as items, right? If you wanna use that, you can. You can even use the Cassandra query language, which I think is super cool. So you can use SQL as well as the Cassandra query language. You can also use it using Azure Table Storage API, right? It's supporting tables as containers and items as well. Just items, right? Azure Storage items. So we're gonna use that here. And again, it's another example of me showing you something really cool that looks like something that's not really cool. I mean, MongoDB is really cool, of course, but there's nothing fancy about it, and that's what I love about this, right? We've got a MongoDB running on a local, we've got that configured here, Spring Data MongoDB database, beautiful Cosmos DB, and then URI here, Azure Cosmos DB MongoDB URI. I've got that here. So if I go back to all services, Cosmos DB, okay, beautiful Cosmos DB. And do I have, oops, nope, Data Explorer. Can I explore? There you go. Reservations, documents, and so on. So there's all, you can actually query it. This is kind of like the query editor for that. I've got a lot of records there you can see. Doesn't matter, okay? Now, I'm gonna use this, very similar. I've got the MongoDB jar on the class path, so nothing special required to make it work. The data that I have in that database is of type reservations. It's document type called reservation. And I'm gonna map it to this Java object here. It's gonna have a monotone, it's gonna have a UUID rather, ID, and it's gonna have an ID and a name. I'm using Spring Data MongoDB, I think. So I'm gonna make sure I've got that in the class path. Yeah, there it is. Okay. At ID, good, at documents. That's a Spring Data MongoDB annotation. Obviously I want getters and setters and all that kind of stuff. So I'm gonna create a all args constructor and no args constructor and at data and so on. I'm also gonna create a Spring Data repository, right? The repository handles the tedious, soul, niliting, deboring, read, write, update, delete, use cases. So reactive, sorry, not reactive, just a code repository, right? For objects of type reservation with keys of type string. And then from there, I've got this. I can do Cosmos, TB, demo, okay? Same idea as before, it's Spring Bean that will listen for an event and then when the event is published, the application context will invoke this. So go Cosmos, TB, go. And I'm gonna inject the repository there to do the work of talking to that database, okay? So we say this type reservation repository find all and then for each record that comes back, I'm just gonna print out the results as before, okay? So fairly straightforward. Let's restart that. And we should see in addition to talking to SQL Server, we're now actually talking to, whoops, we're now actually talking to Cosmos, TB in terms of the MongoDB interface. How cool is that? Okay, there's our customers. Where are the reservations? Did I get something important? Maybe I should clean up. Let me choose something simpler here. I'll do a stream.ofabc. And then I'm gonna map each one into a new reservation, like so, and I'll map that into a record that gets saved into the database, like so, okay? So, R, and then for each one of those, I'm gonna log the results, okay? So I'll use system output line instead. Now, we start, that way I'll actually ensure that I have data of the right type in the database. I don't think I had any, maybe those records for other kinds of data. There we go. There's my reservations. They got IDs. So obviously I created them with a null. They went to the database, they came back with IDs. So that means that they visited the database, did all from my SQL data store. Good, so now we've got two different things there. Another thing that I'm gonna wanna do at this point is suppose I've got a microservice and I want one microservice to be able to talk to another. I could create an HTTP rest endpoint, certainly, but a very common way to do this is to use messaging, right? A lot of use cases, stage event driven architecture, EVA event driven architecture, CQS command query responsibility segmentation. So a lot of different stories there, a lot of different opportunities there, but I'm gonna create a Spring Cloud Stream powered integration with the Azure service bus, right? So Spring Cloud Stream, actually just service bus demo, there you go, service bus demo. And here, what I'm gonna do is I'm gonna launch the message based on an HTTP call, so public void send. So when somebody makes an HTTP get, I know it's not very restful, but when somebody makes a call to the HTTP get endpoint, I wanna see data being responded to, I wanna see data being processed. And that the thing that's gonna consume, the data that's gonna be produced by the send endpoint, is gonna be an event listener. So I'm gonna create an event listener here, saying public void consume. And here, I'll just have a stream listener. So what I'm gonna do is I'm gonna use Spring Cloud Stream, and Spring Cloud Stream is an abstraction. It's an abstraction that allows you to say that I have a backing message thing and it can produce data, it can consume data, and I can do so in terms of these generic channels. Now, if you've ever read the Epic Enterprise application integration book written by Gregor Hope, by the by, spends a lot of his time in Singapore, I think he's got, I think he lives there now, so it changes, but at one point he lived there, right? Yeah, he's living in Singapore. Yeah, there you go. I bumped into him by accident, I was presenting in Singapore last year, I was like, hey buddy, I wasn't expecting to see him. I was actually presenting at his, the office that he was working at, at the time, right? And I was like, oh, you work here, that's so random. I bumped into my friend from like 10 years in the, just in the middle of Singapore, how cool is that? Okay, so. Just in case you have 10 minutes left. I know. Okay, that's fine. Okay, so I'm gonna send a message out in order to do that, I need to inject a reference to a source, a source is a producer of messages, that producer is only possible if I have a binding, right? So what I'm gonna tell Spring Cloud is I'm gonna say, I've got a source and a sync, and okay, that's it, good. These sources and syncs are, they map to, they have their interfaces that have a definition for an output channel, and the other one is an input channel, and they correspond to these stream bindings, Spring Cloud stream binding input, that's the channel interface you saw in the code there, corresponds to the actual queue in Azure service bus called messages queue, and the output channel corresponds again to messages queue. So I'm gonna be, it's gonna be, I'm gonna send data on out to messages queue, and I'm gonna consume data from messages queue, right? So arguably it should be like that, okay? I have that binding in my configuration code, but not in my Java code. My Java code is written in a generic fashion, independent of the backing message queue. So if I wanted to switch this to Kafka, or Revitem queue, or Google Cloud PubSub, again, no Java code would need to be recompiled, I could just change those properties, and everything would continue to work. So var message equals message builder, and here I'm gonna say, hello, beautiful Azure at instant now, come on, you can do this, there, okay? And I'm gonna send that message using the channel. So source.send, output.send message, okay? So I'm sending the message there, and when the data comes back in, I'm gonna send it by invoking an HTTP endpoint, and then that's gonna obviously be routed to a consumer, and I'm gonna have the same class also be a consumer, just to keep the demo simple, and so I'm gonna consume the incoming message, which is gonna have a payload of type string, and here I can get access to the headers, right? Okay, org spring framework messaging, get the headers, and I can visit each one of those, so system.out.printline, right? Oh, no, that's not gonna work, it's gonna be keys value, isn't it? Key value, system.out.printline, okay? Equals B, okay? So there's that, and then I can print out the message payload itself, okay? So let's try that. Let's restart the application, see what we get. Alrighty, now we have to go to the send endpoint, localhost send, and there you go. So I opened up a channel to that, let me do it in slow-mo here so I can actually have things lined up. I'm gonna hit refresh, and you can see that it instantly populates with more data, so every time I hit send, it's creating a new record and sending it out to the cloud, and coming right back to my local machine, and I can see these things, they're now communicating with each other, and they're doing so in a generic sort of fashion. And lastly, as we round our tour, I wanna show you one more thing, I wanna show you how to write stuff to the Azure Object Store JPI, and this one, I'm gonna actually use the native API. This is gonna look very similar to nothing, right? This is just gonna be the native Azure Object Store JPI. So add component, class, object storage demo, and here I'm going to just, what am I gonna do? I guess I can do it in the constructor, right? Why not? I'll just do that there. I'm going to inject a bean, I'm gonna inject a resource, right? I'm gonna tell Spring to find a thing that produces bytes and give me a reference to it in terms of the generic resource abstraction, and I'm gonna use that to then copy that data to get an input stream and then copy that data into the cloud, okay? So container URL, container URL. And in order for this work, I need to have a cat JPEG. So I'm gonna go back to my console here, and I'll take the local file that I've got prepared for this. We're gonna talk to the block blob storage mechanism in Azure, okay? So I happen to think that this cat, most efficiently and correctly epitomizes what it means to be a block blob. So here's my cat. Perfect block blob cat. So what I'm gonna do is I'm gonna send that thing to the cloud, all fluffy and blocky and all that stuff. We're gonna say file copy utils. That's a Spring frame of class, by the way. It's very useful if you've never used it before. And I'm gonna copy the data from the resource, get input stream, okay? And I'm gonna tell Java to ignore the throwable that's being created there. There's the bytes, okay? And I'm gonna take those bytes, I'm gonna upload it to the platforms. I'll say container URL.creepblock blob, block blob URL, okay? Cat, bootiful cat.jpg, okay? And then I'm gonna upload it. And the data that I'm gonna upload is the bytes. And I'm gonna use this reactive flowable API. So flowable.justbytebuffer.wrap. So this part always gets me bytes, please, okay? And then just the length, I think. And then null, null, done yet? No, no more? Okay. And then from there, block and get to get the response and just log it out. So system out upload response dot to string. Okay, now what's the issue? Do you see the problem? It's looking for bytes. So flowable.justwrap, bytes, creepblock blob URL upload. So what is it looking for? It's looking for bytes.length, isn't it this? I've got one parameter extra, that's what it is. So this and then, okay, good. So let's run this and see what we get. Now I've got a zero Cosmos DB, I've got a storage here. Storage, accounts, is that it? Beautiful storage and open explorer. I had to explore. You can run the explorer containers, please. Cats, there's beautiful cat that was uploaded at 5.58 in 17 seconds. Local time, it's now 5.58 in 35 seconds. There's the beautiful cat. Download, please, quickly. There you go, there's our block blob cat. Thank you, my friends, for your time. I hope you got something out of it. Obviously we've only begun to scratch the surface. Key takeaways, Azure is an exhaustive, amazing platform that has been matched only by the beauty of the integration for Spring users. The most compelling feature always behind a technology is the team that works on it. And I know that the team at Microsoft are keen on making this a first class citizen and a first class experience for you. Obviously, a lot of open source stuff, I spent a lot of time showing you stuff that you could do on your local machine without Microsoft at all, right? That's the whole point. They're trying to make it so that you can run stock standard Spring applications as easily and quickly and efficiently as you can in the cloud in production at scale, scale that you wouldn't have seen before. I'm happy to answer questions at email joshlong.com or at starbucksman. Please check out Spring Boot 2.3, check out Spring Cloud for Azure, check out Grow VM support. And I just want you to stay safe, flatten the curve, be good to each other and hopefully we'll all get to see each other again. Thank you, Michael and thank you, Box Day Singapore for considering me for having invited me and for giving me the opportunity to talk to you today. Thank you, thanks a lot, Josh. And it was awesome and we'll see you guys next week with Sergio and Mo on Spring Boot 2.3.0. Thank you. Yes, bye bye. Thank you all.