{"id":8655,"date":"2021-01-23T23:35:05","date_gmt":"2021-01-23T23:35:05","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=8655"},"modified":"2021-01-24T00:07:42","modified_gmt":"2021-01-24T00:07:42","slug":"eureka-server-using-steeltoe-revisited","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/eureka-server-using-steeltoe-revisited\/","title":{"rendered":"Eureka Server (using Steeltoe) revisited"},"content":{"rendered":"<p>The Eureka server is used as a registry for maintaining lists of services and their endpoints. It&#8217;s used a lot in the microservice world by way of a microservice registering it&#8217;s existence somewhere (in this case in Eureka). When a client (whether it&#8217;s another service or anything else for that matter) want to access a service it asks the registry for an instance, in this case we connect to the Eureka server and find the services instance(s) that are available for a specific application name and are ofcourse UP.<\/p>\n<p><strong>Installing and running Eureka Server<\/strong><\/p>\n<p>In a previous post <a href=\"https:\/\/putridparrot.com\/blog\/spring-boot-eureka-server\/\" rel=\"noopener\" target=\"_blank\">Spring boot Eureka server<\/a> we wrote a Java application to run a Eureka server. In this post we&#8217;re going to use Docker to host the server and then use Steeltoe with .NET to interact with the instance.<\/p>\n<p>To get an image of Eureka server, let&#8217;s use the Steeltoe docker image (Spring and others exist, the Steeltoe image is not intended for production, but is fine for what we want to do)<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndocker pull steeltoeoss\/eureka-server\r\n<\/pre>\n<p>Now run up the docker image using<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndocker run --publish 8761:8761 steeltoeoss\/eureka-server\r\n<\/pre>\n<p>If all goes well, connect to the Spring Eureka dashboard using<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nhttp:\/\/locahost:8761\r\n<\/pre>\n<p>change localhost to the ip\/host you&#8217;re running the Eureka server from, now you should now see the Spring Eureka web page.<\/p>\n<p><strong>Registering a .NET core client with Eureka<\/strong><\/p>\n<p>I&#8217;ve a post on this topic <a href=\"https:\/\/putridparrot.com\/blog\/a-net-service-registered-with-eureka\/\" rel=\"noopener\" target=\"_blank\">A .NET service registered with Eureka<\/a>, but let&#8217;s go through the process again with the current version of Steeltoe (as the NuGet packages have changed somewhat).<\/p>\n<ul>\n<li>Create an ASP.NET Core Web Application, as this will represent a REST service that we want to interact with. My project is called RegisterExample and is an API project.<\/li>\n<li>Add the NuGet package Steeltoe.Discovery.ClientCore and Steeltoe.Discovery.Eureka<\/li>\n<li>In Startup.cs within ConfigureServices add the following\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nservices.AddDiscoveryClient(Configuration);\r\n<\/pre>\n<\/li>\n<li>Within the Configure method add the following\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\napp.UseDiscoveryClient();\r\n<\/pre>\n<\/li>\n<li>Finally add the following to the appsettings.json file\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\/\/ Eureka info\r\n  &quot;eureka&quot;: {\r\n    &quot;client&quot;: {\r\n      &quot;serviceUrl&quot;: &quot;http:\/\/localhost:8761\/eureka\/&quot;,\r\n      &quot;shouldFetchRegistry&quot;: &quot;false&quot;,\r\n      &quot;shouldRegisterWithEureka&quot;: true,\r\n      &quot;validateCertificates&quot;: false\r\n    },\r\n    &quot;instance&quot;: {\r\n      &quot;appName&quot;: &quot;weatherapi&quot;,\r\n      &quot;port&quot;: &quot;8080&quot;,\r\n      &quot;ipAddress&quot;: &quot;localhost&quot;,\r\n      &quot;preferIpAddress&quot;: true\r\n    }\r\n  }\r\n<\/pre>\n<\/li>\n<\/ul>\n<p><em>We&#8217;re going to leave the API with the default weatherapi, hence the appName in the appsettings.<\/em><\/p>\n<p>Notice we set the value for &#8220;shouldFetchRegistry&#8221; to false as this service will not be acting as a client to any other services. Obviously change this is you also need to discovery other services. &#8220;shouldRegisterWithEureka&#8221; is set to true as we want this service to automatically register itself with Eureka.<\/p>\n<p>Now navigate to the URL of your Eureka server again (or refresh) and you should see a new Application. In my case I have an application with the name <em>weatherapi<\/em>. This name comes from our appsettings.json configuration application\/name.<\/p>\n<p><strong>Info and Health<\/strong><\/p>\n<p>If you click on the instance link within the Eureka server dashboard, you will navigate to<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nhttps:\/\/localhost:5001\/info\r\n<\/pre>\n<p>(or whatever ip\/hostname and port your service is running on) you get a 404, so let&#8217;s fix that in our project.<\/p>\n<p>Info, by default will display some basic information about the application, product version etc. However you can also add further custom information if you want, but example the git build SHA1 hash or just some general info. <\/p>\n<ul>\n<li>Add NuGet package Steeltoe.Management.EndpointCore<\/li>\n<li>In Startup.cs ConfigureServices, add the following\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nservices.AddSingleton&lt;IInfoContributor, MyInfoContributor&gt;();\r\nservices.AddInfoActuator(Configuration);\r\nservices.AddHealthActuator(Configuration);\r\n<\/pre>\n<p>The first of these lines will add our implementation of an IInfoContributor to allow for custom info.\n<\/li>\n<li>\nStill in Startup.cs, but now the method Configure, add the following to the UseEndpoints endpoint routes<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nendpoints.Map&lt;InfoEndpoint&gt;();\r\nendpoints.Map&lt;HealthEndpoint&gt;();\r\n<\/pre>\n<\/li>\n<li>\nNow we&#8217;ll create a simple implementation of and IInfoContributor which allows us to add our own info, so add the following class<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class MyInfoContributor : IInfoContributor\r\n{\r\n   public void Contribute(IInfoBuilder builder)\r\n   {\r\n      builder.WithInfo(&quot;MyInfo&quot;, new { SomeName = &quot;Scooby Doo&quot; });\r\n   }\r\n}\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>Now when we run our service we hope to see our info data, however by default Steeltoe seems to set the info and health endpoint to \/actuator\/info and \/actuator\/health respectively. Eureka seems to expect \/info. So go to the appsettings.json and add the following to the Instance section<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n&quot;StatusPageUrlPath&quot;: &quot;\/actuator\/info&quot;,\r\n&quot;HealthCheckUrlPath&quot;: &quot;\/actuator\/health&quot; \r\n<\/pre>\n<p><em>Note: I&#8217;m not sure what I&#8217;m missing here and why the defaults don&#8217;t match up, but these configuration changes will tell the Eureka server (when we register our service with it) that it should use these paths for info and health.<\/em><\/p>\n<p>Now, if you run the service again for \/actuator\/info you should see something like this<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{&quot;MyInfo&quot;:{&quot;someName&quot;:&quot;Scooby Doo&quot;},\r\n&quot;applicationVersionInfo&quot;:{&quot;ProductName&quot;:&quot;RegisterExample&quot;,\r\n&quot;FileVersion&quot;:&quot;1.0.0.0&quot;,&quot;ProductVersion&quot;:&quot;1.0.0&quot;},\r\n&quot;steeltoeVersionInfo&quot;:&quot;ProductName&quot;:&quot;Steeltoe.Management.Endpoint&quot;,\r\n&quot;FileVersion&quot;:&quot;3.0.2.0&quot;,&quot;ProductVersion&quot;:\r\n&quot;3.0.2\\u002B4089779c66d127f40325a3be9b613149b3b090f2&quot;}}\r\n<\/pre>\n<p>and health something like<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{&quot;status&quot;:&quot;UP&quot;,&quot;details&quot;:{&quot;liveness&quot;:{},&quot;diskSpace&quot;:{&quot;total&quot;:4000769372160,\r\n&quot;free&quot;:3889734168576,&quot;threshold&quot;:10485760,&quot;status&quot;:&quot;UP&quot;},&quot;eurekaServer&quot;:\r\n{&quot;remoteInstStatus&quot;:&quot;UNKNOWN&quot;,&quot;fetchStatus&quot;:&quot;Not fetching&quot;,&quot;heartbeat&quot;:\r\n&quot;Successful&quot;,&quot;heartbeatStatus&quot;:&quot;UP&quot;,&quot;heartbeatTime&quot;:&quot;2021-01-23T20:40:44&quot;,\r\n&quot;status&quot;:&quot;UP&quot;,&quot;applications&quot;:&quot;NONE&quot;},&quot;readiness&quot;:{}}}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The Eureka server is used as a registry for maintaining lists of services and their endpoints. It&#8217;s used a lot in the microservice world by way of a microservice registering it&#8217;s existence somewhere (in this case in Eureka). When a client (whether it&#8217;s another service or anything else for that matter) want to access a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,102,240],"tags":[],"class_list":["post-8655","post","type-post","status-publish","format-standard","hentry","category-c","category-docker","category-eureka"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=8655"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8655\/revisions"}],"predecessor-version":[{"id":8672,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8655\/revisions\/8672"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=8655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=8655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=8655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}