Spring Boot in Cloud Foundry

Introduction

This post explains the essentials in spring boot that would be helpful while deploying them in Cloud Foundry.

Cloud Foundry

Cloud Foundry is an open source cloud computing platform as a service (PaaS) originally developed by VMware and now owned byPivotal Software – a joint venture by EMC, VMware and General Electric.CF is primarily written in GO and Ruby.
Services using the Cloud Foundry platform include GE’s Predix, IBM Bluemix, CenturyLink Cloud, ActiveState, HP Helion, anynines, and Swisscom.

Spring Boot

The Spring Framework is an application framework and inversion of control container for the Java platform. Spring Boot is Spring’s convention-over-configuration solution for creating stand-alone, production-grade Spring based Applications that you can “just run”. It takes an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration. Features:

  • Create stand-alone Spring applications
  • Embed Tomcat or Jetty directly (no need to deploy WAR files)
  • Provide opinionated ‘starter’ POMs to simplify your Maven configuration
  • Automatically configure Spring whenever possible
  • Provide production-ready features such as metrics, health checks and externalized configuration
  • Absolutely no code generation and no requirement for XML configuration

Liquibase

Liquibase is an open source database-independent library for tracking, managing and applying database schema changes

Liquibase Properties in Spring Boot

Before create a micro service in Spring boot, we have to create a DB service in the Cloud Foundry. So that when we push the service create a DB and bind it to the application using manifest file.

Below is sample manifest file that binds a DB service to the application


applications:
- name: resdemoservice
memory: 512M
instances: 1
random-route: true
services:
- test-postgres-01

In above manifest, the application resdemoservice binds to service with name test-postgres-01. Next is the liquibase setup . Add the following dependencies in your maven project

<dependency>

            <groupId>org.postgresql</groupId>

            <artifactId>postgresql</artifactId>

            <version>9.4-1204-jdbc41</version>

        </dependency>

        <dependency>

            <groupId>org.liquibase</groupId>

            <artifactId>liquibase-core</artifactId>

        </dependency>

Above snippet from pom.xml pulls the liquibase and postgres dependencies. Next we have configure the DB scripts in the XML file that is understood by Liquibase.


Above image we can see that we have to create a file db-changelog-master.xml in db/changelog path under src/main/resources. Please find the sample file below

<databaseChangeLog
xmlns=“http://www.liquibase.org/xml/ns/dbchangelog”

    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:ext=“http://www.liquibase.org/xml/ns/dbchangelog-ext”

    xsi:schemaLocation=“http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd

http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd”>

    <changeSet
id=“1”
author=“Ganesh Parasuraman”>

        <sql
dbms=“postgres”
splitStatements=“true”
stripComments=“true”>

            CREATE TABLE ORDERTBL (

            id INT PRIMARY KEY NOT NULL,

            orderId VARCHAR(20) NOT NULL,

            waiterName VARCHAR(50),

            itemCode VARCHAR(50),

            itemDesc VARCHAR(200),

            status VARCHAR(20),

            quantity INT,

            rate DECIMAL,

            amount DECIMAL,

            isClosed BOOLEAN,

            billDate VARCHAR(50),

            billTime TIMESTAMP

            );

        </sql>

    </changeSet>

    <changeSet
id=“2”
author=“Ganesh Parasuraman”>

        <sql
dbms=“postgres”
splitStatements=“true”
stripComments=“true”>

            ALTER TABLE ORDERTBL OWNER TO test;

        </sql>

    </changeSet>

    <changeSet
id=“3”
author=“Ganesh Parasuraman”>

        <sql
dbms=“postgres”
splitStatements=“true”
stripComments=“true”>

            CREATE SEQUENCE order_id_seq

            START WITH 1

            INCREMENT BY 1

            NO MINVALUE

            NO MAXVALUE

            CACHE 1;

        </sql>

    </changeSet>

    <changeSet
