 All right, thanks everyone for coming to building microservices with .NET Core and Steeltoe. Hopefully, you're in the right place. Quick introduction. I'm Matt Horan, a software engineer at Pivotal. I'm Zach Brown. I also work at Pivotal. And what we're going to talk about today, quick introduction to the .NET Renaissance. We'll talk a little bit about what is Steeltoe and why did we build it. We have a quick demo and then a roadmap and resources at the end. Please be engaged. We'd love for you to talk with us after this talk today and reach out to us on Twitter. Follow Zach or the Steeltoe project. And please engage with us. So Zach, why don't you tell us about this so-called .NET Renaissance? I don't mind if I do. All right, for some people in the open source world, when you hear the words .NET, you don't automatically think cool. Maybe you think old school. I suppose they think that all the cool kids are writing Golang and Node apps nowadays. Well, there's a lot of stuff that's been happening up in Redmond. A lot of changes are under foot. And ultimately, they make right now, this very moment, a very exciting time to be a .NET developer. In case you're not clear what I'm talking about, let me refresh your memory. Microsoft loves Linux. You can now run Bash on Windows. You can run Linux containers on Windows. I mean, who could have seen this coming? It was just a few years ago. This would have been unthinkable. I really personally, I hope, somewhere deep down inside of me that someone at Microsoft has printed up one of those Linux heart Microsoft loves Linux t-shirts and sent it to Steve Ballmer, because I'd love to see him rock that. Microsoft loves open source. To me, this is obviously another massive pivot. But to me, this is even bigger, more significant than the Linux thing. A previous incarnation of Microsoft viewed open source as competition. In fact, there were probably times that they deliberately tried to put open source out of business. So the fact that they're moving towards this model of embracing the open source community is something very significant. And as an example of that, .NET itself is now open source. It's managed by the .NET Foundation, which aims to cultivate and foster a community around .NET. It includes the .NET framework, Roslin, Xamarin, Mono, plus all sorts of community projects. And then more recently, it includes .NET Core, which is a new cross-platform set of runtimes and frameworks that runs on Windows. It runs on Linux. It runs on macOS. And of course, Visual Studio had to get in on the LoveFest. There's a full-blown Visual Studio IDE now for macOS. And they've come out with a new lightweight editor called Visual Studio Code. It runs on Mac, Linux, Windows. But wait, that's not all. SQL Server now runs on Linux. Wow, look at that. Look at all those hearts. What are we meant to take away from this? Does anybody remember when you were in school and you wrote your name and maybe somebody else's name on a piece of paper with a heart in between? Or maybe you were really serious and you carved it into a tree trunk or wrote it in wet cement? So what are we supposed to take away from all these hearts? Microsoft must be getting really serious about this stuff. All right, so what's all this about a .NET Renaissance? At the NDC conference in Oslo this summer, Ian Cooper called out the Java rejuvenation renaissance of five or six years ago and drew some parallels and said that we can draw some conclusions from that, that .NET is in the same place. So basically he said, where at one point you were seeing the JVM lose ground to Ruby and Rails as more developers started turning towards that low-friction web development experience and away from the heavy-duty enterprise app servers, suddenly there was this renaissance of projects like NetE and the Spring Framework and even Netflix OSS where there was a rich community of projects around cloud-native and 12-factor and microservices. And right now we're on the verge of such a renaissance in the .NET world. So by comparison, .NET had its 15th birthday this year, whereas Java is closer to 20 years old. So maybe in the terms of the time frame or around the same timing, you know, with the introduction of .NET Core, given Microsoft's pivot towards open source, we're really turning to a point where .NET is on the verge of this massive renaissance. So what's missing? Well, what's been missing, at least until very recently, is that rich community of cloud-native, 12-factor microservices projects. And that's where Steeltoe comes in and that's what we're going to talk to you about today. You want to tell us what Steeltoe is, Matt? Perfect. So Steeltoe is an open-source project sponsored by Pivotal that brings client libraries for Spring Cloud and Netflix OSS to .NET. It also provides tooling that makes it easy to deploy and run .NET applications on Cloud Foundry and leverage Cloud Foundry services. But before we talk about what's in Steeltoe, let's talk about why we built it. So why is Steeltoe? If you're building cloud-native .NET applications, specifically, to run on Cloud Foundry, you're going to be embracing 12-factor principles. So you want to move away from just having random application dependencies in your code base and just checking binary blobs into your code, move to something like Nougat for storing those dependency references, right? Storing configuration in the environment. So instead of hard coding database strings and other settings into your code base and then checking that in and shipping around a password to everyone, you want to move that into something like a configuration server. You don't want to be storing session state in your process. How do you scale horizontally an application that just stores that session state in memory? Then you do things like jSession ID and session pinning, right? That's not a great way to scale out your application. You need to break down tight coupling between your application and the server it's running on. Guess what? For .NET, that means you can't use the Windows registry. You don't want to use the global assembly cache, the GAC. You don't want to write things to the local file system and rely on them being there. They won't be there when you scale up or down your instance, right? And when you're using a data store, like maybe a relational database, you need to loosely couple your application to that. Again, just like configuration, you've got to find a way to inject that into the application and then swap it out based on, well, are you in Dev, Test, or Prod? Are you working locally? Are you working on Cloud Foundry? So I just got a saying, today's best practices are tomorrow's anti-patterns. Of course, that means yesterday's best practices are today's anti-patterns, right? That would follow. So what this means is there may have been things that you did five years ago in .NET that made a lot of sense. And it worked really well. And that was fantastic. But today, as you're embracing something like Cloud Foundry and you're trying to scale out your application and modernize it, maybe some of those decisions are interfering with application resiliency or scalability. And so you need to reset. Second, well, you can't go to a technology conference and not hear about microservices, right? So I promise you we'll talk about microservices. Microservices allow developers to quickly iterate on small components and divide up responsibility. What you get out of this is being able to onboard developers to a project more quickly when you've broken down a gigantic application into component pieces. You can onboard a developer to one part of the system. We'll show you a demo application where it's broken up into four components. And you have somebody working on the front end and somebody working on one of three back end services. You can quickly iterate on your test cycle. So instead of waiting for the entire integration test suite to pass and then wasting a lot of cycles there, you could just run unit tests that are concentrated on the piece of code that you're iterating on. And then you can come together at the end and just run a full suite of happy path tests, right? You can also choose the right language to solve a problem. You can do this polyglot architecture. And so say you have an application that needs to run on the desktop.net CLR, right? It requires Windows for some reason. But then you're trying to save your company money and you also want to use Linux to run some of that application. So why don't you split up your microservice so that that back end that needs access to Windows, well, that runs just fine on the desktop CLR with Windows support in Cloud Foundry. And then everything else runs on Linux. Maybe you write a node app. Maybe you write a .net core app. You can mix and match as you see fit. You can also scale components independently of each other. So if you need to scale up your front end because you're getting a lot of traffic, you scale that up. You can scale it down. You can scale up your back end all independently of each other, right? So microservices bring some great benefits to the table. They also have some challenges. So microservices, by definition, are a distributed system, right? So there's a ton of complexity underneath there. What if you're trying to find a bug in your application? Well, if it's a monolith, right? The bug is probably in that gigantic code base. So you know where it is. You can go and find it. No problem. But troubleshooting a microservice or set of microservices is kind of like solving a murder mystery. So if you're into that, it's great. It's also really easy to set global configuration and read it from anywhere in a monolith, right? You have one giant code base. You throw it in some, I don't know, what do kids like these days? XML, JSON, something like that, and it's everywhere, right? So in a monolith, that's easy. How do you do that in all of these tiny microservices? How do you get all that configuration out to every single one of those, right? Copying an XML file and checking it into a bunch of code bases is not really a good way to solve that problem. What if those microservices are in a bunch of different languages, written in different languages, right? Maybe one of them doesn't have a JSON parser. I don't know. If a microservice you depend on is running at this horizontal scale and dynamically scaling up and down, how do you find healthy instances and only route traffic to those, right? And if you have all these instances that are scaling up and down, and one of them becomes unhealthy, how do you handle that? What do you do when an instance goes offline? Well, the good news is our friends at Netflix already solved a lot of these problems. However, they solved a lot of these problems specifically for their deployment on AWS. But the Spring team, which Pivotal contributes a number of developers towards, has been working on making generic implementations for a lot of the Spring Cloud open source libraries for the Java programming language. But wait a minute. How does that help .NET developers? Well, that's why we're here. Steeltoe was built to help you build cloud-native .NET applications and leverage Spring Cloud tooling for resilient microservices. Check out all those buzzwords. Cool. All right, so let's talk about what's inside the box. First, a look at the components in Steeltoe that are geared towards building cloud-native .NET microservices, building applications that run on Cloud Foundry. So Steeltoe connectors, they simplify the process of connecting to and using backing data services on Cloud Foundry, things like MySQL, Postgres, Redis, RabbitMQ, OAuth2. They provide out-of-the-box support for discovering many of those services as long as they're bound to your application. And they also include the ability to do settings-based configuration so that developers can supply configuration settings at development time for their on their local system and then have them overridden when you push your application to Cloud Foundry. Steeltoe also includes a number of security-related services so that you can simplify things like using OAuth2-based UAA or Pivotal SSO on your application, accessing JWT-protected resources like the Cloud Controller API. Additionally, Steeltoe makes available an additional security provider. The ASP.NET Core Data Protection Library includes a keyring store. But the way that they've implemented it by default, it writes the keyring to the local disk. Since that's not a very cloud-native pattern, what the Steeltoe project does is it makes available a way for you to override that configuration and write those keyrings to a Cloud Foundry hosted Redis instance. Steeltoe also helps you manage and troubleshoot your microservice by ornamenting it with a set of standard management endpoints. These were inspired by the actuator library in Spring Boot. They're non-invasive, so you can get visibility to the problems where they're actually occurring, even if that's in production. And you can access them on an instance-by-instance basis for your microservice if your microservice is running at horizontal scale. So they include info. So this is an information endpoint. It includes a git hash. So if you're trying to solve that problem of figuring out the running instance of your application, which commit does it actually correspond to in your Git repo, then it makes that a lot easier. There's a health endpoint to see health information about your application. A trace endpoint that returns the last 100 HTTP requests and responses. And then the most powerful is the logger's endpoint. So this allows you to both see and configure in real time the logging levels of your application. As I said, on an instance-by-instance basis, all the way down to the class level in your application. So it's extremely powerful. All right. So Steeltoe also includes configuration providers. There's this .NET configuration API. It enables you to pull configuration data from a variety of sources. It loads it into a hierarchical dictionary of key value pairs that you can then access inside of your application. Out-of-the-box .NET gives you things like command line arguments and file sources like JSON files or even XML or .ini files, heaven forbid, and environment variables. But Steeltoe adds two custom providers to that list. So the first is a Cloud Foundry provider. It parses the standard Cloud Foundry environment variables and then makes them available to you as configuration data from inside your application. And then the config server provider, it enables the Spring Cloud config server to be used as a config data source. So what does that mean? What is Spring Cloud config server? According to the 12-factor principles, you're supposed to separate your configuration from your application code. Definitely, whatever you do, don't check your connection strings or other app secrets into your source control repo. But that begs the question, well, where do you put them then? Spring Cloud config server is a service that gives you a central place to manage your application's configuration values externally and then read them in at runtime. So the way it works is you push your configuration, could be stored in YAML files, for example, into a Git repo. It also supports Hashicorp Vault as a back end if you want to store application secrets in there. And then all of the changes to config are versioned. They're auditable. Then when your app comes online, it pulls the latest config values from the server. It's also possible to call an endpoint on your application that tells it to refresh configuration without having to stop and restart your application. So you can refresh config without any application downtime. All right, service discovery. Service discovery is a pattern that allows you to dynamically bind at runtime to microservices that your app depends on. This is valuable when those services are running at horizontal scale, adding and subtracting instances, constantly changing addresses, especially if those services that you're calling, they live behind a firewall and they aren't publicly addressable. So you can't rely on DNS. Steeltoe implements Netflix Eureka for service discovery. And the pattern works like this. Microservice register themselves when they come online, and whether that's because they're just been deployed or they're scaling out and in. And then the Eureka server periodically checks in to make sure they're still alive and keeps its server list up to date with healthy instances. When a consumer comes online and wants to consume one of those microservices, it first pulls the server list from the Eureka server and then gets periodic updates confirming the current state. Then your application can make calls to the microservices it depends on, even when they're ephemeral, dynamically addressed, scaling in and out, et cetera. It's built to be HA so that if the Eureka server goes offline, your application keeps a cashed copy of that list. It's able to continue to use it until Eureka server is self-healed and comes back up. And now, Histrix circuit breakers. So Steeltoe includes a full .NET implementation of Netflix Histrix Circuit Breaker. It allows your application to fail gracefully, even when a dependent microservice becomes unavailable so your users never, ever have to see some nasty error message. Histrix also includes rich metrics, as well as a dashboard, to visualize the status across all of your microservices. So a little bit more about how it works. This is a quick high-level overview. As long as the dependent service that you're calling remains healthy, the circuit breaker remains closed and all calls are passed through. When a failure threshold is reached, however, the circuit breaker opens up and falls back to a default response or data set, a default fallback behavior. And that gives the service time to recover. So it stops sending requests to that service so that it can self-heal and come back online. Every so often, the circuit breaker will switch to a half-open state where it allows your request to go through to check the status of that service. If the call succeeds, then the circuit breaker goes back to closed. OK, so just generally speaking, Steeltoe works both with .NET Core, this new Linux or cross-platform runtime, as well as .NET Framework. Works both on Windows and Linux. It works standalone. And it works running on Cloud Foundry, of course. All right, well, having said that, let's take a look at a demo. Matt, you want to show us? So I'll just walk through a quick set of architecture slides to talk about what the demo is doing, and then we'll show you how this works. So we took the Music Store reference application from the .NET community. This application is known for exercising the entity framework and ASP.NET Core. It's a monolithic application. So everything's just in one giant code base, and it's just a sample app. You can go to it. You put some stuff in a shopping cart, and you can check out. There's a library of available albums, and then that's pretty much the gist. We broke that down into multiple microservices that correspond to different business functions. And so there's a Music UI, which is just the front end. The Music Store, which is that library of albums that are available. The shopping cart service, which can hold the things that you're looking at purchasing, and an order of processing service, where you can actually check out. This is all implemented using the proxy microservice design pattern, and a single application that Music UI calls out to each of these different back end services to perform the related business functions. There's also a Redis cache for application session state to allow that Music UI to scale out to multiple instances. The application config is stored in the Spring Cloud config server. So this allows all those microservices to know what they need to do and how to do it without having that hard coded in the configuration. The configuration provider automatically injects the connection for the Spring Cloud config server into those microservices. Then we utilize Steel Toe connectors. Connectors automatically detect the back end services that each of these instances have been deployed with and configures the connections to them. So instead of having to hard code your MySQL or Redis connection string into your application, the connectors automatically instantiate the libraries and connect your application to those data stores. Service discovery is implemented using Eureka. So when each of the back end stores, the Music Store, the shopping cart, and the order processing service come online, they register themselves with the Eureka server. Then the Music UI service reaches out to the Eureka server and says, hey, where's the Music Store? OK, and then gets back the URI for that. And you can use the standard .NET HTTP library to call out to them. So it's all relatively seamless. Finally, we decorated the microservices with some management endpoints to make them easier to troubleshoot so you could turn up or down that logging. You can get the health check. You could see the Git SHA that was actually deployed and where my home directory is when I deployed the application. So let's pull this up. I need you to log in, Zach. You're going to have to drag it over to the other screen. Cool. All right, that's visible. All right, so this is the sample app. If you had just deployed that reference app, it would look exactly like this. We changed nothing with the UI, except for breaking up the back end services. So here are all the albums that are available for purchase. You can even drill in further to specific type of music. So I can go ahead and add this to the cart. So looking back at the architecture diagram, maybe. Maybe not. There's the front end, which we were just looking at, reaching out to this Music Store back end. You can swipe back to it. There you go. So then when I add this to my cart, that front end service inserted a reference into the shopping cart, now that actually got stored in this MySQL database. And if I were to go to checkout, I'm actually asked to log in. So this is in the Music Store UI. I will enter my secure password. And I'm brought to this checkout page. Now, I'm not going to bore you with filling this out. We all know how forms work. But if I were to fill this out and submit it, that would go to the back end order processing. We mentioned this Redis Store here and why that's meant to help you be able to scale out that front end application. As you can see here, I'm logged in as me. If I keep reloading the page, I'm still logged in as me. And when I go over to the application dashboard here, I see that my Music UI actually has two instances. And so because we have that Redis Backing Store for the session state, I can scale this up to 10, 1, 5, whatever. So Redis is being used as that backing store. If I go back to my applications here and look at the Music Store app, you see this icon up here is actually notifying us that this application has been extended with that Info, Health, and Logger API. So there's some additional functionality unlocked in the application manager console here. I can click on this instance and get a health check of the disk space that's available in my container and the status of my service that I'm attached to. I can also get the trace of the last 100 requests that were made to the application, including all the headers that were in the response and request. And under Settings here, I can see the SHA and the directory that this was pushed from. So if I'm trying to trace a bug down, that makes it easy. Finally, I can configure that logging level here. And this is affecting the production instance of this application. So as soon as I change this, this actually changed the logging level of the app. And so maybe under normal circumstances, I really don't want any logging. I can turn this all the way down to none. And the reason there's a little bit of lag when I push that is that that's actually sending a request out to the application and flipping that bit. This is all configured and secured using the built-in UAA in Cloud Foundry. And so random people can't just hit this, right? It's checking that I have access to this application. It's sending along an OAuth token to the application, to these endpoints to make these changes. Cool, cool stuff. So Zach, why don't you tell us a little bit about the roadmap and maybe some resources? So I think we're running out of time, so I'll be very quick. But just to give you an idea of what's coming, we're adding a couple of additional management endpoints, including the ability to pull down a thread dump or a heap dump from your running application. Very useful in troubleshooting. We're looking to implement a .NET version of Netflix ribbon to give you more flexibility in load balancing algorithms from your Eureka server, from your Eureka client, rather, and then distributed tracing as well. These slides are available on the schedule app. You can pull them down. There are links in here that help you get started, as well as some additional resources if you'd like to dig in and read some blogs. And if you happen to be attending the Spring One Platform conference in San Francisco later this year, this December, there is a two-day hands-on steel toe course we invite you to attend. All right, and on that note, I think we are done. Cool. Thank you very much. Are there any questions we can answer? There's one right there. Thank you. Does the health endpoint do they integrate with a loggergator? So the health endpoint is slightly different from loggergator. It's integrated directly into the application, and there's some specific monitoring that it's doing there. But we showed you how those actuators show up in the Apps Manager console. And so loggergator does integrate into that. But the health endpoint is separate from loggergator. One more in the back. Is there any work being done on the data store abstractions, like your CRUD interface? Could I just change a configuration parameter and move from an MS SQL database to an Oracle database, something like that? In theory, it's possible. It's not anything that we're actively working on. OK. Are either one of you use spring data stores, stuff like that? So that's a really key feature for me when using spring. I'd love to see a steel toe. Awesome. Will the distributed tracing be using Zipkin? It will most likely be using Zipkin for .NET. There's a question right in front of you. Just shortly, Eureka versus console will both be supported in the .NET version? I don't know about console. Right. So I mean, console is a very heated topic. And I'm happy to talk with you about that after. I think there's a question of how to best run console inside a container on the platform. So that's a challenge. So initially, just based on Cloud Foundry, when the spring team was looking for, how do we solve this discovery problem? Oh, Eureka looks great because it doesn't interfere with DNS, doesn't use anything like console. Now, there's some really cool roadmap stuff that you might have seen talks about today where we have the opportunity for sidecar containers. We're doing things with Istio and all that. So there's a lot of exciting stuff that's going to happen in the next year or so, where I think we're going to have a much better story here in the service discovery. But for today, console in the container, not so great. All right. Well, I think we're out of time. But if you have any other questions, please feel free to come up to us afterwards and ask. All right. Thanks again.