DevOps in Java

Spring Profiles

Spring Profiles provide a way to segregate parts of your application configuration (e.g., with application.yml) to specify your deployment environments.

 1spring.profiles.active: dev
 2
 3---
 4
 5spring:
 6  profiles: dev
 7  datasource:
 8  url: jdbc:mysql://localhost:3306/notepad
 9  username: root
10  password: root
11
12---
13
14test_mysql_host: ${ENV_TEST_MYSQL_HOST:localhost}
15
16spring:
17  profiles: staging
18  datasource:
19  url: jdbc:mysql://${test_mysql_host}:3306/notepad
20  username: root
21  password: root
  • An example of a application.yml file in a Spring Boot application is provided above, showing two different profiles dev and staging.

  • The default profile is set in line 1 as dev.

  • This allows us to start the application from the command line, specifying a profile with $ java -jar -Dspring.profiles.active=staging my_app.jar.

Apache Maven

Apache Maven is a build automation tool to easily run automation tests, package the application, deploy a snapshot version to a repository manager such as Nexus and Artifactory.

Snapshot vs Release

  • A snapshot version in Maven is version that is still under development and has not been released yet.

  • It is still under development and is expected to change a lot.

1<groupId>bigtom.com</groupId>
2<artifactId>kerberos-poc01</artifactId>
3<version>0.0.1-SNAPSHOT</version>
4<name>kerberos-poc01</name>
5<description>Spring Boot Kerberos POC 01</description>

Lifecycle and their Phases

  • Maven has 3 built-in life-cycles:

    • build (default)

    • clean

    • site

build lifecycle

The default build lifecycle consists of the following phases executed in the order below:

  • validate: validate the project is correct and all needed information is available.

  • compile: compile the source code.

  • test: test the compiled source code with a suitable unit test framework. These tests do not require the code be packaged or deployed.

  • package: package the compiled code into a distribution format such as a JAR.

  • verify: run any checks on integration tests (if specified) to ensure the code meets the required quality.

  • install: install the package into the local repository or local environment.

  • deploy: copies the final package to the configured remote repository or remote environment.

Maven Caching

Artifacts produced by Maven are stored in two types of repositories:

  • Local: The local repository is located on your local system at $HOME/.m2/repository.

  • Remote: If a requested artifact is not found in the local repository, it is downloaded from the remote repository into the local cache. By default, this is the Maven Central Repository.

Repository Manager

  • A repository manager acts as a dedicated proxy server for public Maven repositories.

  • For a development team working of a shared internal network, this provides more reliability and faster downloads.

  • In some situations, it also ensures that only white listed libraries enabled on the Repository Manager are used by the development team. This ensures that the development team does not use third party libraries that are not sanctioned are not used, increasing security for the product code.

  • A central company repository manager may also provide a deployment destination for the team, which can in turn be used by other teams in the company.

Feature Flags

Reference URL: https://onix-systems.com/blog/introduction-to-feature-flags-in-java-using-the-spring-boot-framework

  • In Java, Feature Flags help when it’s too early to introduce a feature in an application, or if they should only be available for certain groups of users.

  • In a Spring Boot application, this can be done by inserting Spring flags from the application.properties file using the @ConfigurationProperties annotation.

  • Ideally, the application should handle changes to these globaly configuration changes dynamically, so that the feature starts or stops working almost immediately.

application.yml and @ConditionalOnProperty

  • The most common way to activate the Feature Flag is to use a define the flag in the application.yml and use it with the @ConditionalOnProperty directive.

  • With @ConditionalOnProperty followed by a bean declaration the bean would only be created based on the configured property value.

application.yml

feature-flags:
  is-new-books-service-enabled: true
  is-new-papers-service-enabled: false

We then turn on the implementation option based on the feature’s flag value using @ConditionalOnProperty.

BooksServiceConfig.java

@Confugration
public class BooksServiceConfig {

  @Bean
  @ConditionalOnProperty (
    name = "feature-flags.is-new-books-service-enabled",
    havingValue = "false",
    // The value to assume if this property setting is missing
    matchIfMissing = true
  )
  public BookService booksDefaultService() {
    return new BooksDefaultService();
  }

  @Bean
  @ConditionalOnProperty (
    name = "feature-flags.is-new-papers-service-enabled",
    havingValue = "true"
  )
  public BooksService booksNewService() {
    return new BooksNewService();
  }
}