Pivotal Cloud Foundry Tutorial - Deploying Spring Boot + MySQL Application to PCF | JavaInUse



Pivotal Cloud Foundry Tutorial - Deploying Spring Boot + MySQL Application to PCF

In previous tutorial we had deployed a Spring Boot Application to PCF.
In this tutorial we will develop a Spring Boot + MySQL Application and deploy it to PCF. We will be creating a Spring Boot + MySQL Application using JDBC and testing it locally. We have already seen Spring Boot MYSQL JDBC basics in a previous tutorial For deploying on PCF, we dont need to install MySQL on the PCF cloud. On PCF there is a concept of services where on demand resources like MySQL and RabbitMQ can ordered and directly bound to the application. We will see how this is done.
Spring Boot CF Push

Pivotal Cloud Foundry - Table Of Contents

Pivotal Cloud Foundry Tutorial - Quick Introduction Pivotal Cloud Foundry Tutorial - Setting up the Development Environment Pivotal Cloud Foundry Tutorial - Deploy Spring Boot Application Hello World Example Pivotal Cloud Foundry Tutorial - Understanding PCF Deployment Architecture Pivotal Cloud Foundry Tutorial - Deploying Spring Boot + MySQL Application to PCF Pivotal Cloud Foundry Tutorial - Deploying Spring Boot + RabbitMQ Application to PCF

Lets Begin-

Creating and testing Spring Boot + MySQL application locally

The project will be as follows-
Spring Boot JDBC Maven PCF
Add the spring-jdbc-starter dependency.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>boot-jdbc</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>boot-jdbc</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

In the application.properties file specify the datasource properties
spring.datasource.url=jdbc:mysql://localhost/bootdb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always
Create the schema-mysql.sql file and specify the initialization scripts-
DROP TABLE IF EXISTS employee;

CREATE TABLE employee (
  empId VARCHAR(10) NOT NULL,
  empName VARCHAR(100) NOT NULL
);

INSERT INTO employee(empId,empName)values("emp001","emp1");
INSERT INTO employee(empId,empName)values("emp002","emp2");
INSERT INTO employee(empId,empName)values("emp003","emp3");

Create the Employee Domain class
package com.javainuse.model;

public class Employee {

	private String empId;
	private String empName;

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", empName=" + empName + "]";
	}

}
Create the DAO interface.
package com.javainuse.dao;

import java.util.List;

import com.javainuse.model.Employee;

public interface EmployeeDao {
	List<Employee> getAllEmployees();
}
The DAO implementation class.
package com.javainuse.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import com.javainuse.dao.EmployeeDao;
import com.javainuse.model.Employee;

@Repository
public class EmployeeDaoImpl extends JdbcDaoSupport implements EmployeeDao {

	@Autowired
	DataSource dataSource;

	@PostConstruct
	private void initialize() {
		setDataSource(dataSource);
	}

	@Override
	public List<Employee> getAllEmployees() {
		String sql = "SELECT * FROM employee";
		List<Map<String, Object>> rows = getJdbcTemplate().queryForList(sql);

		List<Employee> result = new ArrayList<Employee>();
		for (Map<String, Object> row : rows) {
			Employee emp = new Employee();
			emp.setEmpId((String) row.get("empId"));
			emp.setEmpName((String) row.get("empName"));
			result.add(emp);
		}

		return result;
	}
}
Create Service interface to specify employee operations to be performed.
package com.javainuse.service;

import java.util.List;

import com.javainuse.model.Employee;

public interface EmployeeService {
	List<Employee> getAllEmployees();
}

The Service class implementation.
package com.javainuse.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.javainuse.dao.EmployeeDao;
import com.javainuse.model.Employee;
import com.javainuse.service.EmployeeService;

@Service
public class EmployeeServiceImpl implements EmployeeService {

	@Autowired
	EmployeeDao employeeDao;

	public List<Employee> getAllEmployees() {
		List<Employee> employees = employeeDao.getAllEmployees();
		return employees;
	}

}

Create the Controller class to expose a GET API which fetches the employee records
package com.javainuse.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.javainuse.model.Employee;
import com.javainuse.service.EmployeeService;

@RestController
public class EmployeeController {

	@Autowired
	EmployeeService empService;

	@RequestMapping(value = "/employees", method = RequestMethod.GET)
	public List<Employee> firstPage() {

		return empService.getAllEmployees();

	}

}
Finally create the class with @SpringBootApplication annotation.
package com.javainuse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.javainuse.service.EmployeeService;

@SpringBootApplication
public class SpringBootJdbcApplication {

	@Autowired
	EmployeeService employeeService;

	public static void main(String[] args) {
		SpringApplication.run(SpringBootJdbcApplication.class, args);
	}
}
Start the application. And got to localhost:8080/employees

Spring Boot PCF JDBCTemplate Example

PCF Deployment-

In Cloud Foundry, services are on demand resources that users can provision and use for their deployed application.
Examples of resources services provide include databases on a shared or dedicated server, or accounts on a SaaS application. These resources are known as service instances and the systems that deliver and operate these resources are known as Services. Think of a service as a factory that delivers service instances.
Services can either be
  • User Defined Service
  • MarketPlace Service
For this example we will be needing the MySQL MarketPlace service.
PCF market services

Provisioning MySql Service using PCF Web Console

  • Login to Pivotal Cloud Foundry with your credentials
    Pivotal Web Services Home
  • Go to Services tab for our development space
    Cloud Foundry Services
  • Click on Add New Service and type MySQL.
    Cloud Foundry MySQL Service
  • Select ClearDB MySql
    Cloud Foundry MySQL ClearDB
  • Select the free plan free Spark DB.
    Cloud Foundry MySQL ClearDB Free

Creating Manifest Configuration file to Bind our Maven Project to PCF SQL Service

Previously when deploying the application to PCF using the cf push command, we had given the required configuration like location if the jar file as command line arguments.
     cf push test-environment -p target\employee-producer-0.0.1-SNAPSHOT.jar
     
There are other configurations like memory, application name,PCF services to be bound which can be specified as command line arguments.
A much better way to specify this is as a configuration file named manifest.yml. Manifest is the blueprint of the application to be deployed in PCF. Manifests provide consistency and reproducibility, and can help us automate deploying apps.
PCF manifest file
In our eclipse jdbc project create a manifest configuration file as follows-
name: SpringBootMySql
path: target\boot-jdbc-0.0.1-SNAPSHOT.jar
memory: 1G
services:
  -mysqldb

Push the application to PCF

  • Open the command terminal and use the following command
         cf login
         

    Cloud Foundry Login
  • It will ask for Cloud Foundry API. Enter The following API value-
         https://api.run.pivotal.io
         

    Cloud Foundry Login API
  • Next it will ask you for the Cloud Foundry credentials
    Cloud Foundry Credentials
  • Use the command cf push-
         cf push
         

    Spring Boot MySQL Push
The application is deployed on PCF. Go the PCF Web Console. Our new application will be up and running.
Spring Boot MySQL Running App
Select the application and go to the specified route. Append /employees to the route url. Our application is up and running.
Spring Boot MySQL Output

Download Source Code

Download it -
PCF- Spring Boot+MySQL