Standalone tool for initializing of hawkBit Database (#2369)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
# hawkBit JPA Flyway migration
|
||||
|
||||
JPA Flyway migrations scrypts
|
||||
JPA Flyway migrations scripts
|
||||
52
hawkbit-repository/hawkbit-repository-jpa-init/README.md
Normal file
52
hawkbit-repository/hawkbit-repository-jpa-init/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# hawkBit JPA Initializer & Migrator
|
||||
|
||||
A standalone tool for validating and migrating the database to the current hawkBit schema. It is used to validate, initialize or migrate the database to the current hawkBit schema.
|
||||
|
||||
## Configuration
|
||||
Could be configured with _hawkbit.db.\<key\>_ or <spring.database.\<key\>_ environment or system properties, with keys:
|
||||
* **mode** - migrate or validate (default)
|
||||
* **url** - database url
|
||||
* **username** - database user - shall have the necessary permissions
|
||||
* **password** - database user's password
|
||||
* **sql-migration-suffixes** - flyway 'sqlMigrationSuffixes' if not the default ones (<upper case database (mariadb -> mysql)>.sql)
|
||||
|
||||
Where:
|
||||
1. Environment properties takes precedence over the system properties
|
||||
2. The _hawkbit.db.\<key\>_ properties take precedence over the _spring.database.\<key\>_ properties
|
||||
|
||||
There are two modes:
|
||||
* **migrate** - migrate the database, only when started with parameter with key mode (environment or system property)
|
||||
* **validate** - validate the database, default, only validates db and throws org.flywaydb.core.api.exception.FlywayValidateException if not in sync
|
||||
|
||||
**Note**: could also be configured using default flyway env properties
|
||||
|
||||
## Usage
|
||||
The module builds executable jar with all dependencies - _hawkbit-repository-jpa-init-\<revision\>-exec.jar_. It could be configured with environment properties and run as an executable jar:
|
||||
```shell
|
||||
# sets the mode - default if validate
|
||||
export hawkbit_db_mode=migrate
|
||||
# sets the database url - default is local h2
|
||||
export hawkbit_db_url=jdbc:mariadb://localhost:3306/hawkbit
|
||||
# sets the database user - default is h2 default root - sa
|
||||
export hawkbit_db_username=root
|
||||
# sets the database user's password - default is empty
|
||||
#export hawkbit_db_password=
|
||||
|
||||
# run executable jar
|
||||
java -jar target/hawkbit-repository-jpa-init-0-SNAPSHOT-exec.jar
|
||||
```
|
||||
|
||||
It could also be configured using system properties and run as a java main class:
|
||||
```shell
|
||||
java -classpath target/hawkbit-repository-jpa-init-0-SNAPSHOT-exec.jar \
|
||||
-Dhawkbit.db.mode=migrate \
|
||||
-Dhawkbit.db.url=jdbc:mariadb://localhost:3306/hawkbit \
|
||||
-Dhawkbit.db.username=root \
|
||||
-Dhawkbit.db.password= \
|
||||
org.eclipse.hawkbit.repository.jpa.init.HawkbitFlywayDbInit
|
||||
```
|
||||
|
||||
## Purpose and usecases
|
||||
If you want to do db management separately from the running services - i.e. not in mgmt-server or monolith (for instance) servers but only occasionally and on real updates, or you like to validate a database according to a hawkbit db schema version you could:
|
||||
1. set spring.flyway.enabled=false in the hawkbit services (or do not pack the hawkbit-repository-jpa-flyway module into the hawkbit services)
|
||||
2. use the tool to do the db management (e.g. in some pipelines)
|
||||
130
hawkbit-repository/hawkbit-repository-jpa-init/pom.xml
Normal file
130
hawkbit-repository/hawkbit-repository-jpa-init/pom.xml
Normal file
@@ -0,0 +1,130 @@
|
||||
<!--
|
||||
|
||||
Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
-->
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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>
|
||||
<parent>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<version>${revision}</version>
|
||||
<artifactId>hawkbit-repository</artifactId>
|
||||
</parent>
|
||||
|
||||
<artifactId>hawkbit-repository-jpa-init</artifactId>
|
||||
<name>hawkBit :: Repository :: JPA DB Init / Upgrade App</name>
|
||||
|
||||
<dependencies>
|
||||
<!-- Flyway to init and manage DB migrations -->
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Database -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- h2 flyway is supported by the flyway-core dependency -->
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-database-postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-mysql</artifactId>
|
||||
</dependency>
|
||||
<!-- Database END -->
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<artifactId>hawkbit-repository-jpa-flyway</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
<!-- not existing phase - don't build jar -->
|
||||
<phase>none</phase>
|
||||
<configuration>
|
||||
<finalName>_</finalName>
|
||||
<classifier>_</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>
|
||||
org.eclipse.hawkbit.repository.jpa.init.HawkbitFlywayDbInit
|
||||
</mainClass>
|
||||
<addClasspath>false</addClasspath>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptors>
|
||||
<descriptor>src/assembly/exec.xml</descriptor>
|
||||
</descriptors>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
<!--
|
||||
|
||||
Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
-->
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 https://maven.apache.org/xsd/assembly-2.2.0.xsd">
|
||||
<id>exec</id>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<containerDescriptorHandlers>
|
||||
<containerDescriptorHandler>
|
||||
<handlerName>metaInf-services</handlerName>
|
||||
</containerDescriptorHandler>
|
||||
</containerDescriptorHandlers>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<unpack>true</unpack>
|
||||
<scope>runtime</scope>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.init;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.flywaydb.core.Flyway;
|
||||
|
||||
/**
|
||||
* hawkBit Flyway db init configuration. Could be configured with "hawkbit.db.*" or "spring.database.*" environment or system properties,
|
||||
* with keys:
|
||||
* <ul>
|
||||
* <li>mode: <code>migrate</code> or <code>validate</code> (default)</li>
|
||||
* <li>url: database url</li>
|
||||
* <li>username: database user - shall have the necessary permissions</li>
|
||||
* <li>password: database user's password</li>
|
||||
* <li>sql-migration-suffixes: flyway 'sqlMigrationSuffixes' if not the default ones (<upper case database (mariadb -> mysql)>.sql) </li>
|
||||
* </ul>
|
||||
*
|
||||
* Where:
|
||||
* <ol>
|
||||
* <li>Environment properties takes precedence over the system properties</li>
|
||||
* <li>The "hawkbit.db.*" properties take precedence over the "spring.database.*" properties</li>
|
||||
* </ol>
|
||||
*
|
||||
* There are two modes:
|
||||
* <ul>
|
||||
* <li>migrate: migrate the database, only when started with parameter with key <code>mode</code> (environment or system property)</li>
|
||||
* <li>validate: validate the database, default, only validates db and throws {@link org.flywaydb.core.api.exception.FlywayValidateException} if not in sync</li>
|
||||
* </ul>
|
||||
* Note: could also be configured using default flyway env properties
|
||||
*/
|
||||
public class HawkbitFlywayDbInit {
|
||||
|
||||
public static final String MIGRATE = "migrate";
|
||||
|
||||
public static final String URL = prop("url", "jdbc:h2:mem:hawkbit;MODE=LEGACY;");
|
||||
public static final String USER = prop("username", "sa");
|
||||
public static final String PASSWORD = prop("password", "");
|
||||
public static final String MODE = prop("mode", "validate");
|
||||
|
||||
public static void main(final String[] args) {
|
||||
final Flyway flyway = Flyway.configure()
|
||||
.dataSource(URL, USER, PASSWORD)
|
||||
.cleanDisabled(true)
|
||||
.table("schema_version")
|
||||
.sqlMigrationSuffixes(prop("sql-migration-suffixes", suffix(URL)) + ".sql")
|
||||
.validateOnMigrate(true)
|
||||
.envVars()
|
||||
.load();
|
||||
|
||||
if (MODE.equals(MIGRATE)) {
|
||||
flyway.migrate();
|
||||
} else {
|
||||
flyway.validate();
|
||||
}
|
||||
}
|
||||
|
||||
private static String prop(final String key, final String defaultValue) {
|
||||
String value = env(key);
|
||||
if (value == null) {
|
||||
value = sys(key);
|
||||
}
|
||||
if (value == null) {
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static String env(final String key) {
|
||||
final String value = env0("hawkbit.db." + key);
|
||||
return value == null ? env0("spring.datasource." + key) : value;
|
||||
}
|
||||
|
||||
private static String env0(final String property) {
|
||||
String value = System.getenv(property);
|
||||
if (value == null) {
|
||||
value = System.getenv(property.toUpperCase());
|
||||
}
|
||||
if (value == null) {
|
||||
value = System.getenv(property.replace('.', '_'));
|
||||
}
|
||||
if (value == null) {
|
||||
value = System.getenv(property.replace('.', '_').toUpperCase());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static String sys(final String key) {
|
||||
return System.getProperty("hawkbit.db." + key, System.getProperty("spring.datasource." + key));
|
||||
}
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("jdbc:(?<database>\\w+):(\\\\)?.*", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private static String suffix(final String url) {
|
||||
final Matcher matcher = PATTERN.matcher(url);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalStateException("Invalid db url: " + url);
|
||||
}
|
||||
final String dbUpperCase = matcher.group("database").toUpperCase();
|
||||
return "MARIADB".equals(dbUpperCase) ? "MYSQL" : dbUpperCase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
-->
|
||||
<!DOCTYPE configuration>
|
||||
|
||||
<configuration>
|
||||
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
|
||||
<import class="ch.qos.logback.core.ConsoleAppender"/>
|
||||
|
||||
<appender name="STDOUT" class="ConsoleAppender">
|
||||
<encoder class="PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.flywaydb.core.internal.command.DbValidate" level="DEBUG"/>
|
||||
<logger name="org.flywaydb.core.internal.command.DbMigrate" level="DEBUG"/>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -15,7 +15,7 @@ spring.jpa.database=H2
|
||||
spring.jpa.show-sql=false
|
||||
# need to use legacy mode for now until we can upgrade EclipseLink
|
||||
# (see details: https://github.com/eclipse-ee4j/eclipselink/issues/1393)
|
||||
spring.datasource.url=jdbc:h2:mem:testdb;MODE=LEGACY;
|
||||
spring.datasource.url=jdbc:h2:mem:hawkbit;MODE=LEGACY;
|
||||
# Logging
|
||||
spring.jpa.properties.eclipselink.logging.level=off
|
||||
# Cluster aware
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
<module>hawkbit-repository-jpa</module>
|
||||
<module>hawkbit-repository-jpa-flyway</module>
|
||||
|
||||
<module>hawkbit-repository-jpa-init</module>
|
||||
|
||||
<module>hawkbit-repository-test</module>
|
||||
</modules>
|
||||
</project>
|
||||
Reference in New Issue
Block a user