DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How to Activate New User Accounts by Email
  • Automate Spring Boot App Deployment With GitLab CI and Docker
  • How To Build Web Service Using Spring Boot 2.x
  • Spring Boot Pet Clinic App: A Performance Study

Trending

  • A Guide to Auto-Tagging and Lineage Tracking With OpenMetadata
  • AI Agents: A New Era for Integration Professionals
  • The Evolution of Scalable and Resilient Container Infrastructure
  • Driving DevOps With Smart, Scalable Testing
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Spring Config Integration With a PCF Application: A Step-by-Step Guide

Spring Config Integration With a PCF Application: A Step-by-Step Guide

A developer takes us through the process of integrating a Spring config file with a PCF application, including all the code you need to get started.

By 
Gitanjali Sahoo user avatar
Gitanjali Sahoo
·
Jan. 03, 21 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
14.2K Views

Join the DZone community and get the full member experience.

Join For Free

Why Spring Configuration? 

Spring Cloud Config provides support for externalized configuration in a distributed system. It allows you to dynamically push updates to configuration properties to the application without needing to restart or redeploy.

Step-by-Step Guide to Integrate With a PCF Application

Step 1: Add a Maven Dependency

XML
 




xxxxxxxxxx
1
23


 
1
<dependency>
2

          
3
               <groupId>io.pivotal.spring.cloud</groupId>
4

          
5
<artifactId>spring-cloud-services-starter-config-client</artifactId>
6

          
7
             </dependency>
8

          
9
              <dependency>
10

          
11
                    <groupId>org.springframework.cloud</groupId>
12

          
13
                    <artifactId>spring-cloud-starter-config</artifactId>
14

          
15
             </dependency>
16

          
17
             <dependency>
18

          
19
                    <groupId>org.springframework.boot</groupId>
20

          
21
                    <artifactId>spring-boot-starter-actuator</artifactId>
22

          
23
             </dependency>


pom.xml 

XML
 




xxxxxxxxxx
1
113


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
    <modelVersion>4.0.0</modelVersion>
6

          
7
    <groupId>gsahoo.demo</groupId>
8
    <artifactId>aSpringConfigDemo</artifactId>
9
    <version>1.0.0</version>
10
    <packaging>jar</packaging>
11

          
12
    <name>aspringconfig-demo</name>
13
    <description>Spring Boot with spring config</description>
14
    <parent>
15
        <groupId>org.springframework.boot</groupId>
16
        <artifactId>spring-boot-starter-parent</artifactId>
17
        <version>2.3.0.RELEASE</version>
18
        <relativePath ></relativePath> <!-- lookup parent from repository -->
19
    </parent>
20

          
21
    <properties>
22
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24
        <java.version>1.8</java.version>
25
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
26
    </properties>
27
    <dependencies>
28
        <dependency>
29
            <groupId>junit</groupId>
30
            <artifactId>junit</artifactId>
31
            <version>3.8.1</version>
32
            <scope>test</scope>
33
        </dependency>
34

          
35
        <dependency>
36
            <groupId>org.springframework.boot</groupId>
37
            <artifactId>spring-boot-starter</artifactId>
38
        </dependency>
39

          
40

          
41

          
42
        <dependency>
43
            <groupId>com.fasterxml.jackson.core</groupId>
44
            <artifactId>jackson-databind</artifactId>
45
        </dependency>
46
        <dependency>
47
            <groupId>org.projectlombok</groupId>
48
            <artifactId>lombok</artifactId>
49
        </dependency>
50

          
51

          
52
        <dependency>
53
            <groupId>io.springfox</groupId>
54
            <artifactId>springfox-swagger2</artifactId>
55
            <version>2.6.1</version>
56
        </dependency>
57

          
58
        <dependency>
59
            <groupId>io.springfox</groupId>
60
            <artifactId>springfox-swagger-ui</artifactId>
61
            <version>2.6.1</version>
62
        </dependency>
63
        <dependency>
64
            <groupId>org.springframework.boot</groupId>
65
            <artifactId>spring-boot-starter-web</artifactId>
66
        </dependency>
67
        <dependency>
68
            <groupId>io.pivotal.spring.cloud</groupId>
69
            <artifactId>spring-cloud-services-starter-config-client</artifactId>
70
        </dependency>
71

          
72
        <dependency>
73
            <groupId>org.springframework.cloud</groupId>
74
            <artifactId>spring-cloud-starter-config</artifactId>
75
        </dependency>
76
        <dependency>
77
            <groupId>org.springframework.boot</groupId>
78
            <artifactId>spring-boot-starter-actuator</artifactId>
79
        </dependency>
80

          
81
    </dependencies>
82
    <dependencyManagement>
83
        <dependencies>
84

          
85
            <dependency>
86
                <groupId>org.springframework.cloud</groupId>
87
                <artifactId>spring-cloud-dependencies</artifactId>
88
                <version>${spring-cloud.version}</version>
89
                <type>pom</type>
90
                <scope>import</scope>
91
            </dependency>
92
            <dependency>
93
                <groupId>io.pivotal.spring.cloud</groupId>
94
                <artifactId>spring-cloud-services-dependencies</artifactId>
95
                <version>2.2.1.RELEASE</version>
96
                <type>pom</type>
97
                <scope>import</scope>
98
            </dependency>
99

          
100
        </dependencies>
101
    </dependencyManagement>
102
    <build>
103
        <plugins>
104
            <plugin>
105
                <groupId>org.springframework.boot</groupId>
