<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sidd B</title>
    <description>The latest articles on DEV Community by Sidd B (@siddb).</description>
    <link>https://dev.to/siddb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F158839%2F1a3bfa6f-7a9f-44f0-b2be-66f1d24b2268.png</url>
      <title>DEV Community: Sidd B</title>
      <link>https://dev.to/siddb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siddb"/>
    <language>en</language>
    <item>
      <title>Microservices Registration and Discovery using Spring Cloud and Eureka</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Mon, 18 Jan 2021 01:16:00 +0000</pubDate>
      <link>https://dev.to/siddb/microservices-registration-and-discovery-using-spring-cloud-and-eureka-124m</link>
      <guid>https://dev.to/siddb/microservices-registration-and-discovery-using-spring-cloud-and-eureka-124m</guid>
      <description>&lt;p&gt; &lt;br&gt;
This blog post drives though an implementation pattern and a working setup with multiple microservices where they get registered with Eureka and the client can discover them and invoke them&lt;/p&gt;

&lt;p&gt;Table of Content&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#1_H2"&gt;What is Eureka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#3_H2"&gt;Why we need Discovery Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#5_H3"&gt;Project achievement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#7_LIS"&gt;Project Contents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#8_H3"&gt;Technology Used&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#10_H2"&gt;Discovery Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#18_H3"&gt;Article Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#27_LIS"&gt;REST Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#28_H3"&gt;Sample Response&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#32_H2"&gt;Article Client Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#41_H3"&gt;Start Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#44_H2"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bootng.com/2021/01/eureka-microservices-registration-and-discovery.html#46_H2"&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Microservices Registration and Discovery using Spring Cloud, Eureka
&lt;/h2&gt;

&lt;p&gt;This blog post drives though an implementation pattern and a working setup with multiple microservices where they get registered with Eureka and the client can discover them and invoke them&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Eureka
&lt;/h2&gt;

&lt;p&gt;Eureka is a REST-based service that provides support for discovering other services so that clients can use the Eureka service to discover services and calling those services.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why we need Discovery Service
&lt;/h2&gt;

&lt;p&gt;In a Microservices architecture where we have multiple services running, we need a mechanism to know what are the services and how to invoke them. Each service typically will have a different URL or IP address to reach out to. Also, clients of those microservices need to know when a new &lt;/p&gt;

&lt;p&gt;microservice is added or an existing microservice was taken down for maintenance. Discovery service provides that mechanism, where services can register themself in the discovery service and clients, can query the discovery service to know more about the available microservices. &lt;/p&gt;
&lt;h3&gt;
  
  
  Project achievement
&lt;/h3&gt;

&lt;p&gt;In this project, we will go through an end to end use case where we will have a client microservice calling another microservice utilizing Eureka discovery service. Essentially we want to find existing services by looking up in discovery service and then invoking the target service without knowing about their whereabouts like URL, or IP or port, etc. For that, we will build a discovery server one service microservice and one client microservice.&lt;/p&gt;

&lt;p&gt;Project Contents&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eureka Discovery Service: Provides the registration and discovery&lt;/li&gt;
&lt;li&gt;Article Microservice: Provides REST services for Article CRUD operation&lt;/li&gt;
&lt;li&gt;Client Microservice: Invokes the article microservice &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-6mZRtRh4TKQ/YATevOM9usI/AAAAAAAAAok/CKREUTiVFEwpsncis8jq45l8KDKm5ZdYwCPcBGAsYHg/s776/Eureka.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XdffChKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-6mZRtRh4TKQ/YATevOM9usI/AAAAAAAAAok/CKREUTiVFEwpsncis8jq45l8KDKm5ZdYwCPcBGAsYHg/w407-h234/Eureka.jpg" alt="" width="407" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above pictures show what we are going to achieve in very high level&lt;/p&gt;

&lt;p&gt;1) We will deploy a Discovery service&lt;/p&gt;

&lt;p&gt;2) We will deploy Article Service which registers itself with discovery service with a unique name.&lt;/p&gt;

&lt;p&gt;3) We will deploy a consumer application which is another spring boot application which will invoke the&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Article Service by its name.  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Technology Used
&lt;/h3&gt;

&lt;p&gt;Java 11&lt;br&gt;&lt;br&gt;
Apache Maven 3.5.0&lt;br&gt;&lt;br&gt;
Spring Boot 2.2.6&lt;br&gt;&lt;br&gt;
Spring Cloud Hoxton.SR1&lt;br&gt;&lt;br&gt;
Netflix Ribbon 2.3.0&lt;br&gt;&lt;br&gt;
Open Feign&lt;br&gt;&lt;br&gt;
JSON  &lt;/p&gt;
&lt;h2&gt;
  
  
  Discovery Server
&lt;/h2&gt;

&lt;p&gt;The following section highlights the important code related to Eureka Server. The details can be looked into in the git repo. Mainly we need to add the maven dependency for Eureka Discovery Server, in the spring boot properties file add the server port and defaultZone and annotate the SpringBoot Application class with @EnableEurekaServer.&lt;/p&gt;

&lt;p&gt;We need to include the Netflix Eureka Server dependency in the maven pom file. &lt;/p&gt;

&lt;p&gt;pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;spring-cloud-starter-netflix-eureka-server&amp;lt;/artifactId&amp;gt;&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;application.properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server.port=8761##Eureka Relatedeureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/eureka.client.healthcheck.enabled=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Eureka Discovery Server is a Spring Boot application that is very simple. We need to annotate the application with @EnableEurekaServer. @EnableEurekaServer allows this application to run as a Eureka server, aided by Spring Boot to instantiate Eureka-related beans based on configuration properties. &lt;/p&gt;

