mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 03:38:33 +08:00
PL-8744 Handling of database connection problems on middleware startup
This commit is contained in:
parent
d24fb2fdd5
commit
5b6bc43a15
@ -190,7 +190,7 @@ public class ServerInfo implements ServerInfoAPI, AppContext.Listener, Ordered {
|
||||
);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to update SYS_SERVER: {}", e);
|
||||
log.error("Unable to update SYS_SERVER: {}", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,12 @@ public class Scheduling implements SchedulingAPI {
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return configuration.getConfig(ServerConfig.class).getSchedulingActive();
|
||||
try {
|
||||
return configuration.getConfig(ServerConfig.class).getSchedulingActive();
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to find out if scheduling is active: {}", e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,7 +27,7 @@ import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.Metadata;
|
||||
import com.haulmont.cuba.core.global.QueryParser;
|
||||
import com.haulmont.cuba.core.global.QueryTransformerFactory;
|
||||
import com.haulmont.cuba.core.sys.DBNotInitializedException;
|
||||
import com.haulmont.cuba.core.sys.DbInitializationException;
|
||||
import com.haulmont.cuba.core.sys.DbUpdater;
|
||||
import com.haulmont.cuba.core.sys.persistence.DbmsType;
|
||||
import com.haulmont.cuba.security.app.Authenticated;
|
||||
@ -179,7 +179,7 @@ public class PersistenceManager implements PersistenceManagerMBean {
|
||||
return sb.toString();
|
||||
} else
|
||||
return "No updates available";
|
||||
} catch (DBNotInitializedException e) {
|
||||
} catch (DbInitializationException e) {
|
||||
return e.getMessage();
|
||||
} catch (Throwable e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
|
@ -101,9 +101,58 @@ public class AppContextLoader extends AbstractWebAppContextLoader {
|
||||
isMaster = clusterManager.isMaster();
|
||||
}
|
||||
// Init database
|
||||
DbUpdater updater = (DbUpdater) AppContext.getApplicationContext().getBean(DbUpdater.NAME);
|
||||
if (isMaster && Boolean.valueOf(AppContext.getProperty("cuba.automaticDatabaseUpdate"))) {
|
||||
DbUpdater updater = (DbUpdater) AppContext.getApplicationContext().getBean(DbUpdater.NAME);
|
||||
updater.updateDatabase();
|
||||
updateDatabase(updater);
|
||||
} else {
|
||||
checkDatabase(updater);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateDatabase(DbUpdater updater) {
|
||||
while (true) {
|
||||
try {
|
||||
updater.updateDatabase();
|
||||
return;
|
||||
} catch (DbInitializationException e) {
|
||||
if (e.isRetryPossible()) {
|
||||
log.error("Error updating database: {}\nWaiting 5 sec and retrying...", e.toString());
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e1) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Error updating database", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkDatabase(DbUpdater updater) {
|
||||
while (true) {
|
||||
try {
|
||||
boolean initialized = updater.dbInitialized();
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException("\n" +
|
||||
"============================================================================\n" +
|
||||
"ERROR: Database is not initialized. Set 'cuba.automaticDatabaseUpdate'\n" +
|
||||
"application property to 'true' to initialize and update database on startup.\n" +
|
||||
"============================================================================");
|
||||
}
|
||||
return;
|
||||
} catch (DbInitializationException e) {
|
||||
if (e.isRetryPossible()) {
|
||||
log.error("Error connecting to database: {}\nWaiting 5 sec and retrying...", e.toString());
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e1) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Error checking database", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ package com.haulmont.cuba.core.sys.dbupdate;
|
||||
|
||||
import com.haulmont.bali.db.DbUtils;
|
||||
import com.haulmont.bali.db.QueryRunner;
|
||||
import com.haulmont.cuba.core.sys.DBNotInitializedException;
|
||||
import com.haulmont.cuba.core.sys.DbInitializationException;
|
||||
import com.haulmont.cuba.core.sys.DbUpdater;
|
||||
import com.haulmont.cuba.core.sys.PostUpdateScripts;
|
||||
import com.haulmont.cuba.core.sys.persistence.DbmsSpecificFactory;
|
||||
@ -81,7 +81,7 @@ public class DbUpdaterEngine implements DbUpdater {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
public void updateDatabase() throws DbInitializationException {
|
||||
if (dbInitialized())
|
||||
doUpdate();
|
||||
else
|
||||
@ -89,11 +89,11 @@ public class DbUpdaterEngine implements DbUpdater {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> findUpdateDatabaseScripts() throws DBNotInitializedException {
|
||||
public List<String> findUpdateDatabaseScripts() throws DbInitializationException {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (dbInitialized()) {
|
||||
if (!changelogTableExists) {
|
||||
throw new DBNotInitializedException(
|
||||
throw new DbInitializationException(
|
||||
"Unable to determine required updates because SYS_DB_CHANGELOG table doesn't exist");
|
||||
} else {
|
||||
List<ScriptResource> files = getUpdateScripts();
|
||||
@ -106,7 +106,7 @@ public class DbUpdaterEngine implements DbUpdater {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new DBNotInitializedException(
|
||||
throw new DbInitializationException(
|
||||
"Unable to determine required updates because SEC_USER table doesn't exist");
|
||||
}
|
||||
return list;
|
||||
@ -147,7 +147,7 @@ public class DbUpdaterEngine implements DbUpdater {
|
||||
return path.substring(indexOfDir + dir.length() + 1).replaceAll("^/+", "");
|
||||
}
|
||||
|
||||
protected boolean dbInitialized() {
|
||||
public boolean dbInitialized() throws DbInitializationException {
|
||||
log.trace("Checking if the database is initialized");
|
||||
Connection connection = null;
|
||||
try {
|
||||
@ -169,7 +169,7 @@ public class DbUpdaterEngine implements DbUpdater {
|
||||
}
|
||||
return found;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("An error occurred while checking database", e);
|
||||
throw new DbInitializationException(true, "Error connecting to database: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (connection != null)
|
||||
try {
|
||||
|
@ -19,7 +19,7 @@ package com.haulmont.cuba.core.sys.utils;
|
||||
|
||||
import com.haulmont.cuba.core.sys.AppComponents;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.core.sys.DBNotInitializedException;
|
||||
import com.haulmont.cuba.core.sys.DbInitializationException;
|
||||
import com.haulmont.cuba.core.sys.dbupdate.DbUpdaterEngine;
|
||||
import com.haulmont.cuba.core.sys.dbupdate.ScriptResource;
|
||||
import org.apache.commons.cli.*;
|
||||
@ -230,7 +230,7 @@ public class DbUpdaterUtil extends DbUpdaterEngine {
|
||||
updatesAvailable = true;
|
||||
} else
|
||||
log.info("No available updates found for database");
|
||||
} catch (DBNotInitializedException e) {
|
||||
} catch (DbInitializationException e) {
|
||||
log.warn("Database not initialized");
|
||||
return;
|
||||
}
|
||||
|
@ -34,11 +34,9 @@ import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
|
||||
@ -48,7 +46,7 @@ import java.util.*;
|
||||
* @see com.haulmont.cuba.security.app.LoginServiceBean
|
||||
*/
|
||||
@Component(LoginWorker.NAME)
|
||||
public class LoginWorkerBean implements LoginWorker, AppContext.Listener, Ordered {
|
||||
public class LoginWorkerBean implements LoginWorker {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(LoginWorkerBean.class);
|
||||
|
||||
@ -414,16 +412,17 @@ public class LoginWorkerBean implements LoginWorker, AppContext.Listener, Ordere
|
||||
|
||||
@Override
|
||||
public UserSession getSession(UUID sessionId) {
|
||||
try {
|
||||
//noinspection UnnecessaryLocalVariable
|
||||
UserSession session = userSessionManager.getSession(sessionId);
|
||||
return session;
|
||||
} catch (RuntimeException e) {
|
||||
if (e instanceof NoUserSessionException)
|
||||
return null;
|
||||
else
|
||||
throw e;
|
||||
UserSession session = userSessionManager.findSession(sessionId);
|
||||
if (session == null && sessionId.equals(configuration.getConfig(GlobalConfig.class).getAnonymousSessionId())) {
|
||||
synchronized (this) {
|
||||
session = userSessionManager.findSession(sessionId);
|
||||
if (session == null) {
|
||||
initializeAnonymousSession();
|
||||
session = userSessionManager.findSession(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -499,13 +498,8 @@ public class LoginWorkerBean implements LoginWorker, AppContext.Listener, Ordere
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
AppContext.addListener(this);
|
||||
}
|
||||
|
||||
protected void initializeAnonymousSession() {
|
||||
log.debug("Initialize anonymous session");
|
||||
log.info("Initializing anonymous session");
|
||||
|
||||
try {
|
||||
UserSession session = loginAnonymous();
|
||||
@ -515,18 +509,4 @@ public class LoginWorkerBean implements LoginWorker, AppContext.Listener, Ordere
|
||||
log.error("Unable to login anonymous session", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStarted() {
|
||||
initializeAnonymousSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStopped() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return LOWEST_PLATFORM_PRECEDENCE - 110;
|
||||
}
|
||||
}
|
@ -26,6 +26,8 @@ import org.apache.commons.lang.text.StrSubstitutor;
|
||||
import org.apache.commons.lang.text.StrTokenizer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@ -73,9 +75,17 @@ public abstract class AbstractWebAppContextLoader extends AbstractAppContextLoad
|
||||
|
||||
AppContext.Internals.startContext();
|
||||
log.info("AppContext initialized");
|
||||
} catch (Throwable e) {
|
||||
} catch (RuntimeException e) {
|
||||
log.error("Error initializing application", e);
|
||||
throw new RuntimeException(e);
|
||||
try {
|
||||
ApplicationContext springContext = AppContext.getApplicationContext();
|
||||
if (springContext != null) {
|
||||
((ConfigurableApplicationContext) springContext).close();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
log.debug("Error closing application context: {}", e1.toString());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ public class CubaThreadPoolTaskScheduler extends ThreadPoolTaskScheduler impleme
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
t.interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.beforeExecute(t, r);
|
||||
|
@ -1,27 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
public class DBNotInitializedException extends Exception {
|
||||
public DBNotInitializedException() {
|
||||
}
|
||||
|
||||
public DBNotInitializedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
public class DbInitializationException extends Exception {
|
||||
|
||||
private boolean retryPossible;
|
||||
|
||||
public DbInitializationException() {
|
||||
}
|
||||
|
||||
public DbInitializationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DbInitializationException(boolean retryPossible, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.retryPossible = retryPossible;
|
||||
}
|
||||
|
||||
public boolean isRetryPossible() {
|
||||
return retryPossible;
|
||||
}
|
||||
}
|
@ -21,7 +21,9 @@ import java.util.List;
|
||||
public interface DbUpdater {
|
||||
String NAME = "cuba_DbUpdater";
|
||||
|
||||
void updateDatabase();
|
||||
boolean dbInitialized() throws DbInitializationException;
|
||||
|
||||
List<String> findUpdateDatabaseScripts() throws DBNotInitializedException;
|
||||
void updateDatabase() throws DbInitializationException;
|
||||
|
||||
List<String> findUpdateDatabaseScripts() throws DbInitializationException;
|
||||
}
|
Loading…
Reference in New Issue
Block a user