Deploying Spring Boot Applications on RedHat’s OpenShift

I’ve been deploying majority of my Spring Boot powered applications on RedHat’s OpenShift for it’s simplicity and flexibility.

Based on the Spring Boot Documentation, Deploying to OpenShift should be easy as 1,2,3 .http://docs.spring.io/spring-boot/docs/current/reference/html/cloud-deployment-openshift.html

**Taken From The Documentation**

Ensure Java and your build tool are installed remotely, e.g. using a pre_build hook (Java and Maven are installed by default, Gradle is not)

Use a build hook to build your jar (using Maven or Gradle), e.g.

#!/bin/bash
cd $OPENSHIFT_REPO_DIR
mvn package -s $OPENSHIFT_DATA_DIR/settings.xml -DskipTests=true

Add a start hook that calls java -jar …​

#!/bin/bash
cd $OPENSHIFT_REPO_DIR
nohup java -jar target/*.jar --server.port=${OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP} &

Use a stop hook (since the start is supposed to return cleanly), e.g.

#!/bin/bash
source $OPENSHIFT_CARTRIDGE_SDK_BASH
PID=$(ps -ef | grep java.*\.jar | grep -v grep | awk '{ print $2 }')
if [ -z "$PID" ]
then
    client_result "Application is already stopped"
else
    kill $PID
fi

However, before we configure our hooks above. We must first reconfigure our M2_repository to a writable directory.

cd $OPENSHIFT_DATA_DIR
echo -e  "<settings>\n  <localRepository>$OPENSHIFT_DATA_DIR</localRepository>\n</settings>\n" > settings.xml
 mvn install -s $OPENSHIFT_DATA_DIR/settings.xml

and voila. You’re done. You can now easily deploy your Spring Boot Powered Applications on OpenShifts DIY Cartridge.

Advertisements

Microservices with Spring

Purpose of this article is to provide examples and to demonstrate building a microservice applications using common patterns with Spring Boot and Spring Cloud Netflix OSS(Zuul, Eureka, and Feign), Hibernate, and JJWT

The Project has been taken from one of my previous projects I’ve built as a Monolith. I will not be including the whole application. Only some components of it.

Source code can be found here

Architecture

 

1-QnEUoCAR7T-7VFaguGFj-w

 

Notes:

All services will have their own database( Identity management service, Ticketing Service, and Customer Service)

Building Our Services — Functional Services

Functional Services are services that provides the core business logic of our application.

Identity Management Service (authentication-service)

The Identity management service that handles token issuance, persisting user information such as roles, username, password, and etc. We can roll up our own or use an existing identity management API like Auth0.

We start off by placing an annotation on our Main class

@SpringBootApplication
@EnableEurekaClient
public class FriflowAdminApplication {
   public static void main(String[] args) {
      SpringApplication.run(FriflowAdminApplication.class, args);
   }
}

The annotation  @EurekaClient specifies that our application is a subscriber of an Existing Eureka Server. Where it will automatically register itself as a service.

We can configure it’s settings with our application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: ${vcap.services.eureka-service.credentials.uri:http://127.0.0.1:8761}/eureka/

Side Note:

As long as Spring Cloud Netflix and Eureka Core are on the classpath any Spring Boot application with @EnableEurekaClient will try to contact a Eureka

The eureka.client.serviceUrl.defaultZone is the address of our Service Registry where our EurkeClient, which is the Identity Management Service will automatically register itself.

To name our service we specify it on our bootstrap.yml

spring:
  application:
    name: authentication-service

Core Business Logic

As the core logic of this service lies in this package

1-Qw2umexvL2rYkMoQOJ20RA

Once we’ve validated the user who’s requesting an to our api. We would then issue an Authentication token using JWT which can be found inside the JwtTokenIssuerService

@Override
public String issueToken(String userName) {

    final long nowMillis = System.currentTimeMillis();
    final long expMillis = nowMillis + (ONE_MINUTE_IN_MILLIS * TOKEN_DURATION_IN_MIN);

    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);
    Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

    return Jwts
            .builder()
            .setIssuedAt(new Date(nowMillis))
            .setExpiration(new Date(expMillis))
            .setSubject(userName)
            .setIssuer(issuer)
            .signWith(signatureAlgorithm, signingKey).compact();

}

You can know more about JWT here, and JJWT here.

And then we have a base REST Controllers that performs our CRUD and some little information processing within these given packages

1-_ATnYL8n6XMaa7f-Pctc3A

Workflow Management Service (ticketing-service)

We can think of the ticketing service as a Ticketing System or a small workflow management system that issues various types tickets such as quotation tickets which contains product inquiries, pricing, materials used. This where most or business processing occurs/execute.

We start off again with our basic configuration

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"org.brightworks.friflow.repo"})
@EntityScan(basePackages =
        {"org.brightworks.friflow.domain",
         "org.brightworks.friflow.domain.process"
        })
@ConditionalOnClass({SpringSecurityDialect.class})
@EnableEurekaClient
@EnableDiscoveryClient
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).run();
    }
}

Ticketing Service/Workflow Management Service Domain ERD

1-jQS-oewiCjxbPgwADatmAw

Some Our API Endpoints/Controllers are specified under this package

1-aURVKJDEGpGMBV_6LFz5Xw

Building our Services — Infrastructure Services

There are several patterns in distributed systems that can aid us in making our Functional/Core services work together. Spring cloud provides those tools to implement some of those Patterns.

Service Registry and Service Discovery

We will be using Eureka as our Service registry, Where all of our services will be self-registered. Another way to think about Service Registry is a phone-book of our existing services.

It’s now easier to set up our Service Discovery Code thanks to Spring Cloud Eureka.

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
   public static void main(String[] args) {
      SpringApplication.run(EurekaServerApplication.class, args);
   }
}

We configure it as follows.

server:
  port: ${PORT:8761}

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

We’re simply saying we will register this Eureka Server at Port 8761. and eureka.client.registerWithEureka means Eureka Server is not going to register itself as a client.

All of our services will be self-registered. No need to add more configurations to what we did above. Upon running you’ll see all of the services registered with Eureka.

 

1-PEyvuEfs62WnNg4LCCSzkQ

Building our Services — Infrastructure Services. Putting it all together

Edge Service/Api Gateway

Edge service will act as the main entry point of clients. It’s primary purpose is to aggregate results from different services, act as a proxy, and perform authorization using JJWT. We will be using Feign, Zuul, and Ribbon for this purpose.

It is suggested that we implement oauth2 with JJWT but For simplicity, we will be only using JJWT and use a filter component to implement authorization.

We start first by specifying our Application config

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
@EnableZuulProxy
public class FriflowApiGatewayApplication {

   @Value("${jwt.security.key}")
   private String jwtKey;

   public static void main(String[] args) {
      SpringApplication.run(
FriflowApiGatewayApplication.class, args);
   }

   @Bean
   public FilterRegistrationBean filterApiBean() {
      FilterRegistrationBean registrationBean = new   FilterRegistrationBean();
      ApiAccessFilter securityFilter = new ApiAccessFilter(jwtKey);
      registrationBean.setFilter(securityFilter);
      registrationBean.addUrlPatterns("/api/*");
      return registrationBean;
   }
}

@EnableFeignClients — Annotation responsible for scanning interface if they are annotated with @FeignClient

@EnableDiscoveryClient — Annotation responsible for activating whichever Discovery client available in our classpath(In this case, Netflix Eureka Discovery Client)

@EnableZuulProxy — Will turn the this application as a reverse proxy that forwards requests to other services.

The filterApiBean is the bean we use to perform filtering of unauthorize requests. It basically checks if it has a JJWT token, and if it’s still valid.

Forwarding the requests to appropriate services — Identity Management Api

Our Api Gateway will now be the main entry point of our clients(e.g mobile devices. another webapp and etc)

In order for us to to forward requests to ticketing-service. We would need first to retrieve an access token from our identity management service.

zuul.routes.authentication.path=/authentication-service/**
zuul.routes.authentication.serviceId=authentication-service
ribbon.eureka.enabled=true

In the configuration above we will be proxying all requests that’s coming from /authentication-service/ to authentication-service. Notice how we did not specify the url our authentication-serivce(identity management api) Thanks to eureka and ribbon it will automatically forward the requests to the existing/available server

To retrieve an access token we can send a posts request to http://localhost:8082/authentication-service/login

 

1-nN7Vo0LHmsPAnXl8N0qUng

once we have entered a valid username and password. We will receive a token.

Forwarding the requests to appropriate services — Ticket Management API

For this example. Although we can use the Zuul proxy as we did above. We will use Feign client. This can be useful if we want to aggregate results/get results from different services.

@FeignClient("ticketing-service")
public interface QuotationClient {

    @RequestMapping(method = RequestMethod.GET,value = "/quotations/dummy")
    QuotationDTO getDummy();

    @RequestMapping(method = RequestMethod.GET,value = "/quotations/{ticketNo}")
    QuotationDTO getByTicket(@PathVariable("ticketNo") String ticketNo);

    @RequestMapping(method = RequestMethod.POST,value = "/quotations")
    QuotationDTO save(@RequestBody QuotationDTO quotation);

    @RequestMapping(method = RequestMethod.PUT,value = "/quotations")
    QuotationDTO update(@RequestBody QuotationDTO quotation);
}

 

The instructions for running each individual service, and code is available at Github

There’s still a lot to improve on this sample project (e.g security, and oauth2, and etc but hopefully this article provided you a ground up on migrating/building your applications using the Microservice design with spring boot.

Side Note: The code was taken from one of my old project that’s been built as monolithic. Some coding conventions/approach might be outdated, and had incurred technical debt. and I will try to update and clean up the code as soon as I can.

Improvements and suggestions are welcome 🙂

references and further readings:

http://microservices.io/
https://player.oreilly.com/videos/9781491944615
http://www.oreilly.com/programming/free/microservices-vs-service-oriented-architecture.csp http://shop.oreilly.com/product/0636920033158.do
https://herbertograca.com/2017/01/26/microservices-architecture/

Alternatives for Hibernate buildSessionFactory()

With the Hibernate 4 the

buildSessionFactory()

method is already deprecated. The

buildSessionFactory()

still works but if you are one of those people who tries to avoid using deprecated or old libraries I found an alternative for you to create your Session Factory.

In Hibernate 4 the

buildSessionFactory(ServiceRegistry serviceRegistry)

is the replacement for the deprecated method

buildSessionFactory()

. I tried googling, searching the documentation of Hibernate 4 for the implementation of

buildSessionFactory(ServiceRegistry serviceRegistry)

but sadly I cannot find any, The getting started guide for it still uses the old buildSessionFactory() method.

Here is an alternative for deprecated buildSessionFactory()

public static SessionFactory configureSessionFactory() {

    try {
        Configuration configuration = new Configuration();

        configuration.configure();

        serviceRegistry = new ServiceRegistryBuilder().applySettings(

        configuration.getProperties()).buildServiceRegistry();

        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    } catch (HibernateException hbe) {

        hbe.printStackTrace();

    }

    return sessionFactory;
}

This code will work providing the your hibernate.cfg.xml is in the same directory of this code. However if you placed your hibernate.cfg.xml in another directory all you have to do is replace the

configuration.configure();

with

configuration.configure(configFilePath);

Four Pillars of Object Oriented Programming

We have to admit, we know and use the “4 Pillars” Of Object Oriented Programming but let’s be honest here there are some of us who tends to forget what are the “4 pillars” of OOP or what is their somehow technical explanation.

if you are like me, who tends to use them a lot but always can’t find the words to explain it to friend or a colleague then this is something worth your time recalling.

So What are the 4 pillars of OOP ? Let’s start!

1.Abstraction
Abstraction is a process of exposing essential feature of an entity while hiding other irrelevant detail. Why would you want to use abstraction?

abstraction reduces code complexity and at the same time it makes your aesthetically pleasant.

2.Encapsulation
We have to take in consideration that Encapsulation is somehow related to Data Hiding.
Encapsulation is when you hide your modules internal data and all other implementation details/mechanism from other modules. it is also a way of restricting access to certain properties or component.

Remember, Encapsulation is not data hiding, but Encapsulation leads to data hiding

3.Inheritance
Like the word Inheritance literally means it is a practice of passing on property, titles, debts, rights and obligations upon the death of an individual. in OOP this is somehow true(Except the death of an individual) , where The base class(the existing class sometimes called as the Parent class) has properties and methods that will be inherited by the sub class(sometimes called a subtype or child class) and it can have additional properties or methods.

The ability of creating a new class from an existing class. 

4. Polymorphism
Just like in biology, Polymorphism refers to the ability to take into different forms or stages. A subclass can define its own unique behavior and still share the same functionalities or behavior of its parent/base class.Yes, you got it right, subclass can have their own behavior and share some of its behavior from its parent class not the other way around. A parent class cannot have the behavior of its subclass.

Polymorphism is the ability of an object to change behavior on runtime

There are more in-depth details about the 4 pillars of OOP in the web. I am just here to remind you what are they. Hopefully this is enough for you to recall everything you have forgotten about the pillars of OOP.