Fix su sincronizzazioni

This commit is contained in:
2025-09-09 16:51:08 +02:00
parent 1fb09d1a41
commit a3eade290e
8 changed files with 298 additions and 395 deletions

View File

@@ -13,7 +13,6 @@ import it.integry.ems.task.TaskExecutorService;
import it.integry.ems.user.service.UserCacheService; import it.integry.ems.user.service.UserCacheService;
import it.integry.ems_model.entity.Azienda; import it.integry.ems_model.entity.Azienda;
import it.integry.ems_model.service.SetupGest; import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityString; import it.integry.ems_model.utility.UtilityString;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -90,10 +89,7 @@ public class EmsCoreDBLoader {
futureTasks.add(() -> { futureTasks.add(() -> {
try { try {
Connection connection = connectionPool.getConnection(modelAtomicReference.get()); Connection connection = connectionPool.getConnection(modelAtomicReference.get());
String sql = "SELECT db_distributore FROM azienda"; multiDBTransactionManager.addConnection(connection);
String dbDistributore = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(connection, sql);
multiDBTransactionManager.addConnection(connection, modelAtomicReference.get().getDbName().equalsIgnoreCase(dbDistributore));
return null; return null;
} catch (Exception ex) { } catch (Exception ex) {

View File

@@ -0,0 +1,8 @@
package it.integry.ems.exception;
public class DistributoreDatabaseNotPresentException extends Exception {
public DistributoreDatabaseNotPresentException() {
super("Distributore database not present yet");
}
}

View File

@@ -255,8 +255,10 @@ public class EntityProcessor {
entity.manageWithParentConnection(primaryDB); entity.manageWithParentConnection(primaryDB);
} else { } else {
String profileDbDistributore = syncManager.getDistributoreProfileDb(currentProfileDb); // String profileDbDistributore = syncManager.getDistributoreProfileDb(currentProfileDb);
String profileDbDistributore = multiDBTransactionManager.getDistributoreProfileName();
List<StbSubscription> syncDetails = syncManager.getSyncDetailIfPresent(currentDB.getProfileName(), profileDbDistributore, entity.getTableName()); List<StbSubscription> syncDetails = syncManager.getSyncDetailIfPresent(currentDB.getProfileName(), profileDbDistributore, entity.getTableName());
boolean isSyncActive = syncDetails != null && !syncDetails.isEmpty(); boolean isSyncActive = syncDetails != null && !syncDetails.isEmpty();
boolean isCurrentlyOnDistributore = UtilityString.isNullOrEmpty(profileDbDistributore) || profileDbDistributore.equalsIgnoreCase(currentProfileDb); boolean isCurrentlyOnDistributore = UtilityString.isNullOrEmpty(profileDbDistributore) || profileDbDistributore.equalsIgnoreCase(currentProfileDb);
@@ -264,11 +266,11 @@ public class EntityProcessor {
logger.info("SINCRONIZZAZIONE su entity " + entity.getTableName() + " ONLINE: " + isSyncActive); logger.info("SINCRONIZZAZIONE su entity " + entity.getTableName() + " ONLINE: " + isSyncActive);
if (!isCurrentlyOnDistributore) { if (!isCurrentlyOnDistributore) {
if (!multiDBTransactionManager.containsDB(profileDbDistributore)) { // if (!multiDBTransactionManager.containsDB(profileDbDistributore)) {
multiDBTransactionManager.addConnection(profileDbDistributore, true); // multiDBTransactionManager.addConnection(profileDbDistributore, true);
} // }
currentDB = multiDBTransactionManager.getDatabaseConnection(profileDbDistributore); currentDB = multiDBTransactionManager.addAndGetDistributoreConnection();
} }
StbSubscription syncDetail = syncDetails.stream() StbSubscription syncDetail = syncDetails.stream()

View File

@@ -1,91 +0,0 @@
package it.integry.ems.sync.MultiDBTransaction;
import it.integry.ems.datasource.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Savepoint;
public class AdvancedDataSource {
private String profileName;
private DataSource dataSource;
private boolean isDistributore;
private boolean isInternalDb;
private Savepoint lastSavePoint;
public AdvancedDataSource(String profileName, DataSource dataSource, boolean isDistributore, boolean isInternalDb) {
this.profileName = profileName;
this.dataSource = dataSource;
this.isDistributore = isDistributore;
this.isInternalDb = isInternalDb;
}
public void makeSavePoint() throws SQLException, IOException {
if (!dataSource.isClosed()) {
lastSavePoint = dataSource.getConnection().setSavepoint();
}
}
public void rollbackNow() throws SQLException, IOException {
if (!dataSource.isClosed()) {
if (lastSavePoint != null) {
dataSource.getConnection().rollback(lastSavePoint);
} else {
dataSource.getConnection().rollback();
}
}
}
void commit() throws SQLException, IOException {
if (!dataSource.isClosed()) {
dataSource.getConnection().commit();
}
}
void close() throws SQLException, IOException {
if (!dataSource.isClosed()) {
dataSource.getConnection().close();
}
}
boolean isClosed() throws SQLException {
return dataSource.isClosed();
}
public Connection getConnection() throws IOException, SQLException {
return dataSource.getConnection();
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public boolean getIsDistributore() {
return isDistributore;
}
public void setDistributore(boolean distributore) {
isDistributore = distributore;
}
public String getProfileName() {
return profileName;
}
public void setProfileName(String profileName) {
this.profileName = profileName;
}
public boolean isInternalDb() {
return isInternalDb;
}
}

View File

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -90,7 +91,7 @@ public class BasicConnectionPool {
return ds; return ds;
} }
public Connection getConnection(AvailableConnectionsModel connectionsModel) throws Exception { public Connection getConnection(AvailableConnectionsModel connectionsModel) throws SQLException {
if (connectionsModel == null) { if (connectionsModel == null) {
return null; return null;
} }

View File

@@ -18,7 +18,6 @@ public class Connection implements java.sql.Connection {
private long sessionId; private long sessionId;
private String profileName; private String profileName;
private boolean isDistributore;
private boolean isInternalDb; private boolean isInternalDb;
@@ -347,16 +346,6 @@ public class Connection implements java.sql.Connection {
this.profileName = profileName; this.profileName = profileName;
return this; return this;
} }
public boolean isDistributore() {
return isDistributore;
}
public Connection setDistributore(boolean distributore) {
isDistributore = distributore;
return this;
}
public boolean isInternalDb() { public boolean isInternalDb() {
return isInternalDb; return isInternalDb;
} }

View File

@@ -1,6 +1,8 @@
package it.integry.ems.sync.MultiDBTransaction; package it.integry.ems.sync.MultiDBTransaction;
import it.integry.common.var.EmsDBConst;
import it.integry.ems._context.ApplicationContextProvider; import it.integry.ems._context.ApplicationContextProvider;
import it.integry.ems.exception.DistributoreDatabaseNotPresentException;
import it.integry.ems.exception.PrimaryDatabaseNotPresentException; import it.integry.ems.exception.PrimaryDatabaseNotPresentException;
import it.integry.ems.javabeans.RequestDataDTO; import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.properties.EmsProperties; import it.integry.ems.properties.EmsProperties;
@@ -42,6 +44,9 @@ public class MultiDBTransactionManager implements AutoCloseable {
@Autowired @Autowired
private RequestDataDTO requestData; private RequestDataDTO requestData;
@Autowired
private EmsDBConst emsDBConst;
private boolean enableLog = true; private boolean enableLog = true;
@@ -95,17 +100,13 @@ public class MultiDBTransactionManager implements AutoCloseable {
this.addConnection(availableConnectionsModel.getProfileName()); this.addConnection(availableConnectionsModel.getProfileName());
} }
public void addConnection(String profileName) throws Exception { public void addConnection(String profileName) throws SQLException {
this.addConnection(profileName, false);
}
public void addConnection(String profileName, boolean isDistributore) throws Exception {
AvailableConnectionsModel availableConnectionsModel = settingsModel.findConnectionModel(profileName); AvailableConnectionsModel availableConnectionsModel = settingsModel.findConnectionModel(profileName);
Connection connection = connectionPool.getConnection(availableConnectionsModel); Connection connection = connectionPool.getConnection(availableConnectionsModel);
this.addConnection(connection, isDistributore); this.addConnection(connection);
} }
public void addConnection(Connection connection, boolean isDistributore) { public void addConnection(Connection connection) {
if (allConnections != null) { if (allConnections != null) {
if (requestData != null && requestData.getRequestURI() != null) { if (requestData != null && requestData.getRequestURI() != null) {
String methodName = " [" + requestData.getRequestURI() + "]"; String methodName = " [" + requestData.getRequestURI() + "]";
@@ -118,30 +119,20 @@ public class MultiDBTransactionManager implements AutoCloseable {
connectionListLock.lock(); connectionListLock.lock();
try { try {
allConnections.add(connection); allConnections.add(connection);
if (isDistributore) {
allConnections = allConnections.stream()
.sorted((o1, o2) -> {
if (o1.isDistributore() && !o2.isDistributore()) return -1;
else if (!o1.isDistributore() && o2.isDistributore()) return 1;
else return 0;
})
.collect(Collectors.toList());
}
} finally { } finally {
connectionListLock.unlock(); connectionListLock.unlock();
} }
} }
} }
public boolean containsDB(final String dbName) { public boolean containsDB(final String profileDb) {
if (allConnections != null) { if (allConnections != null) {
return allConnections.stream() return allConnections.stream()
.anyMatch(advancedDataSource -> advancedDataSource.getProfileName().equalsIgnoreCase(dbName)); .anyMatch(advancedDataSource -> advancedDataSource.getProfileName().equalsIgnoreCase(profileDb));
} else return false; } else return false;
} }
public Connection getDatabaseConnection(final String profileName) throws Exception { public Connection getDatabaseConnection(final String profileName) {
List<Connection> resultList = allConnections.stream() List<Connection> resultList = allConnections.stream()
.filter(advancedDataSource -> advancedDataSource.getProfileName().equalsIgnoreCase(profileName)) .filter(advancedDataSource -> advancedDataSource.getProfileName().equalsIgnoreCase(profileName))
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -149,7 +140,7 @@ public class MultiDBTransactionManager implements AutoCloseable {
if (!resultList.isEmpty()) { if (!resultList.isEmpty()) {
return resultList.get(0); return resultList.get(0);
} else { } else {
throw new Exception("Database not present in connections list"); throw new RuntimeException("Database not present in connections list");
} }
} }
@@ -162,17 +153,25 @@ public class MultiDBTransactionManager implements AutoCloseable {
} }
} }
public String getDistributoreProfileName() throws PrimaryDatabaseNotPresentException { public String getDistributoreProfileName() throws DistributoreDatabaseNotPresentException, PrimaryDatabaseNotPresentException {
for (Connection connection : allConnections) { final String dbDistributoreDbName = emsDBConst.getConsts(getPrimaryConnection().getDbName())
if (connection.isDistributore()) { .getAzienda()
return connection.getProfileName(); .getDbDistributore();
}
} if(dbDistributoreDbName == null)
return getPrimaryConnection().getProfileName(); throw new DistributoreDatabaseNotPresentException();
return dbDistributoreDbName;
} }
public Connection getDistributoreConnection() throws Exception { public Connection addAndGetDistributoreConnection() throws DistributoreDatabaseNotPresentException, SQLException, PrimaryDatabaseNotPresentException {
return connectionPool.getConnection(settingsModel.findConnectionModel(getDistributoreProfileName())); final String distributoreProfileName = getDistributoreProfileName();
if(!containsDB(distributoreProfileName))
addConnection(distributoreProfileName);
return getDatabaseConnection(distributoreProfileName);
} }
@@ -295,7 +294,7 @@ public class MultiDBTransactionManager implements AutoCloseable {
primaryConnection = connectionPool.getConnection(connectionModel); primaryConnection = connectionPool.getConnection(connectionModel);
this.allConnections = new ArrayList<>(); this.allConnections = new ArrayList<>();
this.addConnection(primaryConnection, false); this.addConnection(primaryConnection);
} }

View File

@@ -70,37 +70,35 @@ public class SyncManager {
try { try {
logger.debug("Avvio sincronizzazione per " + entitySource.getTableName() + " su " + multiDBTransactionManager.getDistributoreProfileName()); logger.debug("Avvio sincronizzazione per " + entitySource.getTableName() + " su " + multiDBTransactionManager.getDistributoreProfileName());
Connection connection;
EntityInterface entityToSave;
if (multiDBTransactionManager.getPrimaryConnection().getProfileName().equalsIgnoreCase(multiDBTransactionManager.getDistributoreProfileName())) { if (multiDBTransactionManager.getPrimaryConnection().getProfileName().equalsIgnoreCase(multiDBTransactionManager.getDistributoreProfileName())) {
try { connection = multiDBTransactionManager.getPrimaryConnection();
entitySource.manageWithParentConnection(multiDBTransactionManager.getPrimaryConnection()); entityToSave = entitySource;
proceedSyncronization(entitySource, entityCloned, lastProfileUsed, multiDBTransactionManager);
multiDBTransactionManager.getPrimaryConnection().commit();
} catch (Exception e) {
multiDBTransactionManager.getPrimaryConnection().rollback();
throw e;
}
} else { } else {
try (Connection distributoreConnection = multiDBTransactionManager.getDistributoreConnection()) { connection = multiDBTransactionManager.addAndGetDistributoreConnection();
try { entityToSave = entityCloned;
entityCloned.dataCompleting(distributoreConnection);
entityCloned.manageWithParentConnection(distributoreConnection);
entityToSave.dataCompleting(connection);
}
entityToSave.manageWithParentConnection(connection);
proceedSyncronization(entitySource, entityCloned, lastProfileUsed, multiDBTransactionManager); proceedSyncronization(entitySource, entityCloned, lastProfileUsed, multiDBTransactionManager);
distributoreConnection.commit(); multiDBTransactionManager.commitAll();
} catch (Exception e) {
distributoreConnection.rollback();
throw e;
}
}
}
} catch (Exception e) { } catch (Exception e) {
multiDBTransactionManager.rollbackAll();
String subscriptor = null; String subscriptor = null;
if (e instanceof SyncException) subscriptor = ((SyncException) e).getProfileDb(); if (e instanceof SyncException) subscriptor = ((SyncException) e).getProfileDb();
else { else {
if (UtilityString.isNullOrEmpty(lastProfileUsed[0].toString())) subscriptor = ""; if (UtilityString.isNullOrEmpty(lastProfileUsed[0].toString())) subscriptor = "";
else subscriptor = lastProfileUsed[0].toString(); else subscriptor = lastProfileUsed[0].toString();
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
objectMapper.writeValue(baos, entitySource); objectMapper.writeValue(baos, entitySource);
baos.close(); baos.close();
@@ -226,7 +224,8 @@ public class SyncManager {
public String getDistributoreProfileDb(String profileDb) { public String getDistributoreProfileDb(String profileDb) {
return emsDBConst.getConstsByProfile(profileDb) return emsDBConst.getConstsByProfile(profileDb)
.getAzienda().getDbDistributore(); .getAzienda()
.getDbDistributore();
} }
public List<StbSubscription> getSyncDetailIfPresent(String profileDb, String profileDbDistributore, String tableName) { public List<StbSubscription> getSyncDetailIfPresent(String profileDb, String profileDbDistributore, String tableName) {