Skip to content

Latest commit

 

History

History
246 lines (206 loc) · 9.74 KB

lab01.adoc

File metadata and controls

246 lines (206 loc) · 9.74 KB

Adding Spring Cloud Config to Boot Application

In this lab we’ll utilize Spring Boot and Spring Cloud to configure an application from a configuration dynamically retrieved from a git repository. We’ll then deploy it to Pivotal Cloud Foundry and auto-provision an instance of a configuration server using Pivotal Spring Cloud Services.

Import Base REST Service

  1. We’ve prepared a base project cloud-native-spring, this project will be used as the basis of this lab. Please import this existing project into your favorite IDE.

Update Hello REST service

  1. Spring Cloud Config features are introduced by adding spring-cloud-services-starter-config-client to the classpath. Open your Maven POM found here: /cloud-native-spring/pom.xml. Add the following spring cloud services dependency:

    <dependency>
    	<groupId>io.pivotal.spring.cloud</groupId>
    	<artifactId>spring-cloud-services-starter-config-client</artifactId>
    </dependency>
  2. Add an @Value annotation, private field, and associated usage to the class io.pivotal.CloudNativeSpringApplication (/cloud-native-spring/src/main/java/io/pivotal/CloudNativeApplication.java):

        @Value("${greeting:Hola}")
        private String _greeting;
    
        @RequestMapping("/")
        public String hello() {
            return _greeting + " World!";
        }

    Completed:

    package io.pivotal;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration;
    import org.springframework.context.annotation.Import;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    @EnableJpaRepositories
    @Import(RepositoryRestMvcAutoConfiguration.class)
    public class CloudNativeSpringApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(CloudNativeSpringApplication.class, args);
    	}
    
    	@Value("${greeting:Hola}")
    	private String _greeting;
    
    	@RequestMapping("/")
    	public String hello() {
    		return _greeting + " World!";
    	}
    }
  3. When we introduced the Spring Cloud Services Starter Config Client dependency Spring Security will also be included (Config servers will be protected by OAuth2). However, this will also enable basic authentication to all our service endpoints. Add the following configuration to /cloud-native-spring/src/main/resources/application.yml:

    security:
      basic:
        enabled:  false
    
    management:
      security:
        enabled: false
  4. We’ll also want to give our Spring Boot App a name so that it can lookup application-specific configuration from the config server later. Add the following configuration to /cloud-native-spring/src/main/resources/application.yml:

    spring:
      application:
        name: cloud-native-spring
  5. Complete YML:

    spring:
      application:
        name: cloud-native-spring
    
    info:
      build:
        artifact: @project.artifactId@
        name: @project.name@
        description: @project.description@
        version: @project.version@
    
    endpoints:
      health:
        sensitive: false
    
    security:
      basic:
        enabled:  false
    
    management:
      security:
        enabled: false
  6. We will also need to add dependency management to the pom.xml. Open you Maven POM found here: /cloud-native-spring/pom.xml

  7. Add the folllowing dependencyManagement section to your POM

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.pivotal.spring.cloud</groupId>
                <artifactId>spring-cloud-services-dependencies</artifactId>
                <version>1.2.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Run the cloud-native-spring Application and verify dynamic config is working

  1. Run the application

    $ mvn clean spring-boot:run
  2. Browse to http://localhost:8080 and verify you now see your new greeting.

  3. Stop the cloud-native-spring application

Create Spring Cloud Config Server instance

  1. Now that our application is ready to read its config from a cloud config server, we need to deploy one! This can be done through cloudfoundry using the services marketplace. Browse to the marketplace in Pivotal Cloudfoundry Apps Manager, https://api.sys.sandbox2.cfdish.io navigate to the space you have been using to push your app, and select Config Server:

    config scs
  2. In the resulting details page, select the standard, single tenant plan. Name the instance config-server, select the space that you’ve been using to push all your applications. At this time you don’t need to select an application to bind to the service:

    config scs1
  3. After we create the service instance you’ll be redirected to Space landing page that lists your apps and services. We’ll need to configure it to be back to a git repository. Select the manage link listed below your newly created config-server service listing. You may be prompted to login again.

    config scs2
  4. We will need to update the config-server service we just created to use a git repository. This process may take a few minutes, we can check process by running cf services until update has succeeded:

    cf update-service config-server -c '{"git": { "uri": "https://github.com/phopper-pivotal/config-repo" } }'

+ Leave all the others blank

  1. We will now bind our application to our config-server within our Cloudfoundry deployment manifest. Add these 2 entries to the bottom of /cloud-native-spring/manifest.yml

      env:
        CF_TARGET: https://api.sys.sandbox2.cfdish.io
      services:
      - config-server

    Complete:

    ---
    applications:
    - name: cloud-native-spring
      host: cloud-native-spring-${random-word}
      memory: 512M
      instances: 1
      path: ./target/cloud-native-spring-0.0.1-SNAPSHOT.jar
      buildpack: java_buildpack_offline
      timeout: 180
      env:
        CF_TARGET: https://api.sys.sandbox2.cfdish.io
        JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
      services:
      - config-server

Deploy and test application

  1. Build the application

    $ mvn clean package
  2. Push application into Cloud Foundry

    $ cf push -f manifest.yml
  3. Test your application by navigating to the root URL of the application, which will invoke the hello() service. You should now see a greeting that is read from the cloud config server!

    Bon Jour World!

  4. What just happened?? A Spring component within the Spring Cloud Starter Config Client module called a service connector automatically detected that there was a Cloud Config service bound into the application. The service connector configured the application automatically to connect to the cloud config server and download the configuration and wire it into the application

  5. If you navigate to the GIT repo we specified for our configuration, https://github.com/phopper-pivotal/config-repo, you’ll see a file named cloud-native-spring.yml. This filename is the same as our spring.application.name value for our Boot application. The configuration is read from this file, in our case the following property:

    greeting: Bon Jour
  6. Next we’ll learn how to register our service with a service registry and load balance requests using Spring Cloud components.