Applies to
- Liquibase Pro
- Spring Boot
Summary
Users of Java Spring Boot framework are able to implement database changes by embedding Liquibase into the framework. This allows developers to add database scripts to their source code repository. As such, they are able to update database automatically as part of application start up process.
But how do they implement Liquibase Pro features such as Policy Checks, Flow Files, Operations Reports, or use Liquibase Pro extensions for MongoDB, DynamoDB, CosmosDB, Hashicorp Vault, etc.
In this document, we will discuss how to run Policy Checks, apply Liquibase Pro license key and run Pro features.
New Spring Boot Project with Liquibase Dependencies
To create a new Spring Boot project with Liquibase as part of the Spring Boot workflow, start with Spring Initializr. Ensure that "Liquibase Migration", "Spring Data JPA" and "H2 Database" are added as dependencies.
This is also documented here. Your initializer screen should look like this:
Click the Generate button at the bottom. A demo.zip file will be downloaded containing Java source for DemoApplication, tests, and a Liquibase changelog. Maven build files, including the pom.xml are included in demo.zip as well.
Unzip demo.zip to look inside your pom.xml file and ensure that you have the following dependencies included:
<dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency>
Using Liquibase Pro features in Spring Boot requires implementing a Spring Boot Customizer. Create a new class and give it a name. For the purpose of this tutorial we will call this class LiquibaseFlowCustomizer.java. This will need to extend Liquibase and require additional imports as shown below.
package com.example.demo; import liquibase.Liquibase; import liquibase.integration.spring.Customizer; import org.springframework.context.annotation.Configuration; @Configuration public class LiquibaseFlowCustomizer<T extends Liquibase> implements Customizer<T> { @Override public void customize(T liquibase) { } }
Apply Liquibase Pro License in Spring Boot
Start by adding a property in your application.properties file such as this:
liquibase.license_key=ABwwGgQUWlM...
Then add the following code to your Spring Boot Customizer. Note the use of @Value("${liquibase.license_key}")
which reads the property liquibase.license_key from the application.properties file. The value of this property is stored in a string variable licenseKey
, which is then used in the customize
method to set system property using: System.setProperty("liquibase.licenseKey",
licenseKey);
package com.example.demo; import liquibase.Liquibase; import liquibase.command.CommandScope; import liquibase.integration.spring.Customizer; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Configuration public class LiquibaseFlowCustomizer<T extends Liquibase> implements Customizer<T> { @Value("${liquibase.license_key}") private String licenseKey; @Override public void customize(T liquibase) { System.setProperty("liquibase.licenseKey", licenseKey); } }
Create a changelog
To run liquibase, a changelog is required. Create a barebones changelog containing a single change to tag the database with version_1.0. In the src/main/resources/db/changelog/db.changelog-master.yaml
databaseChangeLog:
- changeSet:
id: test-spring-tag-version
author: liquibase-user
changes:
- tagDatabase:
tag: version_1.0
When you start your application with mvn spring-boot:run
or gradle bootRun
, Liquibase will apply the Liquibase Pro license key and it will be mentioned in the log output:
Flow Files in Spring Boot
Flow files is a Liquibase Pro feature. Running them in Spring Boot first requires applying the Liquibase Pro license key.
In your application.properties file, in addition to supplying the Pro license key, you will also want to specify the location of the flow file
liquibase.flowfile=db/changelog/flowfile.yaml liquibase.license_key=ABwwGgQUWlM...
Your flow file (located in db/changelog/flowfile.yaml) could look like this:
stages: Update: actions: - type: liquibase command: status - type: liquibase command: update endStage: actions: - type: liquibase command: history
Your Spring Boot customizer, in addition to setting Liquibase Pro license key, would need to make Java API call to execute the flow file. Note the additional import:
import com.datical.liquibase.ext.command.FlowCommandStep;
package com.example.demo;
import com.datical.liquibase.ext.command.FlowCommandStep;
import liquibase.Liquibase;
import liquibase.command.CommandScope;
import liquibase.integration.spring.Customizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LiquibaseFlowCustomizer<T extends Liquibase> implements Customizer<T> {
@Value("${liquibase.flowfile}")
private String flowFile;
@Value("${liquibase.license_key}")
private String licenseKey;
@Value("${liquibase.changelogFile}")
private String changelogFile;
@Value("${liquibase.command.url}")
private String url;
@Value("${liquibase.command.username}")
private String username;
@Value("${liquibase.command.password}")
private String password;
private static final Logger LOG = LoggerFactory.getLogger(LiquibaseFlowCustomizer.class);
@Override
public void customize(T liquibase) {
System.setProperty("liquibase.licenseKey", licenseKey);
System.setProperty("liquibase.command.flowFile", flowFile);
System.setProperty("liquibase.command.changelogFile", changelogFile);
System.setProperty("liquibase.command.url", url);
System.setProperty("liquibase.command.username", username);
System.setProperty("liquibase.command.password", password);
try {
new CommandScope(FlowCommandStep.COMMAND_NAME)
.addArgumentValue(FlowCommandStep.FLOW_FILE, flowFile)
.execute();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
When you start your application with mvn spring-boot:run
, Liquibase will apply the Liquibase Pro license key, and run the flow file. The flow file stages will appear in the log:
Other Liquibase Pro features can also be enabled by first setting their values in the application.properties file and then reading them from your customizer code and setting them as system properties.
Here is a complete list of Liquibase system properties that can be configured.
For example, to disable operations reports, the property to set is: liquibase.reports.enabled. Here is how you would code it in your Spring Boot customizer.
- First, add a property to your application.properties file:
liquibase.reportsEnabled=false
- Second, add @Value code to customizer:
@Value("${liquibase.reportsEnabled}")
private String reportsEnabled;
- Third, set Liquibase system properties in the
customize
method:
@Override
public void customize(T liquibase) {
...
System.setProperty("liquibase.licenseKey", licenseKey);
...
}
Structured Logging
Structured Logging makes Liquibase operation data easily available and machine-readable. You can use monitoring and analysis tools to read, query, and act upon this data in automated workflows. Tools you can use with Liquibase Structured Logging include AWS CloudWatch, Grafana, Opensearch, Sematext, Splunk, ElasticSearch and other analysis instruments. Liquibase uses a Mapped Diagnostic Context (MDC) to generate structured logs in a JSON format.
The prerequisite for enabling structured logging is the presence of a valid Liquibase Pro license which can be supplied using steps provided above.
In order to configure structured logging on any Liquibase operation, you would need to provide three arguments: log-format
, log-level
and log-file
. Here is an example of how you could provide these arguments in the "update" operation inside the flow file:
stages: Update: actions: - type: liquibase command: status - type: liquibase command: update globalArgs: { log-file: "liquibaseLog.json", log-format: "JSON_PRETTY", log-level: "INFO" } endStage: actions: - type: liquibase command: history
Policy Checks
For Spring Boot applications, Policy Checks are NOT run as part of spring commands (or maven or gradle commands) since Policy Checks implementation requires running a continuous integration (CI) pipeline which receives a trigger from opening a pull request. Instead, running Policy Checks from pipeline code can be done by directly invoking Liquibase command line interface (CLI) or using a flow file.
For more information about Policy Checks, take a look at this article about Using Liquibase Policy Checks.
Related Article(s):
Comments
0 comments
Please sign in to leave a comment.