Enabling .NET Core Microservices with Steeltoe and Pivotal Cloud Foundry
What is Steeltoe?
Steeltoe was built to simplify the adoption of microservices for .NET developers. It provides the access to the pool of Spring Cloud and NetflixOSS tools that power cloud-native Java apps. What is more, the new toolkit promises first-class integration with Pivotal Cloud Foundry (PCF).
It also simplifies step-by-step porting of a .NET 4.x app to .NET Core microservices by making decomposition of monolithic architectures much easier. The transition results in a heterogeneous environment for the app: some of its parts may run on the Windows platform, while others can be deployed to Linux containers running on Cloud Foundry.
This post from Pivotal sheds more light on the topic, while this one demonstrates how to use Steeltoe for ASP.NET 4.x apps.
A sample .NET Core app on PCF
For this tutorial, we designed a demo app that uses the following services available on-demand from Pivotal CF:
- Config Server for Spring Cloud apps
- Service Registry for Spring Cloud apps based on Eureka
- Redis Cache
We have also built a sample microservices-based solution consisting of two .NET Core projects:
- SentimentUI provides a UI for users where they can submit messages or phrases for sentiment analysis. The project is a simple
index.html
with a script behind it sendingGET
requests to the controller. (Make sure theapp.UseStaticFiles()
method is added in theStartup.cs
file.) - SentimentAPI provides the app logic, connecting to Microsoft Cognitive Services and returning the sentiment score for the submitted message. It has only one endpoint,
/api/sentiment/{message}
, that the SentimentUI controller discovers using the Eureka service.
Note that the netcoreapp1.0
framework should be set in project.json
files for both app components.
The scope of services that can be added to this app is unlimited. We can provide APIs for various processing services, computing services, or DBs, but for the demo, I’m going to keep this app simple.
Preparing a PCF environment
We used the cf create-service
command to create service instances.
- Redis Cache:
- Config Server:
- Service Registry:
cf create-service p-redis shared-vm redCache
cf create-service p-config-server standard config-server
cf create-service p-service-registry standard myDiscoveryService
To check that the services have been installed—and whether there are any apps bound to them—run the cf services
command:
You can also use the Pivotal Apps Manager dashboard to view the installed services in a more user friendly way:
Pushing the app to PCF
The next step is to push the app to Pivotal CF and verify that the endpoints are working. First, we need to specify the buildpack used to run our app:
Go to the SentimentUI root project folder and run cf push
. The command will automatically locate the manifest and deploy the application to Pivotal CF. As shown on the screenshot above, the manifest contains a list of services. Those services will be bound automatically to the app.
The same works for the SentimentAPI project: use the cf push
command from the SentimentAPI root folder. A few minutes later an OK message should appear.
Now that we have a .NET Core app up and running on Pivotal CF, we can take a look at basic Steeltoe functionality in action.
App configuration
Our demo app relies on the following Steeltoe components:
- Configuration extension for accessing configuration parameters served by Spring Cloud Config Server
- Spring Cloud Eureka Server Client for service discovery
- Steeltoe Connector for Redis
We are going to take a mixed approach to configuring the demo app: a JSON settings file will be used to run the application locally, while Spring Cloud Config Server will be leveraged for externalized configuration.
For local configuration, add the appsettings.json
file to your projects. Below is what’s inside of my SentimentAPI’s appsettings.json
file.
As you can see from the snippet, appsettings.json
references localhost for Config Server and Eureka. However, as soon as the app is bound to Config Server settings (provided using environment variables), the local settings will be overridden.
Next is configuring the Config Server settings.
As we have already created the Config Server service instance, we can update it and specify the Git repository to retrieve configuration from. I have already created a Git repository and pushed my settings there. There is a convention and spring.application.name
specified in app.settings
is used to fetch the required configuration file from the repository. (For example, it is the sentimentapi.yml
file for the SentimentAPI project and the sentimentui.yml
file for the SentimentUI project.)
Next, I create a simple JSON file telling Config Server to retrieve the configuration settings from my Git repository.
Now, we update the server by running the following command:
cf update-service config-server -c cloudConfig.json
If we go to the Pivotal services dashboard and navigate to the Config Server manager, we will see that the settings have been applied:
Now, we need to add Config Server as a configuration source in the app’s Startup.cs
file. Make sure that you have the Steeltoe.Extensions.Configuration.CloudFoundry
package installed:
Then, add a new configuration provider to our configuration and make settings accessible from the Config
object (see the SettingFromConfig
method below):
The Config Server configuration is done—the settings will be applied to the app. Also, there is support for DI, and we can serialize the app settings into .NET classes directly and inject them down the track.
Thus, basic Config Server usage has been set. In case you experience any issues, refer to the detailed tutorials on how to get started with Steeltoe and Spring Cloud: locally or on Pivotal CF.
Service discovery
We are going to use Steeltoe’s .NET client for Eureka to register SentimentAPI and let SentimentUI discover it.
First, we need to register the SentimentAPI project on Pivotal CF using myDiscoverService (Service Registry). (To do this, we have previously added UseDiscoveryClient
to the Startup
class). Here is a part from the SentimentAPI manifest file:
By default, the shouldRegisterWithEureka
parameter is true, so it is omitted here, which means that the service registers itself. It doesn’t need to fetch the registry book.
For the SentimentUI project, the other way around, shouldFetchRegistry
is true by default. It does have to fetch the registry book, but has no need to register itself (shouldRegisterWithEureka
is set explicitly).
Now that we understand the concept behind service discovery and have the SentimentAPI project deployed, let’s check Pivotal Apps Manager:
We can see that both apps are bound to the myDiscoveryService instance.
Having the SentimentAPI service on the service dashboard list means that Eureka knows about it and will fetch its host name to any service asking for it.
When calling the service from SentimentUI, the SentimentAPI address will be resolved, and we will be able to get data from sentimentapi.pcf.den.altoros.com
.
Using connectors
Now, we are going to use Steeltoe Redis Connector. Here is how we add the Redis Cache service:
Below is the logic on the controller. Prior to fetching data from the external API, we can check Redis Cache in case someone has already been interested in just the same sentimental phrase. (It is possible, however unlikely.)
So, we have seen how .NET developers can leverage Steeltoe to enable .NET Core apps to consume Spring Cloud services right from Pivotal Cloud Foundry. With thoroughly documented components and a relatively flat learning curve, Steeltoe makes a good job of facilitating development and deployment of microservices-based .NET apps.
Check out Steeltoe’s GitHub repository to learn more about this promising tool. The source code of the sentiment manager can be found here.