Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customization for db migration #1061

Merged
merged 4 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions MigrationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@

## 2.14.0

### Frontend

The AntD component library has been upgraded from version 4 to 5. You might need to update application specific components. See details in: https://ant.design/docs/react/migration-v5

Frontend package.json scripts need to be updated due to webpack-cli upgrade. The scripts like start, build previously passed variables to build process like this `--env.appdef=applications`. These need to be modified by changing the dot to a space like this `--env appdef=applications`. Passing similar env-variables from command line also need to be passed without the dot.

### service-webapp / WebappHelper

Moved `fi.nls.oskari.servlet.WebappHelper` to new path `org.oskari.init.OskariInitializer`. This file is usually not customized so the change shouldn't have any effect on most instances. However if you have an override for the WebappHelper OR for example the `SpringInitializer` (that calls the WebappHelper) on your app you will need to update the references (it's a drop-in replacement). The new OskariInitializer allows overriding the database migration code with your own. See https://github.com/oskariorg/oskari-server/pull/1061 for details.

## 2.13.0

### GeoServer dependency removed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.oskari.init;

/**
* Interface to implement customization for overriding the built-in migration process
*/
public interface CustomMigration {
void migrateDB();
}
74 changes: 45 additions & 29 deletions ...a/fi/nls/oskari/servlet/WebappHelper.java → ...va/org/oskari/init/OskariInitializer.java
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package fi.nls.oskari.servlet;
package org.oskari.init;

import fi.nls.oskari.cache.JedisManager;
import fi.nls.oskari.db.DatasourceHelper;
import fi.nls.oskari.service.ServiceRuntimeException;
import org.oskari.helpers.FlywaydbMigrator;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
Expand All @@ -11,22 +12,18 @@

import javax.naming.Context;