&lt;p&gt;ServiceDiscovery.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.bootng.service;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer@SpringBootApplicationpublic class ServiceDiscovery { public static void main(String[] args) { SpringApplication.run(ServiceDiscovery.class, args); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we build and start the discovery server and access the server through &lt;a href="http://localhost:8761"&gt;http://localhost:8761&lt;/a&gt; we would see something like bellow. Notice the following screenshots shows no entries under applications because no other services are up yet.&lt;/p&gt;

&lt;p&gt;| &lt;a href="https://1.bp.blogspot.com/-deOMCgFAhn4/YAThD-5hSLI/AAAAAAAAApo/hV6AX16anewzIetqnxeoZsjt8dIZ99pvwCPcBGAsYHg/s2223/Screen%2BShot%2B2021-01-17%2Bat%2B5.12.27%2BPM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g--zOMd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-deOMCgFAhn4/YAThD-5hSLI/AAAAAAAAApo/hV6AX16anewzIetqnxeoZsjt8dIZ99pvwCPcBGAsYHg/w640-h192/Screen%252BShot%252B2021-01-17%252Bat%252B5.12.27%252BPM.png" alt="" width="637" height="192"&gt;&lt;/a&gt; |&lt;br&gt;
| Discovery Service UI&lt;br&gt;&lt;br&gt;
 |&lt;/p&gt;
&lt;h3&gt;
  
  
  Article Service
&lt;/h3&gt;

&lt;p&gt;Now we will build and deploy the Article microservice which is another spring boot application that registers itself with the discovery service. The name with which this service is registered is "article-service" and is defined in bootstrap.properties file.&lt;/p&gt;

&lt;p&gt;pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;spring-cloud-starter-netflix-eureka-client&amp;lt;/artifactId&amp;gt;&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;application.properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Server Relatedserver.port=9051## Eureka Relatedeureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/eureka.client.register-with-eureka=trueeureka.client.fetch-registry=falseeureka.vipAddress=article-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;bootstrap.properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.application.name=article-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following is the main application class representing Article Microservice.&lt;/p&gt;

&lt;p&gt;ArticleMicroservice&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ComponentScan({ "com.siddb" })@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClientpublic class ArticleMicroservice {    public static void main(String args[]) { SpringApplication.run(ArticleMicroservice.class, args);    }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Spring Boot Application exposes the following REST endpoints through the ArticleController.java class. And registers itself with the service discovery with the name "article-service" &lt;/p&gt;

&lt;p&gt;ArticleController.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController@RequestMapping("/api")public class ArticleController { private static final Logger log = LoggerFactory.getLogger(ArticleController.class); @Autowired ArticleService articleService; @RequestMapping(value = {"/articles"}, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity&amp;lt;List&amp;lt;Article&amp;gt;&amp;gt; getArticles() throws AppException { List&amp;lt;Article&amp;gt; articles = articleService.getArticles(); return new ResponseEntity&amp;lt;List&amp;lt;Article&amp;gt;&amp;gt;(articles, HttpStatus.OK); } @RequestMapping(value = {"/articles/{id}"}, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity&amp;lt;Article&amp;gt; getArticle(@PathVariable(value = "") String id) throws AppException, NotFoundException { Article articles = articleService.getByID(id); return new ResponseEntity&amp;lt;Article&amp;gt;(articles, HttpStatus.OK); } //other methods for POST and Deleted removed from here for readability.}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;REST Endpoints&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GET &lt;a href="http://localhost:9051/api/articles/ARTICLE%5C_ID"&gt;http://localhost:9051/api/articles/ARTICLE\_ID&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;POST &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt; PAYLOAD
&lt;/li&gt;
&lt;li&gt;DELETE &lt;a href="http://localhost:9051/api/articles/ARTICLE%5C_ID"&gt;http://localhost:9051/api/articles/ARTICLE\_ID&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sample Response
&lt;/h3&gt;

&lt;p&gt;GET &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[{ "id": "America-Travel", "name": "America Travel", "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "category": "Travel" }]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GET &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sample Response: [{ "id": "America-Travel", "name": "America Travel", "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "category": "Travel" }]&lt;/p&gt;

&lt;p&gt;[{ "id": "America-Travel", "name": "America Travel", "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "category": "Travel" }]&lt;/p&gt;

&lt;h2&gt;
  
  
  Article Client Service
&lt;/h2&gt;

&lt;p&gt;Now we will build and deploy the Client Service application which is another Spring Boot application that consumes the REST services deployed by Article Service. Most interesting part &lt;/p&gt;

&lt;p&gt;pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;  &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-cloud-starter-netflix-eureka-client&amp;lt;/artifactId&amp;gt;   &amp;lt;/dependency&amp;gt;   &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-cloud-starter-loadbalancer&amp;lt;/artifactId&amp;gt;    &amp;lt;/dependency&amp;gt;   &amp;lt;!--ribbon related --&amp;gt;  &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-cloud-starter-netflix-ribbon&amp;lt;/artifactId&amp;gt;  &amp;lt;/dependency&amp;gt;   &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-cloud-starter-openfeign&amp;lt;/artifactId&amp;gt;   &amp;lt;/dependency&amp;gt;   &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;   &amp;lt;/dependency&amp;gt;&amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;application.properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hostname=localhostlogging.level.org.springframework=infologging.level.root=infospring.main.banner-mode=offserver.port=9053##Managementmanagement.endpoint.health.show-detailsmanagement.health.key.ping=enabledmanagement.endpoints.web.exposure.include=info,health,mappings##Eureka Relatedeureka.instance.leaseRenewalIntervalInSeconds=1eureka.instance.leaseExpirationDurationInSeconds=90eureka.instance.hostname=${hostname}eureka.instance.hostname.metadataMap.instanceId=${spring.application.name}:${server.port}eureka.client.register-with-eureka=trueeureka.client.fetch-registry=trueeureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/eureka.client.healthcheck.enabled=true##Eureka Ribbonarticle-service-consumer.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerListarticle-service-consumer.ribbon.DeploymentContextBasedVipAddresses=article-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following is the Consumer Application Class. We have annotated it with @EnableDiscoveryClient so that it can discover other services registered with the Discovery Server.&lt;/p&gt;

&lt;p&gt;ConsumerApplication&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ComponentScan({"com.siddb", "com.siddb.controller"})@SpringBootApplication@EnableDiscoveryClientpublic class ConsumerApplication { public static void main(String args[]) { SpringApplication.run(ConsumerApplication.class, args); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following is the main controller which uses the discovery service internally and invokes services on the service article-service using ribbon. From the ribbon configuration in (application.properties), it knows article-service-consumer is tied to a service with VIP Address (name) article-service.&lt;/p&gt;

&lt;p&gt;RibbonController.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestControllerpublic class RibbonController { @Autowired private RestTemplate restTemplate; /** * This method calls the microservice GET article-service/api/articles using Ribbon to get a list of * Articles and returns the same. it uses RestTemplate to make the API calls. * @return * @throws Exception */ @RequestMapping(value = {"render"}, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity&amp;lt;String&amp;gt; renderArticles() throws Exception { JsonNode repos = restTemplate.getForObject("http://article-service-consumer/api/articles", JsonNode.class); int counter = 1; StringBuilder result = new StringBuilder("\n List of Articles"); if (repos.isArray()) { for (JsonNode jsonNode : repos) { result.append("\n Repo ").append(counter++).append("::"); result.append(jsonNode.get("name").asText()); } } return new ResponseEntity&amp;lt;String&amp;gt;(result.toString(), HttpStatus.OK); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Consumer Controller uses the ribbon configuration that we have added in the property file to invoke the article service by the ribbon name "article-service-consumer". This is where the Consumer controller will discover the actual API for the corresponding service name. And call GET &lt;a href="http://article-service-consumer/api/articles"&gt;http://article-service-consumer/api/articles&lt;/a&gt; will be actually to &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt;. This is how using the Eureka Discovery service the client becomes independent of the service (IP address, port, etc.). The client simply can refer to the service with its published name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start Microservices
&lt;/h3&gt;

&lt;p&gt;Now the fun part, start all the microservices and invoke the /render REST API. We need to start all services (discovery service, article service, consumer service). For that, we first need to check out the repo from git and build/run each project.&lt;br&gt;&lt;br&gt;
1) git clone &lt;a href="https://github.com/siddharthagit/spring-boot-sdc"&gt;https://github.com/siddharthagit/spring-boot-sdc&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
 2) go to the root folder that contains this repo.&lt;br&gt;&lt;br&gt;
3) open 3 Terminals one for each subproject (eureka-service-discovery, ms-article-service, ms-consumer-service).&lt;br&gt;&lt;br&gt;
4) build each project and start the services.&lt;br&gt;&lt;br&gt;
 mvn clean install&lt;br&gt;&lt;br&gt;
 mvn spring-boot:run&lt;br&gt;&lt;br&gt;
5) Check the status of each service on the discovery server &lt;a href="http://localhost:8761"&gt;http://localhost:8761&lt;/a&gt;&lt;br&gt;&lt;br&gt;
 6)Invoke the REST API on consumer service &lt;a href="http://localhost:9053/render"&gt;http://localhost:9053/render&lt;/a&gt;&lt;br&gt;&lt;br&gt;
This API internally will use the discovery server to resolve the service and will route the call to &lt;a href="http://localhost:9051/api/articles"&gt;http://localhost:9051/api/articles&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:9053/render"&gt;http://localhost:9053/render&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List of Articles Repo 1::America Travel Repo 2::Asia Travel Repo 3::Europe Travel Repo 4::Road Trip Repo 5::Winter Travel Repo 6::Japan Travel&lt;/p&gt;

&lt;p&gt;| &lt;a href="https://1.bp.blogspot.com/-FiGIkc13ooY/YATgy_Ijv9I/AAAAAAAAApg/He4ovU1BULguKilrnWOIYaCxqyElLNTZACPcBGAsYHg/s2227/Screen%2BShot%2B2021-01-17%2Bat%2B5.08.16%2BPM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GiwpCcbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-FiGIkc13ooY/YATgy_Ijv9I/AAAAAAAAApg/He4ovU1BULguKilrnWOIYaCxqyElLNTZACPcBGAsYHg/w640-h288/Screen%252BShot%252B2021-01-17%252Bat%252B5.08.16%252BPM.png" alt="" title="Discovery Service UI" width="640" height="288"&gt;&lt;/a&gt; |&lt;br&gt;
| Discovery Server UI with all services running&lt;br&gt;&lt;br&gt;
 |&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we've covered how to use Spring Cloud Eureka for service discovery in the microservice/cloud environment. We created two simple REST services that communicate with each other without hardcoding any hostname/port while making REST calls. Though in this article we have shown how the client can invoke the article service with ribbon, the git repo also contains a Feign client that uses Feign and will be covered in a different article. &lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/siddharthagit/spring-boot-sdc"&gt;Git Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-eureka-server.html"&gt;Spring Cloud Eureka&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-19bxwsfmpTQ/YATgrWhaCvI/AAAAAAAAApM/PvlddlQGJLwyzczb5EULCUJ1HOs1AYU0QCPcBGAsYHg/s2223/Screen%2BShot%2B2021-01-17%2Bat%2B5.12.27%2BPM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kWhA_-1M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-19bxwsfmpTQ/YATgrWhaCvI/AAAAAAAAApM/PvlddlQGJLwyzczb5EULCUJ1HOs1AYU0QCPcBGAsYHg/s320/Screen%252BShot%252B2021-01-17%252Bat%252B5.12.27%252BPM.png" alt="" width="320" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discovery</category>
      <category>eureka</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Spring Boot Rest Template Example</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Thu, 18 Jun 2020 23:41:00 +0000</pubDate>
      <link>https://dev.to/siddb/spring-boot-rest-template-example-2j5i</link>
      <guid>https://dev.to/siddb/spring-boot-rest-template-example-2j5i</guid>
      <description>&lt;p&gt; &lt;br&gt;
In this article, we will learn how to invoke or call Rest full API's in spring boot. Essentially we are going to write a simple client to consume a few public RESTful API's. RESTTemplate is for just that, Spring's RESTTemplate is used to write client applications to consume RESTful API &lt;/p&gt;

&lt;p&gt;Table of Content&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.bootng.com/2020/06/spring-boot-rest-template-example.html#4_LIS"&gt;Technologies used&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.bootng.com/2020/06/spring-boot-rest-template-example.html#13_GIT"&gt;Github source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.bootng.com/2020/06/spring-boot-rest-template-example.html#14_LIS"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.bootng.com/2020/06/spring-boot-rest-template-example.html#15_H3"&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Consuming RESTful API in Spring Boot
&lt;/h2&gt;

&lt;p&gt;In our earlier articles, we learned how to create rest full API's . In this article, we will learn how to invoke or call Rest full API's in spring boot. Essentially we are going to write a simple client to consume a few public RESTful API's. RESTTemplate is for just that, Spring's RESTTemplate is used to write client applications to consume RESTful API &lt;/p&gt;

&lt;p&gt;In this article, we will consume two different public API. For that, we will write a standalone Spring Boot App, to consumes the REST API's as follows&lt;/p&gt;

&lt;p&gt;API 1: Get all GitHub API's&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;API 2: Get all Github repositories for user bootng&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.github.com/users/bootng/repos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Technologies Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Java 11&lt;/li&gt;
&lt;li&gt;Apache Maven 3.5.0&lt;/li&gt;
&lt;li&gt;Spring Boot 2.2.6&lt;/li&gt;
&lt;li&gt;Eclipse IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Main Application Class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.javaexp;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.slf4j.Logger;import org.slf4j.LoggerFactory;@SpringBootApplicationpublic class ResttemplateApplication { private static final Logger log = LoggerFactory.getLogger(ResttemplateApplication.class); public static void main(String args[]) { log.info("about to call ResttemplateApplication.run()"); SpringApplication.run(ResttemplateApplication.class, args); log.info("completed executing ResttemplateApplication.run()"); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first REST client is as bellow, which calls a REST endpoint and then displays results in the console. &lt;/p&gt;

&lt;p&gt;LoadAllGithubEndpoints.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.bootng;import java.util.Iterator;import java.util.Map.Entry;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.web.client.RestTemplateBuilder;import org.springframework.core.annotation.Order;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;import com.fasterxml.jackson.databind.JsonNode;/** * This Class List all the endpoints from URL https://api.github.com * */@Component@Order(1)public class LoadAllGithubEndpoints implements CommandLineRunner { private static final Logger log = LoggerFactory.getLogger(ResttemplateApplication.class); @Override public void run(String... args) throws Exception { log.info("about to call LoadAllEndpoint.run()"); RestTemplate restTemplate = new RestTemplateBuilder().build(); ResponseEntity&amp;lt;JsonNode&amp;gt; apis = restTemplate.getForEntity("https://api.github.com", JsonNode.class); StringBuilder result = new StringBuilder("\n List of Public API's"); apis.getBody().fields().next().getValue(); Iterator&amp;lt;Entry&amp;lt;String, JsonNode&amp;gt;&amp;gt; it = apis.getBody().fields(); while (it.hasNext()) { result.append("\n").append(it.next().getValue().asText()); } log.info(result.toString()); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our second REST client is as bellow, which calls a REST endpoint and then displays all the repositories for user bootng in the console. &lt;/p&gt;

&lt;p&gt;LoadGithubRepo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.bootng;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.web.client.RestTemplateBuilder;import org.springframework.core.annotation.Order;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;import com.fasterxml.jackson.databind.JsonNode;@Component@Order(2)public class LoadGithubRepo implements CommandLineRunner { private static final Logger log = LoggerFactory.getLogger(ResttemplateApplication.class); @Override public void run(String... args) throws Exception { log.info("about to call LoadGithubRepo.run()"); RestTemplate restTemplate = new RestTemplateBuilder().build(); ResponseEntity&amp;lt;JsonNode&amp;gt; repos = restTemplate .getForEntity("https://api.github.com/users/bootng/repos", JsonNode.class); int counter = 1; StringBuilder result = new StringBuilder("\n List of Repositories"); if (repos.getBody().isArray()) { for(JsonNode jsonNode : repos.getBody()) { result.append("\n Repo ").append(counter++).append("::"); result.append(jsonNode.get("name").asText()); } } log.info(result.toString()); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that LoadGithubRepo is marked with annotation Order(2) and LoadAllGithubEndpoints is marked with annotation Order(1). That means Spring will execute LoadAllGithubEndpoints first and then LoadGithubRepo.&lt;/p&gt;

&lt;p&gt;Building and Running the application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn clean installmvn spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Console Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20-June-18 16:25:17:627 INFO main c.b.ResttemplateApplication:27 - about to call LoadAllEndpoint.run()
20-June-18 16:25:18:570 INFO main c.b.ResttemplateApplication:40 -
List of Public API's
https://api.github.com/user
https://github.com/settings/connections/applications{/client\_id}
https://api.github.com/authorizations
https://api.github.com/search/code?q={query}{&amp;amp;page,per\_page,sort,order}
https://api.github.com/search/commits?q={query}{&amp;amp;page,per\_page,sort,order}
https://api.github.com/user/emails
https://api.github.com/emojis
https://api.github.com/events
https://api.github.com/feeds
https://api.github.com/user/followers
https://api.github.com/user/following{/target}
https://api.github.com/gists{/gist\_id}
https://api.github.com/hub
https://api.github.com/search/issues?q={query}{&amp;amp;page,per\_page,sort,order}
https://api.github.com/issues
https://api.github.com/user/keys
https://api.github.com/search/labels?q={query}&amp;amp;repository\_id={repository\_id}{&amp;amp;page,per\_page}
https://api.github.com/notifications
https://api.github.com/orgs/{org}
https://api.github.com/orgs/{org}/repos{?type,page,per\_page,sort}
https://api.github.com/orgs/{org}/teams
https://api.github.com/gists/public
https://api.github.com/rate\_limit
https://api.github.com/repos/{owner}/{repo}
https://api.github.com/search/repositories?q={query}{&amp;amp;page,per\_page,sort,order}
https://api.github.com/user/repos{?type,page,per\_page,sort}
https://api.github.com/user/starred{/owner}{/repo}
https://api.github.com/gists/starred
https://api.github.com/users/{user}
https://api.github.com/user/orgs
https://api.github.com/users/{user}/repos{?type,page,per\_page,sort}
https://api.github.com/search/users?q={query}{&amp;amp;page,per\_page,sort,order}
20-June-18 16:25:18:570 INFO main c.b.ResttemplateApplication:21 - about to call LoadGithubRepo.run()
20-June-18 16:25:19:069 INFO main c.b.ResttemplateApplication:36 -
 List of Repositories
 Repo 1::angular-word-merger
 Repo 2::hansini-static-deploy
 Repo 3::JUnit5-examples
 Repo 4::okhttp
 Repo 5::spring-boot-web-start
 Repo 6::springboot\_docker
20-June-18 16:25:19:071 INFO main c.b.ResttemplateApplication:57 - Started ResttemplateApplication in 3.382 seconds (JVM running for 6.625)
20-June-18 16:25:19:071 INFO main c.b.ResttemplateApplication:17 - completed executing ResttemplateApplication.run()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get source code and build&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/siddharthagit/spring-boot-resttemplate"&gt;https://github.com/siddharthagit/spring-boot-resttemplate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;cd spring-boot-resttemplate&lt;/li&gt;
&lt;li&gt;mvn clean install&lt;/li&gt;
&lt;li&gt;mvn spring-boot:run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Summary&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this article, we saw how to write a simple REST client using RESTTEmplate in Spring Boot.&lt;/li&gt;
&lt;li&gt;In our next article, we will see more use cases of using RESTTemplate like for POST/PUT, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.bootng.com/2020/06/resttemplate-quick-guide.html"&gt;RestTemplate quick guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>resttemplate</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Springboot application with Docker</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Sat, 07 Mar 2020 01:50:00 +0000</pubDate>
      <link>https://dev.to/siddharthab/springboot-application-with-docker-36ij</link>
      <guid>https://dev.to/siddharthab/springboot-application-with-docker-36ij</guid>
      <description>&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-XdY3CtcgFIs/XmLzRRt6WiI/AAAAAAAAAL8/Bu2jgMgS9qg4PXmX_ojJPQYbutqehCi0wCLcBGAsYHQ/s1600/pjimage.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CKecBCH4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-XdY3CtcgFIs/XmLzRRt6WiI/AAAAAAAAAL8/Bu2jgMgS9qg4PXmX_ojJPQYbutqehCi0wCLcBGAsYHQ/s640/pjimage.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Table of Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Technology Used&lt;/li&gt;
&lt;li&gt;Code Structure&lt;/li&gt;
&lt;li&gt;Building Docker Image&lt;/li&gt;
&lt;li&gt;Github Source Code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Docker and Spring boot Application
&lt;/h2&gt;

&lt;p&gt;This blog details the steps taken to add docker support to a spring boot application written in java.&lt;/p&gt;

&lt;p&gt;This blog is developed with&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 11&lt;/li&gt;
&lt;li&gt;Docker 19.03.5&lt;/li&gt;
&lt;li&gt;Spring Boot 1.5.9&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The spring boot application is a simple application to read all the links from a target URL and rendering the links. &lt;/p&gt;

&lt;h2&gt;
  
  
  Code Structure
&lt;/h2&gt;

&lt;p&gt;SpringBootLinkApplication.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ComponentScan&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"com.bootng"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; 
&lt;span class="nd"&gt;@SpringBootApplicationpublic&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpringBootLinkApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoggerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringBootLinkApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"about to call SpringBootLinkApplication.run()"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringBootLinkApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="nd"&gt;@Bean&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CommandLineRunner&lt;/span&gt; &lt;span class="nf"&gt;commandLineRunner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ApplicationContext&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Let's inspect the beans provided by Spring Boot:"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;beanNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBeanDefinitionNames&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beanNames&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nl"&gt;beanName:&lt;/span&gt; &lt;span class="n"&gt;beanNames&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beanName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;};&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;LinkController.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controllerpublic&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoggerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringBootLinkApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="nd"&gt;@Autowired&lt;/span&gt; &lt;span class="nc"&gt;BlogService&lt;/span&gt; &lt;span class="n"&gt;blogService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
 &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"/"&lt;/span&gt;
 &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@ResponseBody&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getHome&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inside getHome "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"GoTo \\links to see all the links \n"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"/links"&lt;/span&gt;
 &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@ResponseBody&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getHeadLines&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inside blog GET getHeadLines method"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sourceLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://www.bootng.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blogService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAllLinks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceLink&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nl"&gt;link:&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Links scanned from bootng.com \n"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@ResponseBody&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getHeadLines&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sourceLink&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inside blog GET getHeadLines method"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blogService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAllLinks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceLink&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nl"&gt;link:&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Links scanned from specified url \n"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"/test"&lt;/span&gt;
 &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@ResponseBody&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;isSerivceUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inside blog GET method"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Service is Running Fine"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;BlogLinkService.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Servicepublic&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogLinkService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getAllLinks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;();&lt;/span&gt;
   &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jsoup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;Elements&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a[href]"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Element&lt;/span&gt; &lt;span class="nl"&gt;link:&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" %s : %s"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"abs:href"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// TODO Auto-generated catch block e.printStackTrace(); } return result; }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above files are part of the main Java Classes for the Springboot application. Which defines the Application, Controller, and Service Class. Now we will add docker support to it. For that we need to add a file with name "DockerFile" to the repository as follows.&lt;/p&gt;

&lt;p&gt;DockerFile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.war

#cd /usr/local/workspace
WORKDIR /usr/local/workspace

COPY ${JAR_FILE} app.jar

# java -jar /usr/local/workspace/app.jar
ENTRYPOINT ["java","-jar","app.jar"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Building Docker Image
&lt;/h2&gt;

&lt;p&gt;Build Project and Build Docker Image&lt;/p&gt;

&lt;p&gt;Following commands will first build our Spring Boot application generate a war file, and then build the docker image containing the war file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn install
docker build . -t springboot_docker
Sending build context to Docker daemon  43.16MB
Step 1/5 : FROM openjdk:8-jdk-alpine
 ---&amp;gt; a3562aa0b991
Step 2/5 : ARG JAR_FILE=target/*.war
 ---&amp;gt; Using cache
 ---&amp;gt; e637fbb1ac39
Step 3/5 : WORKDIR /usr/local/workspace
 ---&amp;gt; Using cache
 ---&amp;gt; daa4b4a89727
Step 4/5 : COPY ${JAR_FILE} app.jar
 ---&amp;gt; Using cache
 ---&amp;gt; bd3788117296
Step 5/5 : ENTRYPOINT ["java","-jar","app.jar"]
 ---&amp;gt; Using cache
 ---&amp;gt; 118546685007
Successfully built 118546685007
Successfully tagged springboot_docker:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Execute the SpringBoot application inside the docker image with tag "springboot_docker"&lt;/p&gt;

&lt;p&gt;Previous step we build the docker image containing our Spring boot applicaiton and tagged the docker image with tag "springboot_docker". To run the dockerized application run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 8080:8080 springboot_docker
 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)
 INFO main c.b.SpringBootLinkApplication:57 - Started SpringBootLinkApplication in 4.813 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Access the Application&lt;/p&gt;

&lt;p&gt;Since the Spring boot web application is running on port 8080, open a browser and go to &lt;a href="http://localhost:8080/links?sourceLink=http://bootng.com"&gt;http://localhost:8080/links?sourceLink=http://bootng.com&lt;/a&gt;. It should print links somewhat like bellow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Links scanned from bootng.com 
 https://www.bootng.com/search/label/spring-boot?max-results=3 : spring-boot
 https://www.bootng.com/search/label/gcp?max-results=3 : GCP
 https://www.bootng.com/search/label/angular?max-results=3 : Angular
 https://www.bootng.com/search/label/Agile?max-results=3 : Agile
 https://www.bootng.com/search/label/Java?max-results=3 : Java
 https://www.bootng.com/search/label/Java?max-results=3 : Links
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Download Source code &lt;a href="https://github.com/bootng/springboot_docker"&gt;Repo&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/bootng/springboot%5C_docker.git"&gt;https://github.com/bootng/springboot\_docker.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;cd springboot_docker&lt;/li&gt;
&lt;li&gt;mvn install&lt;/li&gt;
&lt;li&gt;docker build . - t springboot_docker&lt;/li&gt;
&lt;li&gt;docker run -p 8080:8080 springboot_docker&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>docker</category>
    </item>
    <item>
      <title>Journey of Google Cloud Professional Cloud Architect Exam</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Thu, 12 Dec 2019 05:10:43 +0000</pubDate>
      <link>https://dev.to/siddharthab/journey-of-google-cloud-professional-cloud-architect-exam-4go0</link>
      <guid>https://dev.to/siddharthab/journey-of-google-cloud-professional-cloud-architect-exam-4go0</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YxXU_FMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/400/1%2ALNZ6muhckR5k7G1xzSQ4lA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YxXU_FMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/400/1%2ALNZ6muhckR5k7G1xzSQ4lA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Learning something new is always great. Initially this certification was not my goal. I was learning GCP to know different services it provides specially for hosting and Image processing for my project written in Angular and Java. Later I came to know about the certification and then though to get the Certification done.&lt;/p&gt;

&lt;p&gt;I am writing this post to share my journey of getting certified in Google Cloud Architect and material that I found helpful. I hope this post will be useful for me later or others who are interested in this certification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exam Details
&lt;/h3&gt;

&lt;p&gt;Exam Guide: Official exam guide link is here &lt;a href="https://cloud.google.com/certification/guides/professional-cloud-architect/"&gt;https://cloud.google.com/certification/guides/professional-cloud-architect/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Exam consists of 50 multiple choice questions.&lt;br&gt;&lt;br&gt;
Total Duration is 120 Minutes&lt;br&gt;&lt;br&gt;
Exam registration can be scheduled via WebAssessor&lt;br&gt;&lt;br&gt;
I got the exam result after 2 days via email.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning GCP In General
&lt;/h3&gt;

&lt;p&gt;Since I was totally new to GCP I found the following courses from coursera very useful. The first course is good specially if new to GCP. The second course is about Networking in details with many hands-on labs.&lt;/p&gt;

&lt;p&gt;Coursera GCP Architecture&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.coursera.org/specializations/gcp-architecture"&gt;https://www.coursera.org/specializations/gcp-architecture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coursera Networking Google Cloud Platform&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.coursera.org/specializations/networking-google-cloud-platform"&gt;https://www.coursera.org/specializations/networking-google-cloud-platform&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also signed up for Google Cloud platform and took advantage of the 300 Usd credit to try and learn different products.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparation For the Exam
&lt;/h3&gt;

&lt;p&gt;GCP is vast and it is getting more and more product and services.&lt;br&gt;&lt;br&gt;
Exam covers a lot of product and offerings from GCP but not all. Some of them goes deeper which needs good understanding of the product and when/how to use it. There are also questions which touches at surface level, for them having a over all idea is good to choose correct answer.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Understanding in Depth&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Case Studies&lt;/strong&gt;  : Know the official case studies and prepare a solution. A lot of questions are asked from the case studies. Going though them before the exam would be helpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM and Billing&lt;/strong&gt; : Good understanding of IAM, ACL etc, best practices etc, BigQuery IAM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Storage&lt;/strong&gt; : In-depth knowledge about Cloud storage, storage classes, Lifecycle management, How to delete/change storage class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compute Engine&lt;/strong&gt; : Details about compute engine, Snapshots/Images and how to create vm from them. Preemptible VMs, Shielded VM’s. Now we also have Cloud GPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Engine:&lt;/strong&gt; Standard vs Flexible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GKE and Kubernetes&lt;/strong&gt; : Difference between GKE, Kubernetes, Creating cluster, common K8 commands. Nodes, Pods vs Containers etc. Minimum number of nodes/vms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption/Security with GCP&lt;/strong&gt;  : Knowledge of CMEK, CSEK, Encryption for Cloud Storage/Bucket etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi cloud connectivity :&lt;/strong&gt; Peering, Direct Connect, VPN etc. Usecases when to choose one. Like VPN provides encryption, but for speed Cloud inter connect is better. Also what is the SLA?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC&lt;/strong&gt; : Networking knowledge in depth, GCP provide a number of options/solutions for network design, Shared VPC etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Different kind of LB’s available in GCP&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bigtable&lt;/strong&gt; : It is proprietary NOSQL database, understanding when to use it and best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BigQuery&lt;/strong&gt; : When to use BigQuery, best practices, Indexes etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud SQL&lt;/strong&gt; : It is managed Relational Databases, understanding different offerings, configuring replica. Different products available as part of Cloud SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack Driver&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/stackdriver/"&gt;https://cloud.google.com/stackdriver/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Datastore&lt;/strong&gt; : In-depth knowledge about Cloud datastore. How to create index. Google recently added two different mode Datastore mode and native mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disaster Recovery :&lt;/strong&gt; Design principal for disaster recovery in GCP, different kinds of replicas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Pub/Sub:&lt;/strong&gt; Understanding how and when to best use pubsub.&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/functions/docs/tutorials/pubsub"&gt;https://cloud.google.com/functions/docs/tutorials/pubsub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment Manger&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For the exam deployment manager is an important topic, understanding what it does and how to configure it would be good. Like Templating, CLI commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Different kinds of Deployments&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
General concepts like Canary deployment, Rolling deployment, Blue/Green Deployment, A/B Testing would be good to know.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Other topics that needs to be familiar with&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Transfer Appliance and Data Rehydration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/transfer-appliance/"&gt;https://cloud.google.com/transfer-appliance/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Datalab&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/datalab/"&gt;https://cloud.google.com/datalab/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dataproc:&lt;/strong&gt; It is GCP Managed Apache Spark and Apache Hadoop&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/dataproc/"&gt;https://cloud.google.com/dataproc/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud DataFlow&lt;/strong&gt;  : It is based on Apace Beam SDK&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Composer&lt;/strong&gt; : It is based on Apace Air Flow&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Armour&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/armor/"&gt;https://cloud.google.com/armor/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Loss Prevention API&lt;/strong&gt;  . How to classify and mask sensitive data.&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/dlp/"&gt;https://cloud.google.com/dlp/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance&lt;/strong&gt;  : Design for compliance PCI, HIPPA etc&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Functions :&lt;/strong&gt; Understanding of how cloud functions works.&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/functions/features/"&gt;https://cloud.google.com/functions/features/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jenkins&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://jenkins.io/"&gt;https://jenkins.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spinnaker&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
spinnaker.io&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Build&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/cloud-build/"&gt;https://cloud.google.com/cloud-build/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Run&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/run/"&gt;https://cloud.google.com/run/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud identity aware proxy&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/iap/"&gt;https://cloud.google.com/iap/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud sql proxy&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/sql/docs/mysql/sql-proxy"&gt;https://cloud.google.com/sql/docs/mysql/sql-proxy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketplace&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It is like App Store for GCP. Look into marketplace in GCP Console&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/marketplace/"&gt;https://cloud.google.com/marketplace/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Directory Sync&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We can sync with LDAP, reading about this service on GCP would be good enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools and Skd&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Understanding and uses of bq, Cloud Shell, Gsutil, kubectl, gcloud etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Links to some materials for the exam
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best practices for IAM&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/docs/enterprise/best-practices-for-enterprise-organizations"&gt;https://cloud.google.com/docs/enterprise/best-practices-for-enterprise-organizations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A GCP flowchart a day&lt;/strong&gt;  : Good to review how to choose right services&lt;br&gt;&lt;br&gt;
&lt;a href="https://medium.com/google-cloud/a-gcp-flowchart-a-day-2d57cc109401"&gt;https://medium.com/google-cloud/a-gcp-flowchart-a-day-2d57cc109401&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Solution&lt;/strong&gt; : Following is a sample solution on GCP site, they provide various other architectural solutions which are good to validate the concepts&lt;br&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/solutions/migrating-a-two-tier-web-app-to-gcp"&gt;https://cloud.google.com/solutions/migrating-a-two-tier-web-app-to-gcp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Case studies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/certification/guides/cloud-architect/casestudy-mountkirkgames-rev2/"&gt;Mountkirk Games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/certification/guides/cloud-architect/casestudy-dress4win-rev2/"&gt;Dress4Win&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/certification/guides/cloud-architect/casestudy-terramearth-rev2/"&gt;TerramEarth&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Coursera also host a certification preparation course. I did not get much time to complete the full course. But going though the sample case studies would be a good addition to validate own solution.&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.coursera.org/learn/preparing-cloud-professional-cloud-architect-exam"&gt;https://www.coursera.org/learn/preparing-cloud-professional-cloud-architect-exam&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Areas like Compute Engine, Networking, Billing, AIM, Databases, Tools for Analytics etc. are very important. For them we need good understanding of the different options available while architecting a good solution or choosing the appropriate answer in the exam. Apart from that having a good knowledge of the other product/services will be helpful to answer properly.&lt;/p&gt;

&lt;p&gt;I took notes so that before the exam i can go over them which is otherwise easy to forget.&lt;/p&gt;

&lt;p&gt;Like which products are regional/zonal&lt;br&gt;&lt;br&gt;
Choosing network design for speed requirements.&lt;br&gt;&lt;br&gt;
Different database for capacity, transaction etc.&lt;br&gt;&lt;br&gt;
Network capacities.&lt;br&gt;&lt;br&gt;
Compute engine options.&lt;br&gt;&lt;br&gt;
Cloud Datastore options.&lt;/p&gt;

</description>
      <category>googlecloudplatfor</category>
    </item>
    <item>
      <title>Setting up a static website  with GCP and Google Domain</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Mon, 01 Jul 2019 06:50:00 +0000</pubDate>
      <link>https://dev.to/siddharthab/setting-up-a-static-website-with-gcp-and-google-domain-3ko8</link>
      <guid>https://dev.to/siddharthab/setting-up-a-static-website-with-gcp-and-google-domain-3ko8</guid>
      <description>&lt;p&gt;This article will cover the setups required to publish a static website on GCP and using a custom domain from Google domain. It assumes we have some content like html page etc. to publish on GCP as static site. Although it is written for domains registered with Google domain, any other domain providers should also work.&lt;br&gt;
Assumptions&lt;/p&gt;

&lt;p&gt;We have some static resources like HTML pages to be published.&lt;br&gt;
We have secured a domain name with ownership.&lt;br&gt;
We will be using CNAME to map the domain name to the static page bucket in GCP.&lt;/p&gt;

&lt;h1&gt;
  
  
  High level steps
&lt;/h1&gt;

&lt;p&gt;1) Setting up the Custom Domain DNS to forward the request to the&lt;br&gt;
2) Setting up the Buckets on Google cloud&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting DNS on the custom domain
&lt;/h1&gt;

&lt;p&gt;We want the domain name to be mapped to GCP resource (bucket in our case holding static resources). Setting up the DNS for the custom domain is really simple, we just need to map the CNAME entry in the custom domain DNS section.&lt;/p&gt;

&lt;p&gt;Login to Google Domain and go to the DNS setup page for the respective domain. Under the Custom resource records have an entry for www to c.storage.googleapis.com as follows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---3gK-Wx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9ifi4t59ouujrufqmick.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---3gK-Wx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9ifi4t59ouujrufqmick.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we save the configuration as above we are good to go to the next section for setting up the static bucket in GCP.&lt;/p&gt;

&lt;p&gt;To know more about CNAME and how it works A vs CNAME record explains the advantages of CNAME record and how it works. &lt;br&gt;
&lt;a href="https://webdevpedia.blogspot.com/2019/06/a-record-vs-cname-record.html"&gt;A vs CNAME Record&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Buckets on Google cloud
&lt;/h1&gt;

&lt;p&gt;Create a bucket whose name matches the CNAME you created for your domain.&lt;br&gt;
For example, if you added a CNAME record pointing &lt;a href="http://www.bootng.com"&gt;www.bootng.com&lt;/a&gt; to c.storage.googleapis.com., then create a bucket with the name "&lt;a href="http://www.bootng.com"&gt;www.bootng.com&lt;/a&gt;".&lt;br&gt;
To create a bucket:&lt;br&gt;
Open the Cloud Storage browser in the Google Cloud Platform Console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.cloud.google.com/"&gt;OPEN THE CLOUD STORAGE BROWSER&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Create bucket to open the bucket creation form.&lt;br&gt;
Enter your bucket information and click Continue to complete each step:&lt;br&gt;
The Name of your bucket.&lt;br&gt;
The Storage class and Location for your bucket.&lt;/p&gt;

&lt;p&gt;Click Create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qyvij6tr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pln4jdpiwkbgfmabhmo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qyvij6tr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pln4jdpiwkbgfmabhmo1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the bucket is created we need to upload the content of the static site and then give appropriate permissions to the individual objects (files directories) or to the bucket itself.&lt;/p&gt;

&lt;p&gt;To assign permission to the bucket:&lt;/p&gt;

&lt;p&gt;Go to the list of bucket page and corresponding to the bucket just created click on the last column which will open the action menu like bellow and click on Edit bucket permissions link&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C7JST9ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f2xnovksz09fu3eqoiil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C7JST9ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f2xnovksz09fu3eqoiil.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we want to make the content of this bucket publicly available we need to grant read access to a special group called &lt;strong&gt;allUsers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xML4-N9A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6yfy2z7ik4a4fibdsalb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xML4-N9A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6yfy2z7ik4a4fibdsalb.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once this is done the bucket list will show that this bucket is available to public access.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With the above setting now when we type &lt;a href="http://www.bootng.com"&gt;www.bootng.com&lt;/a&gt; will map to the content of the bucket &lt;a href="http://www.bootng.com"&gt;www.bootng.com&lt;/a&gt; on GCP. &lt;/p&gt;

&lt;p&gt;We still need to access resources explicitly for instance if we have welcome.html then we need to type &lt;a href="http://www.bootng.com/welcome.html"&gt;www.bootng.com/welcome.html&lt;/a&gt; in the browser&lt;/p&gt;

&lt;p&gt;Few things not covered in this article are&lt;br&gt;
1) Mapping default page to the domain name -&amp;gt; so that we can just type &lt;a href="http://www.bootng.com"&gt;www.bootng.com&lt;/a&gt;&lt;br&gt;
2) Mapping subdomain to the GCP bucket -&amp;gt; so that we can just type bootng.com&lt;/p&gt;

</description>
      <category>gcp</category>
      <category>googledomains</category>
      <category>staticsite</category>
    </item>
    <item>
      <title>macOS Catalina to have zsh as default shell</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Thu, 13 Jun 2019 09:56:08 +0000</pubDate>
      <link>https://dev.to/siddb/macos-catalina-to-have-zsh-as-default-shell-2014</link>
      <guid>https://dev.to/siddb/macos-catalina-to-have-zsh-as-default-shell-2014</guid>
      <description>&lt;p&gt;Apple's #WWDC2019 (Worldwide Developers Conference) was held on June 3-7.&lt;br&gt;
macOS's next big upgrade will be called Catalina and with it comes a big change for developers.&lt;/p&gt;

&lt;p&gt;By default macOS releases till now used bash as the default shell. New user accounts in macOS Catalina will have zsh as the default shell. Zsh is an open source shell very popular and comes with a ton of features.&lt;/p&gt;

&lt;p&gt;Zsh is very popular in dev community and can be installed in pre Catalina macOS as well. Zsh and Iterm2 (&lt;a href="https://www.iterm2.com"&gt;https://www.iterm2.com&lt;/a&gt;) goes very well together and improve the developer productivity.  &lt;/p&gt;

</description>
      <category>catalina</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Deploying Angular App to GCP</title>
      <dc:creator>Sidd B</dc:creator>
      <pubDate>Sat, 08 Jun 2019 09:33:00 +0000</pubDate>
      <link>https://dev.to/siddb/deploying-angular-app-to-gcp-1dp2</link>
      <guid>https://dev.to/siddb/deploying-angular-app-to-gcp-1dp2</guid>
      <description>&lt;p&gt;This article provide steps that to deploy an Angular App to Google GCP AppEngine.&lt;br&gt;&lt;br&gt;
I will be deploying a frontend Angular App (&lt;a href="https://github.com/siddharthagit/angular-word-merger"&gt;Angular Word Combiner&lt;/a&gt;) with does not need any backend.&lt;br&gt;&lt;br&gt;
Bellow is the screenshot of the Application that we would be deploying.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-Ib0K1VJD0gU/XPtj3J4ws9I/AAAAAAAAAGk/bw6OLSErfGcMflm9ZeuL_xNGI323f4obQCLcBGAs/s1600/Screen%2BShot%2B2019-06-08%2Bat%2B12.29.09%2BAM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NCNyitfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-Ib0K1VJD0gU/XPtj3J4ws9I/AAAAAAAAAGk/bw6OLSErfGcMflm9ZeuL_xNGI323f4obQCLcBGAs/s640/Screen%252BShot%252B2019-06-08%252Bat%252B12.29.09%252BAM.png" alt="" width="640" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google offers 2 options to deploy your application on GCP  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google App Engine&lt;/li&gt;
&lt;li&gt;Google Compute Engine&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here I will be using Google App Engine to deploy the Word-Combiner App. App Engine is the Googles managed platform to deploy application. App Engine comes in two flavors Standard and Custom. I will  be using App Engine Standard.&lt;/p&gt;

&lt;p&gt;First get the Word Combiner APP from git repo to local disk.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/siddharthagit/angular-word-merger.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to create a config file that will be used by Google Cloud App Engine to deploy the project. Now go to the directory and add the app.yaml file. The name of the file needs to be app.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and paste the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# [START runtime]runtime: nodejs8handlers:- url: / static_files: dist/index.html upload: dist/index.html- url: / static_dir: dist# [END runtime]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to build the Angular app so that it generates the production artifacts that would be deployed to App Engine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng build --prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-H-zp63RwXdQ/XPtuATJcEAI/AAAAAAAAAGw/icnfZv5uyEktilczV9pFf_iDmHmYJFwvQCLcBGAs/s1600/Screen%2BShot%2B2019-06-08%2Bat%2B1.12.29%2BAM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lN6H10fR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-H-zp63RwXdQ/XPtuATJcEAI/AAAAAAAAAGw/icnfZv5uyEktilczV9pFf_iDmHmYJFwvQCLcBGAs/s640/Screen%252BShot%252B2019-06-08%252Bat%252B1.12.29%252BAM.png" alt="" width="640" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-8k4kEpnB4kc/XPtvIU2nAGI/AAAAAAAAAG4/OwRHzZmxuPcTSUFCnQyWUHUuzC9M0ZJyACLcBGAs/s1600/Screen%2BShot%2B2019-06-08%2Bat%2B1.17.23%2BAM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4f1EwPCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-8k4kEpnB4kc/XPtvIU2nAGI/AAAAAAAAAG4/OwRHzZmxuPcTSUFCnQyWUHUuzC9M0ZJyACLcBGAs/s640/Screen%252BShot%252B2019-06-08%252Bat%252B1.17.23%252BAM.png" alt="" width="640" height="214"&gt;&lt;/a&gt;&lt;br&gt;
 Go to the Google Cloud Console and login with your Google account. Create a new project for your angular app deployment e.g. angular-word-merger &lt;br&gt;
&lt;a href="https://1.bp.blogspot.com/-qL5js6g5g2E/XPtz_e27woI/AAAAAAAAAHE/MQz8ZQkzcyMsj1gG-PRBO56dVpjLYNDSgCLcBGAs/s1600/Screen%2BShot%2B2019-06-06%2Bat%2B10.19.05%2BPM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ove3lJJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-qL5js6g5g2E/XPtz_e27woI/AAAAAAAAAHE/MQz8ZQkzcyMsj1gG-PRBO56dVpjLYNDSgCLcBGAs/s640/Screen%252BShot%252B2019-06-06%252Bat%252B10.19.05%252BPM.png" alt="" width="640" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-sO8pd5YlQwE/XPtz_wG0ixI/AAAAAAAAAHU/dqlVrUZZFHkWE2dE0ZtMwX86FsGnpgy2wCEwYBhgL/s1600/Screen%2BShot%2B2019-06-06%2Bat%2B10.49.35%2BPM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ht_ou2D7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-sO8pd5YlQwE/XPtz_wG0ixI/AAAAAAAAAHU/dqlVrUZZFHkWE2dE0ZtMwX86FsGnpgy2wCEwYBhgL/s640/Screen%252BShot%252B2019-06-06%252Bat%252B10.49.35%252BPM.png" alt="" width="640" height="376"&gt;&lt;/a&gt;&lt;br&gt;
 Second step, is to install the Google Cloud SDK. Follow the steps at &lt;a href="https://cloud.google.com/sdk/"&gt;https://cloud.google.com/sdk/&lt;/a&gt; so that we can deploy our application via command line. For Mac following the instructions in &lt;a href="https://cloud.google.com/sdk/docs/quickstart-macos"&gt;https://cloud.google.com/sdk/docs/quickstart-macos&lt;/a&gt; to download the SDK locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcloud app deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-E1g1uX7rhdQ/XPt6odsirTI/AAAAAAAAAHc/C90HcdNVC5w6zZKLIiYbQ3H-Tklvk3BzgCLcBGAs/s1600/Screen%2BShot%2B2019-06-08%2Bat%2B2.06.01%2BAM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CH9RnQR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-E1g1uX7rhdQ/XPt6odsirTI/AAAAAAAAAHc/C90HcdNVC5w6zZKLIiYbQ3H-Tklvk3BzgCLcBGAs/s640/Screen%252BShot%252B2019-06-08%252Bat%252B2.06.01%252BAM.png" alt="" width="640" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if you goto &lt;a href="https://angular-word-merger.appspot.com"&gt;https://angular-word-merger.appspot.com&lt;/a&gt; it should load the Angular App from GCP.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>gcp</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