id=“4”
author=“Ganesh Parasuraman”>

        <sql
dbms=“postgres”
splitStatements=“true”
stripComments=“true”>

            ALTER TABLE order_id_seq OWNER TO test;

        </sql>

    </changeSet>

    <changeSet
id=“5”
author=“Ganesh Parasuraman”>

        <sql
dbms=“postgres”
splitStatements=“true”
stripComments=“true”>

            ALTER SEQUENCE order_id_seq OWNED BY ORDERTBL.id;

        </sql>

    </changeSet>

</databaseChangeLog>

In above file I had used the sql tag for writing SQL scripts, we can also use alter and create table tags to do above operations in DB.

In application.properties , please add the below properties

liquibase.change-log=classpath:db/changelog/db-changelog-master.xml

Above property would make liquibase to look for xml file rather than YAML file which is standard.

Now we need to push the application to cloud. We can note that liquibase create two tables databasechangelog and databasechangelock for its usage to track the running of the scripts in that environment

We can now add more scripts to change log and it would be executed once the application is starting in the cloud foundry.

Local and Cloud Database configuration in Spring Boot

While using spring boot in cloud foundry, we often run the application in local development environment for dev testing and then push the same to CF. For creating DB connections and datasource , we can use the Spring boot profiles to distinguish between Local and Cloud. Under the sources folder I create two configuration files

  1. DataConfig that is used in Cloud
  2. LocalDataConfig that is used in Local

The dependency management should include the following dependencies

<dependency>

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

            <artifactId>spring-boot-starter</artifactId>

        </dependency>

<dependency>

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

            <artifactId>spring-boot-starter-cloud-connectors</artifactId>

        </dependency>

We need to create Data configurations for the application

@Configuration

@Profile(“cloud”)

public
class DataConfig {


@Bean


public JdbcTemplate jdbcTemplate(){

    return
new JdbcTemplate(dataSource());

}


@Bean


public Cloud cloud() {


return
new CloudFactory().getCloud();

}


@Bean


public DataSource dataSource() {


return cloud().getSingletonServiceConnector(DataSource.class, null);

}

}

Above code would create SQL JDBC template and inject into the Spring context as “jdbcTemplate”. Please note that we have tagged this class as profile “cloud”. So in DAOs we can auto wire the JDBC template as shown below

@Autowired

    private JdbcTemplate jdbcTemplate;

Now we have created cloud JDBC connectivity. In Pivotal Spring boot are started with “cloud” as the active profile, in other environment like Bluemix it is not the case so. For to solve this problem please add the following property in application.properties file

spring.profiles.active=cloud

Now we have to perform configuration such that your spring boot runs in Local environment and for that we create a local configuration as shown in code below

@Configuration

@Profile(“local”)

public
class LocalDataConfig {

    @Bean

     public JdbcTemplate jdbcTemplate(){

        return
new JdbcTemplate(dataSource());

        

     }

     @Bean

     @ConfigurationProperties(“postgres”)

     public DataSource dataSource() {

            return DataSourceBuilder.create().build();

        }

}

And add following local DB properties

postgres.url=jdbc:postgresql://{host}:{port}/dbname

postgres.driverClassName={driverclassname}

postgres.userName={username}

postgres.password={password}

As we have activated the profile ‘cloud’ in config file, we have run the application with following VM args

Dspring.profiles.active=local

Which would override the setting to run the app in cloud profile.

4 thoughts on “Spring Boot in Cloud Foundry

  1. This is the appropriate weblog for anybody who wants to discover this topic. You understand a great deal its nearly tough to argue with you (not too I actually would want…HaHa). You certainly put the latest spin using a topic thats been discussing for several years. Great stuff, just wonderful!

  2. I like what you guys are usually up too. This type of clever work and reporting! Keep up the great works guys I’ve incorporated you guys to my blogroll.

Leave a Reply

Your email address will not be published. Required fields are marked *