/**
* Created by SMAKINEN on 8.7.2015.
*/
public class WebappHelper {
public class OskariInitializer {

private static final DatasourceHelper DS_HELPER = DatasourceHelper.getInstance();

private static final String STR_LOG_LINE = "#########################################################";


private static Logger log = LogFactory.getLogger(WebappHelper.class);
private static Logger LOG = LogFactory.getLogger(OskariInitializer.class);
private static SchedulerService schedulerService;
private static boolean propsLoaded = false;

private WebappHelper() {}
private OskariInitializer() {}

public static void loadProperties() {
// populate properties
Expand All @@ -35,7 +32,7 @@ public static void loadProperties() {
System.out.println("- loading /oskari-ext.properties");
PropertyUtil.loadProperties("/oskari-ext.properties");
// init logger after the properties so we get the correct logger impl
log = LogFactory.getLogger(WebappHelper.class);
LOG = LogFactory.getLogger(OskariInitializer.class);
propsLoaded = true;
}

Expand All @@ -45,17 +42,17 @@ public static void init() {
loadProperties();
}
// catch all so we don't get mysterious listener start errors
log.info(STR_LOG_LINE);
log.info("Oskari-map context is being initialized");
LOG.info(STR_LOG_LINE);
LOG.info("Oskari-map context is being initialized");
initializeOskariContext();

// init jedis
log.info("Initializing Redis connections");
LOG.info("Initializing Redis connections");
JedisManager.connect();
log.info("Oskari-map context initialization done");
log.info(STR_LOG_LINE);
LOG.info("Oskari-map context initialization done");
LOG.info(STR_LOG_LINE);
} catch (Exception ex) {
log.error(ex, "!!! Error initializing context for Oskari !!!");
LOG.error(ex, "!!! Error initializing context for Oskari !!!");
}

migrateDB();
Expand All @@ -64,7 +61,7 @@ public static void init() {
try {
schedulerService.initializeScheduler();
} catch (final SchedulerException e) {
log.error(e, "Failed to start up the Oskari scheduler");
LOG.error(e, "Failed to start up the Oskari scheduler");
}
}

Expand All @@ -73,36 +70,42 @@ public static void init() {
*/
public static void initializeOskariContext() {

log.info("- checking default DataSource");
LOG.info("- checking default DataSource");
final Context ctx = DS_HELPER.getContext();
if(!DS_HELPER.checkDataSource(ctx)) {
log.error("Couldn't initialize default DataSource");
LOG.error("Couldn't initialize default DataSource");
}

// loop "db.additional.pools" to see if we need any more pools configured
log.info("- checking additional DataSources");
LOG.info("- checking additional DataSources");
final String[] additionalPools = DatasourceHelper.getAdditionalModules();
for(String pool : additionalPools) {
if(!DS_HELPER.checkDataSource(ctx, pool)) {
log.error("Couldn't initialize DataSource for module:", pool);
LOG.error("Couldn't initialize DataSource for module:", pool);
}
}
}

private static void migrateDB() {
if(PropertyUtil.getOptional("db.flyway", true) == false) {
log.warn("Skipping flyway migration! Remove 'db.flyway' property or set it to 'true' to enable migration");
if (PropertyUtil.getOptional("db.flyway", true) == false) {
LOG.warn("Skipping flyway migration! Remove 'db.flyway' property or set it to 'true' to enable migration");
return;
}
boolean ignoreMigrationFailures = PropertyUtil.getOptional("db.ignoreMigrationFailures", false);
CustomMigration customMigration = getCustomMigration();
if (customMigration != null) {
LOG.warn("Running custom migration instead of built-in");
customMigration.migrateDB();
return;
}

// upgrade database structure with http://flywaydb.org/
log.info("Oskari-map checking DB status");
LOG.info("Oskari-map checking DB status");
try {
FlywaydbMigrator.migrate(DS_HELPER.getDataSource());
log.info("Oskari core DB migrated successfully");
LOG.info("Oskari core DB migrated successfully");
} catch (Exception e) {
log.error(e, "DB migration for Oskari core failed!");
LOG.error(e, "DB migration for Oskari core failed!");
if(!ignoreMigrationFailures) {
throw e;
}
Expand All @@ -112,26 +115,39 @@ private static void migrateDB() {
final String poolName = DS_HELPER.getOskariDataSourceName(module);
try {
FlywaydbMigrator.migrate(DS_HELPER.getDataSource(poolName), module);
log.info(module + " DB migrated successfully");
LOG.info(module + " DB migrated successfully");
} catch (Exception e) {
log.error(e, "DB migration for module", module, "failed!");
LOG.error(e, "DB migration for module", module, "failed!");
if(!ignoreMigrationFailures) {
throw e;
}
}
}
}

public static CustomMigration getCustomMigration() {
String className = PropertyUtil.getOptional("db.flyway.migrationCls");
if (className == null) {
return null;
}
try {
final Class clazz = Class.forName(className);
return (CustomMigration) clazz.newInstance();
} catch (Exception e) {
throw new ServiceRuntimeException("Error initializing migration class from 'db.flyway.migrateCls='" + className, e);
}
}

public static void teardown() {
if (schedulerService != null) {
try {
schedulerService.shutdownScheduler();
} catch (final SchedulerException e) {
log.error(e, "Failed to shut down the Oskari scheduler");
LOG.error(e, "Failed to shut down the Oskari scheduler");
}
}
DS_HELPER.teardown();
JedisManager.shutdown();
log.info("Context destroy");
LOG.info("Context destroy");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import fi.nls.oskari.control.ActionControl;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.servlet.WebappHelper;
import fi.nls.oskari.spring.extension.OskariParamMethodArgumentResolver;
import fi.nls.oskari.spring.extension.OskariViewResolver;
import fi.nls.oskari.util.PropertyUtil;
import org.oskari.init.OskariInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -55,7 +55,7 @@ public void setServletContext(ServletContext context) {
@PostConstruct
public void oskariInit() {
// check DB connections/content
WebappHelper.init();
OskariInitializer.init();
}

// --------- locale handling -------------
Expand Down Expand Up @@ -135,7 +135,7 @@ public ViewResolver getDefaultsViewResolver() {
public void tearDown() {
LOG.info("Teardown");
ActionControl.teardown();
WebappHelper.teardown();
OskariInitializer.teardown();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@

import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.servlet.WebappHelper;
import fi.nls.oskari.spring.session.RedisSessionConfig;
import fi.nls.oskari.util.PropertyUtil;
import org.oskari.init.OskariInitializer;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

/**
Expand All @@ -26,7 +24,7 @@ public class SpringInitializer extends AbstractHttpSessionApplicationInitializer
@Override
public void onStartup(ServletContext servletContext) {
// IMPORTANT! read properties at startup - needed for profile selection
WebappHelper.loadProperties();
OskariInitializer.loadProperties();
// re-init logger so we get the one configured in properties
log = LogFactory.getLogger(SpringInitializer.class);
final WebApplicationContext context = getContext();
Expand Down
Loading