RED-8702: Explore document databases to store entityLog
- updated connection logic for clustered deployment - updated dependencies
This commit is contained in:
parent
e30ea19f15
commit
fc9a014395
@ -25,7 +25,7 @@ repositories {
|
||||
val springBootVersion = "3.1.5"
|
||||
|
||||
dependencies {
|
||||
api("com.knecon.fforesight:tenant-commons:0.23.0")
|
||||
api("com.knecon.fforesight:tenant-commons:0.24.0")
|
||||
api("org.liquibase:liquibase-core:4.20.0")
|
||||
api("org.liquibase.ext:liquibase-mongodb:4.20.0")
|
||||
api("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootVersion}")
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
package com.knecon.fforesight.mongo.database.commons.liquibase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
|
||||
import liquibase.Contexts;
|
||||
import liquibase.GlobalConfiguration;
|
||||
import liquibase.LabelExpression;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.Scope;
|
||||
import liquibase.configuration.ConfiguredValue;
|
||||
import liquibase.database.Database;
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.integration.commandline.LiquibaseCommandLineConfiguration;
|
||||
import liquibase.integration.spring.SpringLiquibase;
|
||||
import liquibase.integration.spring.SpringResourceAccessor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MongoSpringLiquibase extends SpringLiquibase {
|
||||
|
||||
protected Database database;
|
||||
|
||||
public MongoSpringLiquibase() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executed automatically when the bean is initialized.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws LiquibaseException {
|
||||
|
||||
final ConfiguredValue<Boolean> shouldRunProperty = LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentConfiguredValue();
|
||||
|
||||
if (!(Boolean) shouldRunProperty.getValue()) {
|
||||
Scope.getCurrentScope().getLog(getClass()).info("Liquibase did not run because " + shouldRunProperty.getProvidedValue().describe() + " was set to false");
|
||||
return;
|
||||
}
|
||||
if (!shouldRun) {
|
||||
Scope.getCurrentScope()
|
||||
.getLog(getClass())
|
||||
.info("Liquibase did not run because 'shouldRun' " + "property was set " + "to false on " + getBeanName() + " Liquibase Spring bean.");
|
||||
return;
|
||||
}
|
||||
|
||||
try (Liquibase liquibase = createLiquibase(getDatabase())) {
|
||||
generateRollbackFile(liquibase);
|
||||
performUpdate(liquibase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void generateRollbackFile(Liquibase liquibase) throws LiquibaseException {
|
||||
|
||||
if (rollbackFile != null) {
|
||||
|
||||
try (final OutputStream outputStream = Files.newOutputStream(rollbackFile.toPath()); Writer output = new OutputStreamWriter(outputStream,
|
||||
GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue())) {
|
||||
|
||||
if (tag != null) {
|
||||
liquibase.futureRollbackSQL(tag, new Contexts(getContexts()), new LabelExpression(getLabelFilter()), output);
|
||||
} else {
|
||||
liquibase.futureRollbackSQL(new Contexts(getContexts()), new LabelExpression(getLabelFilter()), output);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new LiquibaseException("Unable to generate rollback file.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("squid:S2095")
|
||||
protected Liquibase createLiquibase(Database db) throws LiquibaseException {
|
||||
|
||||
SpringResourceAccessor resourceAccessor = createResourceOpener();
|
||||
Liquibase liquibase = new Liquibase(getChangeLog(), resourceAccessor, db);
|
||||
if (parameters != null) {
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
liquibase.setChangeLogParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (isDropFirst()) {
|
||||
liquibase.dropAll();
|
||||
}
|
||||
|
||||
return liquibase;
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,17 +7,16 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
import com.knecon.fforesight.mongo.database.commons.utils.MongoUtils;
|
||||
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
|
||||
import com.knecon.fforesight.tenantcommons.TenantProvider;
|
||||
import com.knecon.fforesight.tenantcommons.model.MongoDBConnection;
|
||||
import com.knecon.fforesight.tenantcommons.model.TenantResponse;
|
||||
import com.knecon.fforesight.tenantcommons.utils.MongoConnectionStringHelper;
|
||||
|
||||
import feign.RetryableException;
|
||||
import liquibase.Contexts;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.changelog.ChangeSet;
|
||||
import liquibase.database.Database;
|
||||
import liquibase.database.DatabaseFactory;
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
|
||||
import liquibase.integration.spring.SpringResourceAccessor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -54,41 +53,50 @@ public class TenantMongoLiquibaseExecutor implements InitializingBean, ResourceL
|
||||
@SneakyThrows
|
||||
protected void runOnAllTenants(List<TenantResponse> tenants) {
|
||||
|
||||
tenants.forEach(this::runLiquibase);
|
||||
}
|
||||
|
||||
|
||||
private void runLiquibase(TenantResponse tenant) {
|
||||
|
||||
MongoDBConnection mongoDBConnection = tenant.getMongoDBConnection();
|
||||
var mongoUrl = MongoUtils.buildMongoUrl(mongoDBConnection);
|
||||
log.info("Initializing MongoDB liquibase for tenant {} / {}", tenant.getTenantId(), mongoUrl);
|
||||
|
||||
try (SpringResourceAccessor resourceAccessor = new SpringResourceAccessor(resourceLoader)) {
|
||||
|
||||
try (MongoLiquibaseDatabase database = (MongoLiquibaseDatabase) DatabaseFactory.getInstance()
|
||||
.openDatabase(mongoUrl, mongoDBConnection.getUsername(), encryptionService.decrypt(mongoDBConnection.getPassword()), null, resourceAccessor)) {
|
||||
database.setSupportsValidator(false);
|
||||
try (Liquibase liquibase = new Liquibase(tenantMongoLiquibaseProperties.getChangeLog(), resourceAccessor, database)) {
|
||||
Contexts contexts = new Contexts(tenantMongoLiquibaseProperties.getContexts());
|
||||
List<ChangeSet> changeSetsList = liquibase.listUnrunChangeSets(contexts, null);
|
||||
if (!changeSetsList.isEmpty()) {
|
||||
liquibase.update(contexts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to run liquibase migration on MongoDB for tenant: {}", tenant.getTenantId(), e);
|
||||
}
|
||||
log.info("Liquibase ran on MongoDB for tenant " + tenant.getTenantId());
|
||||
tenants.forEach(this::runMongoLiquibase);
|
||||
}
|
||||
|
||||
|
||||
public void initializeTenant(String tenantId) {
|
||||
|
||||
runLiquibase(tenantProvider.getTenant(tenantId));
|
||||
runMongoLiquibase(tenantProvider.getTenant(tenantId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void runMongoLiquibase(TenantResponse tenant) {
|
||||
|
||||
log.info("Initializing MongoDB liquibase for tenant {}", tenant.getTenantId());
|
||||
|
||||
try (SpringResourceAccessor resourceAccessor = new SpringResourceAccessor(resourceLoader)) {
|
||||
|
||||
MongoDBConnection mongoDBConnection = tenant.getMongoDBConnection();
|
||||
try (MongoLiquibaseDatabase database = (MongoLiquibaseDatabase) DatabaseFactory.getInstance()
|
||||
.openDatabase(MongoConnectionStringHelper.buildGenericMongoUrl(mongoDBConnection),
|
||||
mongoDBConnection.getUsername(),
|
||||
encryptionService.decrypt( mongoDBConnection.getPassword()),
|
||||
null,
|
||||
resourceAccessor)) {
|
||||
database.setSupportsValidator(false);
|
||||
|
||||
executeMongoSpringLiquibase(database);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to run liquibase migration on MongoDB for tenant: {}", tenant.getTenantId(), e);
|
||||
} log.info("Liquibase ran on MongoDB for tenant " + tenant.getTenantId());
|
||||
}
|
||||
|
||||
|
||||
protected void executeMongoSpringLiquibase(Database database) throws LiquibaseException {
|
||||
|
||||
MongoSpringLiquibase liquibase = new MongoSpringLiquibase();
|
||||
liquibase.setResourceLoader(resourceLoader);
|
||||
liquibase.setDatabase(database);
|
||||
liquibase.setChangeLog(tenantMongoLiquibaseProperties.getChangeLog());
|
||||
liquibase.setContexts(tenantMongoLiquibaseProperties.getContexts());
|
||||
liquibase.setClearCheckSums(tenantMongoLiquibaseProperties.isClearChecksums());
|
||||
liquibase.afterPropertiesSet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.knecon.fforesight.mongo.database.commons.service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -12,9 +11,7 @@ import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.knecon.fforesight.mongo.database.commons.model.MongoClientConnection;
|
||||
import com.knecon.fforesight.tenantcommons.model.MongoDBConnection;
|
||||
import com.mongodb.MongoClientSettings;
|
||||
import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.knecon.fforesight.tenantcommons.utils.MongoConnectionStringHelper;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
|
||||
@ -46,7 +43,7 @@ public class MongoClientCache {
|
||||
var mongoDBConnection = mongoConnectionProvider.getMongoDBConnection(key);
|
||||
|
||||
if (mongoDBConnection != null) {
|
||||
return new MongoClientConnection(mongoDBConnection.getDatabase(), buildMongoClient(mongoDBConnection));
|
||||
return new MongoClientConnection(key, buildMongoClient(mongoDBConnection));
|
||||
}
|
||||
throw new RuntimeException("No Connection provided");
|
||||
}
|
||||
@ -56,14 +53,7 @@ public class MongoClientCache {
|
||||
|
||||
private MongoClient buildMongoClient(MongoDBConnection mongoDBConnection) {
|
||||
|
||||
MongoCredential credential = MongoCredential.createCredential(mongoDBConnection.getUsername(),
|
||||
mongoDBConnection.getDatabase(),
|
||||
mongoDBConnection.getPassword().toCharArray());
|
||||
return MongoClients.create(MongoClientSettings.builder()
|
||||
.applyToClusterSettings(builder -> builder.hosts(Collections.singletonList(new ServerAddress(mongoDBConnection.getHost(),
|
||||
Integer.parseInt(mongoDBConnection.getPort())))))
|
||||
.credential(credential)
|
||||
.build());
|
||||
return MongoClients.create(MongoConnectionStringHelper.buildGenericMongoConnectionString(mongoDBConnection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
package com.knecon.fforesight.mongo.database.commons.utils;
|
||||
|
||||
import com.knecon.fforesight.tenantcommons.model.MongoDBConnection;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class MongoUtils {
|
||||
|
||||
|
||||
private StringBuilder createMongoConnectionStringBuilder(String host, String port, String database) {
|
||||
|
||||
return new StringBuilder("mongodb://").append(host).append(':').append(port).append('/').append(database);
|
||||
}
|
||||
|
||||
private StringBuilder createMongoConnectionStringBuilder(String host, String port, String username, String password, String database) {
|
||||
|
||||
return createMongoConnectionStringBuilder(host, port, username, password).append('/').append(database);
|
||||
}
|
||||
|
||||
|
||||
private StringBuilder createMongoConnectionStringBuilder(String host, String port, String username, String password) {
|
||||
|
||||
return new StringBuilder("mongodb://").append(username).append(':').append(password).append("@").append(host).append(':').append(port);
|
||||
}
|
||||
|
||||
|
||||
public String buildMongoUrl(MongoDBConnection mongoDBConnection) {
|
||||
|
||||
return createMongoConnectionStringBuilder(mongoDBConnection.getHost(),
|
||||
mongoDBConnection.getPort(),
|
||||
mongoDBConnection.getDatabase()).toString();
|
||||
}
|
||||
|
||||
|
||||
public String buildMongoUrlWithAuth(MongoDBConnection mongoDBConnection) {
|
||||
|
||||
return createMongoConnectionStringBuilder(mongoDBConnection.getHost(),
|
||||
mongoDBConnection.getPort(),
|
||||
mongoDBConnection.getUsername(),
|
||||
mongoDBConnection.getPassword()).toString();
|
||||
}
|
||||
|
||||
|
||||
public String buildMongoUrlWithAuthForDatabase(MongoDBConnection mongoDBConnection) {
|
||||
|
||||
return createMongoConnectionStringBuilder(mongoDBConnection.getHost(),
|
||||
mongoDBConnection.getPort(),
|
||||
mongoDBConnection.getUsername(),
|
||||
mongoDBConnection.getPassword(),
|
||||
mongoDBConnection.getDatabase()).toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user