106
                <artifactId>spring-boot-maven-plugin</artifactId>
107
            </plugin>
108
        </plugins>
109
    </build>
110
</project>


Step 2: Add refreshscope and EnableAutoConfiguration to the Model Class

Java
 




x


 
1
package gsahoo.demo.model;
2

          
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5
import org.springframework.cloud.context.config.annotation.RefreshScope;
6
import org.springframework.context.annotation.Configuration;
7
import org.springframework.stereotype.Component;
8

          
9
@Configuration
10

          
11
@EnableAutoConfiguration
12

          
13
@RefreshScope
14

          
15
@Component
16

          
17
public class Person {
18

          
19
    @Value("${person.company}")
20

          
21
    String company = null;
22

          
23
    public void setCompany(String company) {
24

          
25
        this.company = company;
26

          
27
    }
28

          
29
    public String getCompany() {
30

          
31
        return company;
32

          
33
    }
34

          
35
}


If you are autowiring this model object in any other class then make sure to add refreshscope to that class as well.

Step 3: Enable Actuator Endpoints 

By default only the /health and /info endpoints are enabled. Enable other endpoints one-by-one by declaring explicitly or enabling them all by using a wildcard character.

Add the below line to your application.properties file to enable the /refresh endpoint:

management.endpoints.web.exposure.include=refresh 

You may additionally disable default security for this tutorial by adding the below code to application.properties file:

management.security.enabled=false

or by adding the below lines of code to your Spring Boot application:

Java
 




xxxxxxxxxx
1
16


 
1
package gsahoo.demo;
2

          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
6
import org.springframework.cloud.context.config.annotation.RefreshScope;
7
import org.springframework.context.annotation.Bean;
8
import org.springframework.context.annotation.Configuration;
9
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
10

          
11
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class , ManagementWebSecurityAutoConfiguration.class})
12
public class aSpringConfigDemoApplication {
13

          
14
    public static void main(String[] args) {
15
        SpringApplication.run(aSpringConfigDemoApplication.class, args);
16
    }


Note: For this tutorial, security is disabled in order to access actuator endpoints. In a prod environment you must consider security.

Step 4: Add a Property to the application.properties File

person.company=ABC

Step 5: Build and Deploy the App to Cloud Foundry

cf push

Run the above command from the root folder of the application. Use the manifest.yml file to declare your app name:

YAML
 




xxxxxxxxxx
1
10
9


 
1
---
2
applications:
3
- name: aspringconfig-demo
4
  memory: 1G
5
  instances: 1
6
 
7
  path: target/aSpringConfigDemo-1.0.0.jar
8
  buildpack: <provide-your-buildpack-version>
9
  disk_quota: 2G


Step 6: Create an Instance of Spring Server in CF

Select Spring Config from PCF Marketplace to create an instance.

Use JSON to enter GitLab information:

Use the below format to enter your JSON data:

  • uri  - the HTTP URL to the GitLab URL.
  • searchPaths - the GitLab URL subfolder that the application should search through for the config file. If this is not specified then the app will search in the current folder specified by the "uri" attributes. 
  • username  - user account to login to the above GitLab URL. It must have read access to the GitLab URL from where it will read the config file.
  • password - password attached to the GitLab user name.
  • label - specify which GitLab branch to use to read the config file. If not specified then it defaults to the "master branch."

Step 7: Bind Your App to the Above Service Instance

If the service instance is created successfully then it can be viewed from the Service Instance manager:

If it is successfully bound to the app then you should see a log entry as below:

Plain Text
 




xxxxxxxxxx
1


 
1
--- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-https:............................


Testing

Step 1: Add/Update the Property Value in a Config File in GitLab 

  1. Create a file named aspringconfig-demo-cloud.properties (filename follows the naming convention <application_name>-<active-profile-name>.properties) under the folder that was provided in the serachPaths property above. Be sure to put this file under the GitLab URL provided in the uri property above.
  2. Add a new value for person.company e.g. person.company=XYZ.
  3. Commit the file to GitLab.

Step 2: Call the Actuator/Refresh Endpoint to Refresh/Reload the Property

The property that was changed in Step 1 will be returned by this call. Your application now has a reference to the updated value:

How Does it Work Internally?

When a Spring bean is declared with @refreshscope, a proxy wrapper gets created for that bean. This proxy class interacts with underlying an bean class to return the value.

When a refresh event occurs in Spring:

  1. invalidate the proxy class.
  2. reload the config file.
  3. recreate the underlying bean class.
  4. return the new value.

Though this feature has the benefit of updating to a new value at runtime, care should be taken considering that on a refresh event Spring beans become invalid until re-creation. If a user is using the bean at that time they may experience a 500 error or similar error. 

File Precedence

  • Precedence rules for GitLab config files are also the same as in a regular Spring Boot application: 
    • Active profiles take precedence over defaults.
    • Profile-specific property files override the application-named property file which overrides non-specific property files such as the application.properties file or application.yml file.

If the app name is "foo" and profile name is "dev" then foo-dev.properties overrides the foo.properties file. The foo.properties file overrides the application.properties file.

When multiple files are specified, the latter ones can override the values of earlier ones.

References

http://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html

https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html

Spring Framework application Spring Boot GitLab Property (programming) Integration app

Opinions expressed by DZone contributors are their own.

Related

  • How to Activate New User Accounts by Email
  • Automate Spring Boot App Deployment With GitLab CI and Docker
  • How To Build Web Service Using Spring Boot 2.x
  • Spring Boot Pet Clinic App: A Performance Study

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!