diff --git a/ems-core/src/main/java/it/integry/ems/datasource/DataSource.java b/ems-core/src/main/java/it/integry/ems/datasource/DataSource.java index 07a26c4fc8..7ac98d9330 100644 --- a/ems-core/src/main/java/it/integry/ems/datasource/DataSource.java +++ b/ems-core/src/main/java/it/integry/ems/datasource/DataSource.java @@ -6,6 +6,7 @@ import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems_model.config.EmsRestConstants; import it.integry.ems_model.utility.UtilityDB; import it.integry.ems_model.utility.UtilityHashMap; +import it.integry.ems_model.utility.UtilityString; import org.apache.commons.dbcp2.BasicDataSource; import java.sql.SQLException; @@ -13,6 +14,8 @@ import java.util.HashMap; public class DataSource extends BasicDataSource { + private final int POOL_SIZE; + private AvailableConnectionModel connectionModel; /** @@ -24,6 +27,13 @@ public class DataSource extends BasicDataSource { @Deprecated public DataSource() { super(); + POOL_SIZE = 5; + } + + @Deprecated + public DataSource(int poolSize) { + super(); + POOL_SIZE = poolSize; } public EmsRestConstants.DB_TYPE getTypeDB() { @@ -62,12 +72,20 @@ public class DataSource extends BasicDataSource { } public synchronized void initialize(String profileDB) throws Exception { + initialize(profileDB, null); + } + + public synchronized void initialize(String profileDB, String customAppName) throws Exception { AvailableConnectionModel connectionsModel = SettingsModel.getInstance().findConnectionModel(profileDB); - initialize(connectionsModel); + initialize(connectionsModel, customAppName); } public synchronized void initialize(AvailableConnectionModel connectionModel) throws Exception { + initialize(connectionModel, null); + } + + public synchronized void initialize(AvailableConnectionModel connectionModel, String customAppName) throws Exception { if (connectionModel == null) { throw new Exception("Configurazione DB non trovata"); } @@ -76,7 +94,7 @@ public class DataSource extends BasicDataSource { this.setDriverClassName(connectionModel.getDriverClassName()); - this.setUrl(connectionModel.getDbConnectionString("EMS Connection")); + this.setUrl(connectionModel.getDbConnectionString(UtilityString.isNull(customAppName, "EMS Connection"))); this.setUsername(connectionModel.getUsername()); this.setPassword(connectionModel.getPasswordDecrypted()); this.setDefaultCatalog(connectionModel.getDbName()); @@ -87,9 +105,9 @@ public class DataSource extends BasicDataSource { // ===== OTTIMIZZAZIONI CRITICHE ===== // Pool sizing ottimizzato per READ_UNCOMMITTED (meno locking = più connessioni possibili) - this.setInitialSize(5); // Inizia con più connessioni + this.setInitialSize(POOL_SIZE); // Inizia con più connessioni this.setMaxTotal(-1); // Aumentato il massimo - this.setMinIdle(5); // Non scendere sotto 5 + this.setMinIdle(POOL_SIZE); // Non scendere sotto 5 this.setMaxIdle(-1); // Mantieni più connessioni idle // Timeout ottimizzati per performance massime diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java new file mode 100644 index 0000000000..a9d0d1a6eb --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java @@ -0,0 +1,262 @@ +package it.integry.ems.dbms_change_tracker.component; + +import com.microsoft.sqlserver.jdbc.SQLServerConnection; +import it.integry.ems.datasource.DataSource; +import it.integry.ems.dbms_change_tracker.model.ChangeTrackingConfigDTO; +import it.integry.ems.dbms_change_tracker.model.DetectedChangeDataDTO; +import it.integry.ems.sync.MultiDBTransaction.Connection; +import it.integry.ems_model.exception.DataConverterNotFoundException; +import it.integry.ems_model.utility.UtilityDB; +import it.integry.ems_model.utility.UtilityHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +public class DbmsChangeTracker { + + private DataSource dataSource; + private final Logger logger = LogManager.getLogger(); + + + private final int CHANGE_RETENTION_HOURS = 1; + private final boolean AUTO_CLEANUP = true; + + private Connection integryConnection; + private boolean trackerEnabled = false; + private long currentVersion; + + + private Listener eventListener; + + public DbmsChangeTracker(String profileDb) throws Exception { + createDataSource(profileDb); + createConnection(); + } + + private void createDataSource(String profileDb) throws Exception { + DataSource ds = new DataSource(1); + ds.initialize(profileDb, "Integry Changes Tracker"); + this.dataSource = ds; + } + + private void createConnection() throws SQLException { + integryConnection = dataSource.getConnection(); + if (!(integryConnection.isWrapperFor(SQLServerConnection.class))) { + integryConnection.close(); + + throw new SQLException("Connection is not a SQL Server connection"); + } + } + + public void enableTrackerInDbms() throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + final ChangeTrackingConfigDTO currentConfig = retrieveTrackerCurrentConfig(); + if (currentConfig != null) { + logInfo("Changes Tracker is already enabled (with " + currentConfig.getRetentionPeriod() + " " + currentConfig.getRetentionPeriodUnit().toLowerCase() + " retention and auto cleanup " + (currentConfig.isAutoCleanupOn() ? "ON" : "OFF") + ")"); + return; + } + + String enableSql = "ALTER DATABASE " + integryConnection.getDbName() + " \n" + + "SET CHANGE_TRACKING = ON (" + + "CHANGE_RETENTION = " + CHANGE_RETENTION_HOURS + " HOURS, " + + "AUTO_CLEANUP = " + (AUTO_CLEANUP ? "ON" : "OFF") + + ");\n"; + + //COMMIT necessario perché ALTER DATABASE richiede che non ci siano altre transazioni attive + UtilityDB.executeStatement(integryConnection, "COMMIT", enableSql); + + logInfo("Changes Tracker is now enabled (with " + CHANGE_RETENTION_HOURS + " hours retention and auto cleanup " + (AUTO_CLEANUP ? "ON" : "OFF") + ")"); + } + + + public void enableTrackerOnTable(String tableName) throws SQLException { + if (isTableTrackingEnabled(tableName)) { + return; + } + + UtilityDB.executeStatement(integryConnection, "ALTER TABLE dbo." + tableName + "\n" + + "ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = ON);", "COMMIT"); + } + + + public void disableTrackerOnNotUsedTables(List usedTables) throws SQLException { + final List trackedTables = retrieveTrackedTables(); + + trackedTables.removeAll(usedTables); + + for (String tableName : trackedTables) { + disableTrackerOnTable(tableName); + } + } + + public void disableTrackerOnTable(String tableName) throws SQLException { + if (!isTableTrackingEnabled(tableName)) { + return; + } + + UtilityDB.executeStatement(integryConnection, "ALTER TABLE dbo." + tableName + "\n" + + "DISABLE CHANGE_TRACKING;", "COMMIT"); + } + + + public void startTracking() throws SQLException { + currentVersion = retrieveCurrentVersion(); + trackerEnabled = true; + } + + public void checkForChanges() throws Exception { + if (!trackerEnabled) + return; + + final List trackedTables = retrieveTrackedTables(); + + HashMap changesByVersion = new HashMap<>(); + + for (String trackedTable : trackedTables) { + long minValidVersion = getMinValidVersion(trackedTable); + if (currentVersion < minValidVersion) { + throw new SQLException("Change Tracking on table " + trackedTable + " has been reset. Current version: " + currentVersion + ", Min valid version: " + minValidVersion); + } + + + final List detectedChanges = retrieveChangeList(trackedTable); + + detectedChanges.forEach(detectedChangeDataDTO -> { + changesByVersion.put(detectedChangeDataDTO.getSysChangeVersion(), detectedChangeDataDTO); + }); + + } + + logTrace("Detected " + changesByVersion.size() + " changes since version " + currentVersion); + + dispatchChanges(changesByVersion); + } + + private void dispatchChanges(HashMap changesByVersion) throws Exception { + final List sortedChanges = changesByVersion.keySet().stream() + .sorted() + .collect(Collectors.toList()); + + + for (Long changeId : sortedChanges) { + final DetectedChangeDataDTO detectedChange = changesByVersion.get(changeId); + + switch (detectedChange.getSysChangeOperation()) { + case INSERT: + if (eventListener != null) + eventListener.onInsertDetected(detectedChange.getTableName(), detectedChange.getPrimaryKey()); + break; + + case UPDATE: + if (eventListener != null) + eventListener.onUpdateDetected(detectedChange.getTableName(), detectedChange.getPrimaryKey()); + break; + + case DELETE: + if (eventListener != null) + eventListener.onDeleteDetected(detectedChange.getTableName(), detectedChange.getPrimaryKey()); + break; + } + + currentVersion = changeId; + } + } + + + private List retrieveChangeList(String tableName) throws SQLException { + String sql = "SELECT *\n" + + "FROM CHANGETABLE(CHANGES dbo." + tableName + ", " + currentVersion + ") AS c"; + final List> result = UtilityDB.executeSimpleQuery(integryConnection, sql); + + return result.stream() + .map(x -> { + DetectedChangeDataDTO detectedChangeDataDTO = new DetectedChangeDataDTO() + .setTableName(tableName) + .setSysChangeVersion(UtilityHashMap.getValueIfExists(x, "SYS_CHANGE_VERSION")) + .setSysChangeCreationVersion(UtilityHashMap.getValueIfExists(x, "SYS_CHANGE_CREATION_VERSION")) + .setSysChangeOperation(DetectedChangeDataDTO.Operation.from(UtilityHashMap.getValueIfExists(x, "SYS_CHANGE_OPERATION"))); + + x.remove("SYS_CHANGE_VERSION"); + x.remove("SYS_CHANGE_CREATION_VERSION"); + x.remove("SYS_CHANGE_OPERATION"); + x.remove("SYS_CHANGE_COLUMNS"); + x.remove("SYS_CHANGE_CONTEXT"); + + detectedChangeDataDTO.setPrimaryKey(x); + + return detectedChangeDataDTO; + }) + .collect(Collectors.toList()); + } + + private long retrieveCurrentVersion() throws SQLException { + String sql = "SELECT CHANGE_TRACKING_CURRENT_VERSION() AS current_version"; + + long currentVersion = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(integryConnection, sql); + return currentVersion; + } + + private long getMinValidVersion(String table) throws SQLException { + String sql = "SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(" + UtilityDB.valueToString(table) + "))"; + + long minValidVersion = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(integryConnection, sql); + return minValidVersion; + } + + private List retrieveTrackedTables() throws SQLException { + String sql = "SELECT OBJECT_NAME(object_id) AS table_name\n" + + " FROM sys.change_tracking_tables"; + + List trackedTables = UtilityDB.executeSimpleQueryOnlyFirstColumn(integryConnection, sql); + return trackedTables; + } + + private boolean isTableTrackingEnabled(String tableName) throws SQLException { + String sql = "SELECT CAST(COUNT(is_track_columns_updated_on) AS BIT) AS enabled\n" + + " FROM sys.change_tracking_tables \n" + + " WHERE object_id = OBJECT_ID('dbo." + tableName + "')"; + + boolean enabled = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(integryConnection, sql); + return enabled; + } + + private ChangeTrackingConfigDTO retrieveTrackerCurrentConfig() throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + String checkSql = "SELECT DB_NAME(database_id) as database_name,\n" + + "CAST(is_auto_cleanup_on AS BIT) AS is_auto_cleanup_on,\n" + + "retention_period,\n" + + "retention_period_units_desc,\n" + + "max_cleanup_version\n" + + "FROM sys.change_tracking_databases \n" + + "WHERE DB_NAME(database_id)=DB_NAME()"; + + final ChangeTrackingConfigDTO currentConfig = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(integryConnection, checkSql, ChangeTrackingConfigDTO.class); + + return currentConfig; + } + + + private void logInfo(String message) { + logger.info("[" + integryConnection.getProfileName() + "] " + message); + } + + private void logTrace(String message) { + logger.trace("[" + integryConnection.getProfileName() + "] " + message); + } + + + public DbmsChangeTracker setEventListener(Listener eventListener) { + this.eventListener = eventListener; + return this; + } + + public interface Listener { + void onInsertDetected(String tableName, HashMap primaryKey) throws Exception; + + void onUpdateDetected(String tableName, HashMap primaryKey) throws Exception; + + void onDeleteDetected(String tableName, HashMap primaryKey) throws Exception; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java new file mode 100644 index 0000000000..62d66d4684 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java @@ -0,0 +1,121 @@ +package it.integry.ems.dbms_change_tracker.component; + +import it.integry.annotations.PostContextAutowired; +import it.integry.annotations.PostContextConstruct; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordDeletedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordInsertedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordUpdatedEvent; +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.ems.sync.MultiDBTransaction.Connection; +import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; +import it.integry.ems_model.entity.MtbAart; +import it.integry.ems_model.entity.StbGestSetup; +import it.integry.ems_model.entity.StbGestSetupDepo; +import it.integry.ems_model.entity.WtbGestSetupUser; +import it.integry.ems_model.exception.DataConverterNotFoundException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Component +public class DbmsChangeTrackerComponent { + private final Logger logger = LogManager.getLogger(); + + private final HashMap activeChangeTrackers = new HashMap<>(); + + private final ArrayList trackedTables = new ArrayList() {{ + add(MtbAart.ENTITY); + add(StbGestSetup.ENTITY); + add(StbGestSetupDepo.ENTITY); + add(WtbGestSetupUser.ENTITY); + }}; + + + private final ApplicationEventPublisher applicationEventPublisher; + + @PostContextAutowired + private MultiDBTransactionManager multiDBTransactionManager; + + public DbmsChangeTrackerComponent(ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + + + @PostContextConstruct + public void init() throws Exception { + for (Connection conn : multiDBTransactionManager.getActiveConnections()) { + IntegryCustomerDB customerDB = IntegryCustomerDB.parse(conn.getDbName()); + activeChangeTrackers.put(customerDB, new DbmsChangeTracker(conn.getProfileName())); + } + + enableAllChangeTracking(); + } + + + private void enableAllChangeTracking() throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + for (Map.Entry entrySet : activeChangeTrackers.entrySet()) { + IntegryCustomerDB customerDB = entrySet.getKey(); + DbmsChangeTracker dbmsChangeTracker = entrySet.getValue(); + + dbmsChangeTracker.enableTrackerInDbms(); + + for (String tableName : trackedTables) { + dbmsChangeTracker.enableTrackerOnTable(tableName); + } + + dbmsChangeTracker.disableTrackerOnNotUsedTables(trackedTables); + + dbmsChangeTracker.setEventListener(new DbmsChangeTracker.Listener() { + @Override + public void onInsertDetected(String tableName, HashMap primaryKey) { + onItemInserted(customerDB, tableName, primaryKey); + } + + @Override + public void onUpdateDetected(String tableName, HashMap primaryKey) { + onItemUpdated(customerDB, tableName, primaryKey); + } + + @Override + public void onDeleteDetected(String tableName, HashMap primaryKey) { + onItemDeleted(customerDB, tableName, primaryKey); + } + }); + + dbmsChangeTracker.startTracking(); + } + } + + + @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS) + private void checkAllChanges() throws Exception { + for (DbmsChangeTracker dbmsChangeTracker : activeChangeTrackers.values()) { + dbmsChangeTracker.checkForChanges(); + } + } + + + private void onItemInserted(IntegryCustomerDB customerDB, String tableName, HashMap primaryKey) { + logger.trace("Item inserted in profileDb {} table {} with primaryKey {}", customerDB.getValue(), tableName, primaryKey); + applicationEventPublisher.publishEvent(new TableRecordInsertedEvent(this, customerDB, tableName, primaryKey)); + } + + private void onItemUpdated(IntegryCustomerDB customerDB, String tableName, HashMap primaryKey) { + logger.trace("Item updated in profileDb {} table {} with primaryKey {}", customerDB.getValue(), tableName, primaryKey); + applicationEventPublisher.publishEvent(new TableRecordUpdatedEvent(this, customerDB, tableName, primaryKey)); + } + + private void onItemDeleted(IntegryCustomerDB customerDB, String tableName, HashMap primaryKey) { + logger.trace("Item deleted in profileDb {} table {} with primaryKey {}", customerDB.getValue(), tableName, primaryKey); + applicationEventPublisher.publishEvent(new TableRecordDeletedEvent(this, customerDB, tableName, primaryKey)); + } + +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/ChangeTrackingConfigDTO.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/ChangeTrackingConfigDTO.java new file mode 100644 index 0000000000..693471e201 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/ChangeTrackingConfigDTO.java @@ -0,0 +1,67 @@ +package it.integry.ems.dbms_change_tracker.model; + +import it.integry.ems_model.annotation.SqlField; + +public class ChangeTrackingConfigDTO { + + @SqlField("database_name") + private String databaseName; + + @SqlField("is_auto_cleanup_on") + private boolean autoCleanupOn; + + @SqlField("retention_period") + private int retentionPeriod; + + @SqlField("retention_period_units_desc") + private String retentionPeriodUnit; + + // @SqlField("max_cleanup_version") + private Object maxCleanupVersion; + + + public String getDatabaseName() { + return databaseName; + } + + public ChangeTrackingConfigDTO setDatabaseName(String databaseName) { + this.databaseName = databaseName; + return this; + } + + public boolean isAutoCleanupOn() { + return autoCleanupOn; + } + + public ChangeTrackingConfigDTO setAutoCleanupOn(boolean autoCleanupOn) { + this.autoCleanupOn = autoCleanupOn; + return this; + } + + public int getRetentionPeriod() { + return retentionPeriod; + } + + public ChangeTrackingConfigDTO setRetentionPeriod(int retentionPeriod) { + this.retentionPeriod = retentionPeriod; + return this; + } + + public String getRetentionPeriodUnit() { + return retentionPeriodUnit; + } + + public ChangeTrackingConfigDTO setRetentionPeriodUnit(String retentionPeriodUnit) { + this.retentionPeriodUnit = retentionPeriodUnit; + return this; + } + + public Object getMaxCleanupVersion() { + return maxCleanupVersion; + } + + public ChangeTrackingConfigDTO setMaxCleanupVersion(Object maxCleanupVersion) { + this.maxCleanupVersion = maxCleanupVersion; + return this; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/DetectedChangeDataDTO.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/DetectedChangeDataDTO.java new file mode 100644 index 0000000000..359a085ee0 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/DetectedChangeDataDTO.java @@ -0,0 +1,108 @@ +package it.integry.ems.dbms_change_tracker.model; + +import com.fasterxml.jackson.annotation.JsonValue; +import it.integry.ems_model.entity._enum.IBaseEnum; + +import java.util.HashMap; + +public class DetectedChangeDataDTO { + + private long sysChangeVersion; + private long sysChangeCreationVersion; + private Operation sysChangeOperation; + + private String tableName; + private HashMap primaryKey; + + + public long getSysChangeVersion() { + return sysChangeVersion; + } + + public DetectedChangeDataDTO setSysChangeVersion(long sysChangeVersion) { + this.sysChangeVersion = sysChangeVersion; + return this; + } + + public long getSysChangeCreationVersion() { + return sysChangeCreationVersion; + } + + public DetectedChangeDataDTO setSysChangeCreationVersion(long sysChangeCreationVersion) { + this.sysChangeCreationVersion = sysChangeCreationVersion; + return this; + } + + public Operation getSysChangeOperation() { + return sysChangeOperation; + } + + public DetectedChangeDataDTO setSysChangeOperation(Operation sysChangeOperation) { + this.sysChangeOperation = sysChangeOperation; + return this; + } + + public String getTableName() { + return tableName; + } + + public DetectedChangeDataDTO setTableName(String tableName) { + this.tableName = tableName; + return this; + } + + public HashMap getPrimaryKey() { + return primaryKey; + } + + public DetectedChangeDataDTO setPrimaryKey(HashMap primaryKey) { + this.primaryKey = primaryKey; + return this; + } + + + public enum Operation implements IBaseEnum { + INSERT('I'), + UPDATE('U'), + DELETE('D'); + + private final char value; + + Operation(char value) { + this.value = value; + } + + public static Operation from(Object value) { + if (value instanceof String && ((String) value).length() == 1) { + value = ((String) value).charAt(0); + } + + char castValue = (char) value; + for (Operation b : Operation.values()) { + if (b.value == castValue) + return b; + } + return null; + } + + @JsonValue + public char getValue() { + return this.value; + } + + @Override + public Object get() { + return this.value; + } + + @Override + public Operation fromInternal(Object val) { + return from(val); + } + + @Override + public String toString() { + return String.valueOf(value); + } + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordDeletedEvent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordDeletedEvent.java new file mode 100644 index 0000000000..60a38b0ef3 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordDeletedEvent.java @@ -0,0 +1,27 @@ +package it.integry.ems.dbms_change_tracker.model.events; + +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.event.BaseCustomerDBEvent; + +import java.util.HashMap; + +public class TableRecordDeletedEvent extends BaseCustomerDBEvent { + + private final String tableName; + private final HashMap primaryKey; + + public TableRecordDeletedEvent(Object source, IntegryCustomerDB integryCustomerDB, String tableName, HashMap primaryKey) { + super(source, integryCustomerDB); + + this.tableName = tableName; + this.primaryKey = primaryKey; + } + + public String getTableName() { + return tableName; + } + + public HashMap getPrimaryKey() { + return primaryKey; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordInsertedEvent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordInsertedEvent.java new file mode 100644 index 0000000000..15b93e3bcf --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordInsertedEvent.java @@ -0,0 +1,27 @@ +package it.integry.ems.dbms_change_tracker.model.events; + +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.event.BaseCustomerDBEvent; + +import java.util.HashMap; + +public class TableRecordInsertedEvent extends BaseCustomerDBEvent { + + private final String tableName; + private final HashMap primaryKey; + + public TableRecordInsertedEvent(Object source, IntegryCustomerDB integryCustomerDB, String tableName, HashMap primaryKey) { + super(source, integryCustomerDB); + + this.tableName = tableName; + this.primaryKey = primaryKey; + } + + public String getTableName() { + return tableName; + } + + public HashMap getPrimaryKey() { + return primaryKey; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordUpdatedEvent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordUpdatedEvent.java new file mode 100644 index 0000000000..af125b88a5 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableRecordUpdatedEvent.java @@ -0,0 +1,27 @@ +package it.integry.ems.dbms_change_tracker.model.events; + +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.event.BaseCustomerDBEvent; + +import java.util.HashMap; + +public class TableRecordUpdatedEvent extends BaseCustomerDBEvent { + + private final String tableName; + private final HashMap primaryKey; + + public TableRecordUpdatedEvent(Object source, IntegryCustomerDB customerDB, String tableName, HashMap primaryKey) { + super(source, customerDB); + + this.tableName = tableName; + this.primaryKey = primaryKey; + } + + public String getTableName() { + return tableName; + } + + public HashMap getPrimaryKey() { + return primaryKey; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dynamic_cache/DynamicCacheService.java b/ems-core/src/main/java/it/integry/ems/dynamic_cache/DynamicCacheService.java index 8660b7abd2..fa176ad2dc 100644 --- a/ems-core/src/main/java/it/integry/ems/dynamic_cache/DynamicCacheService.java +++ b/ems-core/src/main/java/it/integry/ems/dynamic_cache/DynamicCacheService.java @@ -37,8 +37,7 @@ public class DynamicCacheService { DATI_AZIENDA_KEY, ENTITY_LOGGER_SETUP, GRIGLIA_ACQUISTO_KEY, - ENTITY_SYNC_KEY, - STB_GEST_SETUP_KEY + ENTITY_SYNC_KEY } public void addItem(Keys key, int invalidateTimeInMins, RunnableWithReturn refreshAction) { diff --git a/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java b/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java new file mode 100644 index 0000000000..e1d884a5e2 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java @@ -0,0 +1,188 @@ +package it.integry.ems.dynamic_cache; + +import it.integry.annotations.PostContextAutowired; +import it.integry.annotations.PostContextConstruct; +import it.integry.ems.dbms_change_tracker.component.DbmsChangeTrackerComponent; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordDeletedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordInsertedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableRecordUpdatedEvent; +import it.integry.ems.dto.EntityHierarchy; +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.ems.sync.MultiDBTransaction.Connection; +import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; +import it.integry.ems_model.base.EntityBase; +import it.integry.ems_model.base.EntityPropertyHolder; +import it.integry.ems_model.entity.MtbAart; +import it.integry.ems_model.entity.StbGestSetup; +import it.integry.ems_model.entity.StbGestSetupDepo; +import it.integry.ems_model.entity.WtbGestSetupUser; +import it.integry.ems_model.exception.DataConverterNotFoundException; +import it.integry.ems_model.utility.UtilityDB; +import it.integry.ems_model.utility.UtilityQuery; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +@Component +public class EntityCacheComponent implements ApplicationListener { + + private final DbmsChangeTrackerComponent dbmsChangeTrackerComponent; + private final EntityPropertyHolder entityPropertyHolder; + + private final HashMap, EntityBase>>> entityCache = new HashMap<>(); + + private final HashMap> enabledEntities = new HashMap>() {{ + put(MtbAart.ENTITY, MtbAart.class); + put(StbGestSetup.ENTITY, StbGestSetup.class); + put(StbGestSetupDepo.ENTITY, StbGestSetupDepo.class); + put(WtbGestSetupUser.ENTITY, WtbGestSetupUser.class); + }}; + + public EntityCacheComponent(DbmsChangeTrackerComponent dbmsChangeTrackerComponent, EntityPropertyHolder entityPropertyHolder) { + this.dbmsChangeTrackerComponent = dbmsChangeTrackerComponent; + this.entityPropertyHolder = entityPropertyHolder; + } + + @PostContextAutowired + private MultiDBTransactionManager multiDBTransactionManager; + + @PostContextConstruct + public void init() throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + + for (Connection conn : multiDBTransactionManager.getActiveConnections()) { + IntegryCustomerDB customerDB = IntegryCustomerDB.parse(conn.getDbName()); + entityCache.putIfAbsent(customerDB, new ConcurrentHashMap<>()); + + for (Map.Entry> enabledEntity : enabledEntities.entrySet()) { + String tableName = enabledEntity.getKey(); + Class clazz = enabledEntity.getValue(); + + ConcurrentHashMap, EntityBase> entities = retrieveEntityList(conn, tableName, clazz); + entityCache.get(customerDB).put(tableName, entities); + } + } + } + + + public List getCachedEntitiesList(IntegryCustomerDB customerDB, String tableName, Predicate filterPredicate) { + List entities = entityCache.get(customerDB).get(tableName) + .values() + .parallelStream() + .map(x -> (T) x) + .filter(filterPredicate) + .map(x -> (T) x.clone()) + .collect(Collectors.toList()); + return entities; + } + + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof TableRecordInsertedEvent) { + handleRecordInserted((TableRecordInsertedEvent) event); + + } else if (event instanceof TableRecordUpdatedEvent) { + handleRecordUpdated((TableRecordUpdatedEvent) event); + + } else if (event instanceof TableRecordDeletedEvent) { + handleRecordDeleted((TableRecordDeletedEvent) event); + + } + } + + + private void handleRecordInserted(TableRecordInsertedEvent event) { + HashMap entityPrimaryKey = convertSqlMapToEntityMap(event.getPrimaryKey(), enabledEntities.get(event.getTableName())); + + try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(event.getCustomerDB())) { + EntityBase newItem = retrieveEntityItem(mdb.getPrimaryConnection(), event.getTableName(), + enabledEntities.get(event.getTableName()), + event.getPrimaryKey()); + + + entityCache.get(event.getCustomerDB()) + .get(event.getTableName()) + .put(entityPrimaryKey, newItem); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void handleRecordUpdated(TableRecordUpdatedEvent event) { + HashMap entityPrimaryKey = convertSqlMapToEntityMap(event.getPrimaryKey(), enabledEntities.get(event.getTableName())); + + try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(event.getCustomerDB())) { + EntityBase newItem = retrieveEntityItem(mdb.getPrimaryConnection(), event.getTableName(), + enabledEntities.get(event.getTableName()), + event.getPrimaryKey()); + + entityCache.get(event.getCustomerDB()) + .get(event.getTableName()) + .put(entityPrimaryKey, newItem); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void handleRecordDeleted(TableRecordDeletedEvent event) { + HashMap entityPrimaryKey = convertSqlMapToEntityMap(event.getPrimaryKey(), enabledEntities.get(event.getTableName())); + + final EntityBase removedItem = entityCache.get(event.getCustomerDB()) + .get(event.getTableName()) + .remove(entityPrimaryKey); + } + + + private ConcurrentHashMap, EntityBase> retrieveEntityList(Connection connection, String tableName, Class clazz) throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + String sql = "SELECT * FROM " + tableName; + + final List objects = UtilityDB.executeSimpleQueryDTO(connection, sql, clazz); + + final List pkFields = entityPropertyHolder.getEntityFields(clazz, EntityHierarchy.Field::isPrimaryKey); + + + ConcurrentHashMap, EntityBase> objectsMap = new ConcurrentHashMap<>(); + for (EntityBase object : objects) { + HashMap pkMap = new HashMap<>(); + for (EntityHierarchy.Field pkField : pkFields) { + Object pkValue = pkField.getField().get(object); + pkMap.put(pkField.getFieldName(), pkValue); + } + objectsMap.put(pkMap, object); + } + + return objectsMap; + } + + private EntityBase retrieveEntityItem(Connection connection, String tableName, Class clazz, HashMap primaryKey) throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { + String sql = "SELECT * FROM " + tableName + "\n" + + " WHERE " + UtilityQuery.concatFieldsInWhereCond(primaryKey); + + final EntityBase object = (EntityBase) UtilityDB.executeSimpleQueryOnlyFirstRowDTO(connection, sql, clazz); + return object; + } + + + private HashMap convertSqlMapToEntityMap(HashMap sqlMap, Class clazz) { + HashMap entityMap = new HashMap<>(); + for (Map.Entry entry : sqlMap.entrySet()) { + String fieldName = entityPropertyHolder.getEntityFields(clazz, f -> f.isSqlField() && f.getSqlField().value().equals(entry.getKey())) + .stream() + .findFirst() + .map(EntityHierarchy.Field::getFieldName) + .orElse(entry.getKey()); + entityMap.put(fieldName, entry.getValue()); + } + return entityMap; + } + +} diff --git a/ems-core/src/main/java/it/integry/ems_model/base/EquatableEntityInterface.java b/ems-core/src/main/java/it/integry/ems_model/base/EquatableEntityInterface.java index 60d0d860af..ace2627637 100644 --- a/ems-core/src/main/java/it/integry/ems_model/base/EquatableEntityInterface.java +++ b/ems-core/src/main/java/it/integry/ems_model/base/EquatableEntityInterface.java @@ -9,6 +9,4 @@ public interface EquatableEntityInterface extends EntityInterface { boolean equalsKey(T other); boolean equals(Object other); - - } diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/AtbForn.java b/ems-core/src/main/java/it/integry/ems_model/entity/AtbForn.java index caece43c81..9b37fcaa6f 100644 --- a/ems-core/src/main/java/it/integry/ems_model/entity/AtbForn.java +++ b/ems-core/src/main/java/it/integry/ems_model/entity/AtbForn.java @@ -449,6 +449,7 @@ public class AtbForn extends EntityBase implements EquatableEntityInterface { private final static Logger logger = LogManager.getLogger(); @@ -94,6 +97,10 @@ public class StbGestSetup extends EntityBase { this.keySection = keySection; } + public StbGestSetupKey getKey() { + return new StbGestSetupKey(gestName, section, keySection); + } + public String getGestName() { return gestName; } @@ -184,6 +191,10 @@ public class StbGestSetup extends EntityBase { return this; } + public boolean isFlagSetupUserDepo() { + return "S".equalsIgnoreCase(this.flagSetupDepo); + } + public String getFlagSetupDepo() { return flagSetupDepo; } @@ -193,6 +204,10 @@ public class StbGestSetup extends EntityBase { return this; } + public boolean isFlagSetupUserWeb() { + return "S".equalsIgnoreCase(this.flagSetupUserWeb); + } + public String getFlagSetupUserWeb() { return flagSetupUserWeb; } @@ -272,4 +287,31 @@ public class StbGestSetup extends EntityBase { } + @Override + public boolean equalsKey(StbGestSetup that) { + if (this == that) + return true; + + if (hashCodeKey() != that.hashCodeKey()) + return false; + + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()); + } + + @Override + public int hashCodeKey() { + return Objects.hash(getGestName(), getSection(), getKeySection()); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof StbGestSetup)) return false; + StbGestSetup that = (StbGestSetup) o; + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()) && Objects.equals(getValue(), that.getValue()) && Objects.equals(getDescription(), that.getDescription()) && Objects.equals(getFlagSync(), that.getFlagSync()) && Objects.equals(getQueryDefault(), that.getQueryDefault()) && Objects.equals(getFlagUserView(), that.getFlagUserView()) && Objects.equals(getDataModifica(), that.getDataModifica()) && Objects.equals(getModificatoDa(), that.getModificatoDa()) && Objects.equals(getFlagSetupDepo(), that.getFlagSetupDepo()) && Objects.equals(getFlagMultiValue(), that.getFlagMultiValue()) && Objects.equals(isFlagSetupUserWeb(), that.isFlagSetupUserWeb()) && Objects.equals(getCodQuery(), that.getCodQuery()) && Objects.equals(getFlagTipoJson(), that.getFlagTipoJson()) && Objects.equals(getFlagTipoColore(), that.getFlagTipoColore()) && Objects.equals(getTipoSetup(), that.getTipoSetup()); + } + + @Override + public int hashCode() { + return Objects.hash(getGestName(), getSection(), getKeySection(), getValue(), getDescription(), getFlagSync(), getQueryDefault(), getFlagUserView(), getDataModifica(), getModificatoDa(), getFlagSetupDepo(), getFlagMultiValue(), isFlagSetupUserWeb(), getCodQuery(), getFlagTipoJson(), getFlagTipoColore(), getTipoSetup()); + } } diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/StbGestSetupDepo.java b/ems-core/src/main/java/it/integry/ems_model/entity/StbGestSetupDepo.java index a82661c5ea..fbb3944b74 100644 --- a/ems-core/src/main/java/it/integry/ems_model/entity/StbGestSetupDepo.java +++ b/ems-core/src/main/java/it/integry/ems_model/entity/StbGestSetupDepo.java @@ -6,15 +6,18 @@ import it.integry.ems_model.annotation.PK; import it.integry.ems_model.annotation.SqlField; import it.integry.ems_model.annotation.Table; import it.integry.ems_model.base.EntityBase; -import org.kie.api.definition.type.PropertyReactive; +import it.integry.ems_model.base.EquatableEntityInterface; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.kie.api.definition.type.PropertyReactive; + +import java.util.Objects; @Master @PropertyReactive @Table(StbGestSetupDepo.ENTITY) @JsonTypeName(StbGestSetupDepo.ENTITY) -public class StbGestSetupDepo extends EntityBase { +public class StbGestSetupDepo extends EntityBase implements EquatableEntityInterface { private final static Logger logger = LogManager.getLogger(); @@ -95,4 +98,34 @@ public class StbGestSetupDepo extends EntityBase { public void setFlagSync(String flagSync) { this.flagSync = flagSync; } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof StbGestSetupDepo)) return false; + StbGestSetupDepo that = (StbGestSetupDepo) o; + return Objects.equals(getCodMdep(), that.getCodMdep()) && Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getKeySection(), that.getKeySection()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getValue(), that.getValue()) && Objects.equals(getFlagSync(), that.getFlagSync()); + } + + @Override + public int hashCodeKey() { + return Objects.hash(getCodMdep(), getGestName(), getKeySection(), getSection()); + } + + @Override + public int hashCode() { + return Objects.hash(getCodMdep(), getGestName(), getKeySection(), getSection(), getValue(), getFlagSync()); + } + + + @Override + public boolean equalsKey(StbGestSetupDepo that) { + if (this == that) + return true; + + if (hashCodeKey() != that.hashCodeKey()) + return false; + + return Objects.equals(getCodMdep(), that.getCodMdep()) && Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()); + } } diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/WtbGestSetupUser.java b/ems-core/src/main/java/it/integry/ems_model/entity/WtbGestSetupUser.java index 2f8519f3c5..55dad285e5 100644 --- a/ems-core/src/main/java/it/integry/ems_model/entity/WtbGestSetupUser.java +++ b/ems-core/src/main/java/it/integry/ems_model/entity/WtbGestSetupUser.java @@ -6,15 +6,18 @@ import it.integry.ems_model.annotation.PK; import it.integry.ems_model.annotation.SqlField; import it.integry.ems_model.annotation.Table; import it.integry.ems_model.base.EntityBase; -import org.kie.api.definition.type.PropertyReactive; +import it.integry.ems_model.base.EquatableEntityInterface; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.kie.api.definition.type.PropertyReactive; + +import java.util.Objects; @Master @PropertyReactive @Table(WtbGestSetupUser.ENTITY) @JsonTypeName(WtbGestSetupUser.ENTITY) -public class WtbGestSetupUser extends EntityBase { +public class WtbGestSetupUser extends EntityBase implements EquatableEntityInterface { private final static Logger logger = LogManager.getLogger(); @@ -84,4 +87,34 @@ public class WtbGestSetupUser extends EntityBase { public void setValue(String value) { this.value = value; } + + + @Override + public int hashCodeKey() { + return Objects.hash(getGestName(), getSection(), getKeySection(), getUserName()); + } + + + @Override + public boolean equalsKey(WtbGestSetupUser that) { + if (this == that) + return true; + + if (hashCodeKey() != that.hashCodeKey()) + return false; + + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()) && Objects.equals(getUserName(), that.getUserName()); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof WtbGestSetupUser)) return false; + WtbGestSetupUser that = (WtbGestSetupUser) o; + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getKeySection(), that.getKeySection()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getUserName(), that.getUserName()) && Objects.equals(getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getGestName(), getKeySection(), getSection(), getUserName(), getValue()); + } } diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/key/MtbAartKey.java b/ems-core/src/main/java/it/integry/ems_model/entity/key/MtbAartKey.java new file mode 100644 index 0000000000..18aef5fe2f --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems_model/entity/key/MtbAartKey.java @@ -0,0 +1,35 @@ +package it.integry.ems_model.entity.key; + +import it.integry.ems_model.annotation.SqlField; + +import java.util.Objects; + +public class MtbAartKey { + + @SqlField("cod_mart") + private String codMart; + + public MtbAartKey() { + } + + public MtbAartKey(String codMart) { + this.codMart = codMart; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof MtbAartKey)) return false; + MtbAartKey that = (MtbAartKey) o; + return Objects.equals(codMart, that.codMart); + } + + @Override + public int hashCode() { + return Objects.hashCode(codMart); + } + + + public String getCodMart() { + return codMart; + } +} diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupDepoKey.java b/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupDepoKey.java new file mode 100644 index 0000000000..1299132b30 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupDepoKey.java @@ -0,0 +1,65 @@ +package it.integry.ems_model.entity.key; + +import it.integry.ems_model.utility.UtilityHashMap; + +import java.util.HashMap; +import java.util.Objects; + +public class StbGestSetupDepoKey { + + private final String codMdep; + private final String gestName; + private final String section; + private final String keySection; + + public StbGestSetupDepoKey(String codMdep, String gestName, String section, String keySection) { + this.codMdep = codMdep; + this.gestName = gestName; + this.section = section; + this.keySection = keySection; + } + + + public String getCodMdep() { + return codMdep; + } + + public String getGestName() { + return gestName; + } + + public String getSection() { + return section; + } + + public String getKeySection() { + return keySection; + } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof StbGestSetupDepoKey)) return false; + StbGestSetupDepoKey that = (StbGestSetupDepoKey) o; + return Objects.equals(getCodMdep(), that.getCodMdep()) && Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()); + } + + @Override + public int hashCode() { + return Objects.hash(getCodMdep(), getGestName(), getSection(), getKeySection()); + } + + + public static StbGestSetupDepoKey fromHashMap(HashMap inputData) { + String codMdep = UtilityHashMap.getValueIfExists(inputData, "cod_mdep"); + String gestName = UtilityHashMap.getValueIfExists(inputData, "gest_name"); + String section = UtilityHashMap.getValueIfExists(inputData, "section"); + String keySection = UtilityHashMap.getValueIfExists(inputData, "key_section"); + + if (codMdep == null || gestName == null || section == null || keySection == null) { + return null; + } + + return new StbGestSetupDepoKey(codMdep, gestName, section, keySection); + } +} diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupKey.java b/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupKey.java new file mode 100644 index 0000000000..a8b3d2aabc --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems_model/entity/key/StbGestSetupKey.java @@ -0,0 +1,57 @@ +package it.integry.ems_model.entity.key; + +import it.integry.ems_model.utility.UtilityHashMap; + +import java.util.HashMap; +import java.util.Objects; + +public class StbGestSetupKey { + + private final String gestName; + private final String section; + private final String keySection; + + public StbGestSetupKey(String gestName, String section, String keySection) { + this.gestName = gestName; + this.section = section; + this.keySection = keySection; + } + + public String getGestName() { + return gestName; + } + + public String getSection() { + return section; + } + + public String getKeySection() { + return keySection; + } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof StbGestSetupKey)) return false; + StbGestSetupKey that = (StbGestSetupKey) o; + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()); + } + + @Override + public int hashCode() { + return Objects.hash(getGestName(), getSection(), getKeySection()); + } + + + public static StbGestSetupKey fromHashMap(HashMap inputData) { + String gestName = UtilityHashMap.getValueIfExists(inputData, "gest_name"); + String section = UtilityHashMap.getValueIfExists(inputData, "section"); + String keySection = UtilityHashMap.getValueIfExists(inputData, "key_section"); + + if (gestName == null || section == null || keySection == null) { + return null; + } + + return new StbGestSetupKey(gestName, section, keySection); + } +} diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/key/WtbGestSetupUserKey.java b/ems-core/src/main/java/it/integry/ems_model/entity/key/WtbGestSetupUserKey.java new file mode 100644 index 0000000000..64cb6339e6 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems_model/entity/key/WtbGestSetupUserKey.java @@ -0,0 +1,63 @@ +package it.integry.ems_model.entity.key; + +import it.integry.ems_model.utility.UtilityHashMap; + +import java.util.HashMap; +import java.util.Objects; + +public class WtbGestSetupUserKey { + + private final String gestName; + private final String section; + private final String keySection; + private final String username; + + public WtbGestSetupUserKey(String gestName, String section, String keySection, String username) { + this.gestName = gestName; + this.section = section; + this.keySection = keySection; + this.username = username; + } + + public String getGestName() { + return gestName; + } + + public String getSection() { + return section; + } + + public String getKeySection() { + return keySection; + } + + public String getUsername() { + return username; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof WtbGestSetupUserKey)) return false; + WtbGestSetupUserKey that = (WtbGestSetupUserKey) o; + return Objects.equals(getGestName(), that.getGestName()) && Objects.equals(getSection(), that.getSection()) && Objects.equals(getKeySection(), that.getKeySection()) && Objects.equals(getUsername(), that.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getGestName(), getSection(), getKeySection(), getUsername()); + } + + + public static WtbGestSetupUserKey fromHashMap(HashMap inputData) { + String gestName = UtilityHashMap.getValueIfExists(inputData, "gest_name"); + String section = UtilityHashMap.getValueIfExists(inputData, "section"); + String keySection = UtilityHashMap.getValueIfExists(inputData, "key_section"); + String username = UtilityHashMap.getValueIfExists(inputData, "username"); + + if (gestName == null || section == null || keySection == null || username == null) { + return null; + } + + return new WtbGestSetupUserKey(gestName, section, keySection, username); + } +} diff --git a/ems-core/src/main/java/it/integry/ems_model/service/SetupGest.java b/ems-core/src/main/java/it/integry/ems_model/service/SetupGest.java index 3d7a0c1eba..53df276b8c 100644 --- a/ems-core/src/main/java/it/integry/ems_model/service/SetupGest.java +++ b/ems-core/src/main/java/it/integry/ems_model/service/SetupGest.java @@ -4,9 +4,15 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import it.integry.common.var.CommonConstants; +import it.integry.ems._context.ApplicationContextProvider; +import it.integry.ems.dynamic_cache.EntityCacheComponent; +import it.integry.ems.migration._base.IntegryCustomerDB; import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; +import it.integry.ems_model.entity.StbGestSetup; +import it.integry.ems_model.entity.StbGestSetupDepo; import it.integry.ems_model.entity.StbGestSetupDet; +import it.integry.ems_model.entity.WtbGestSetupUser; import it.integry.ems_model.utility.Query; import it.integry.ems_model.utility.UtilityDB; import it.integry.ems_model.utility.UtilityString; @@ -15,33 +21,16 @@ import org.json.JSONObject; import org.springframework.stereotype.Service; import org.springframework.web.context.ContextLoader; +import javax.annotation.Nullable; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Service public class SetupGest { -// @Autowired -// private DynamicCacheService dynamicCacheService; -// -// @Autowired -// private SettingsModel settingsModel; -// -// @PostContextConstruct(priority = 30) -// public void init() { -// List dbNames = settingsModel.getAvailableConnections(true).stream() -// .map(AvailableConnectionsModel::getDbName) -// .distinct() -// .collect(Collectors.toList()); -// -// dynamicCacheService.addQuery(DynamicCacheService.Keys.STB_GEST_SETUP_KEY, 1, "SELECT * FROM " + StbGestSetup.ENTITY, StbGestSetup.class, dbNames); -// } public String getImportSetup(Connection conn, String type, String format, String key) throws Exception { return getSetup(conn, type, format, key, "IMPORT"); @@ -101,30 +90,70 @@ public class SetupGest { return !UtilityString.isNullOrEmpty(value) ? BigDecimal.valueOf(Double.parseDouble(value)) : defaultValue; } - private String getSetup(Connection connection, String gestName, String section, String keySection, String precode) throws SQLException { - if (!precode.isEmpty()) { - gestName = precode + "_" + gestName; + + private String getSetup(Connection connection, String gestName, String section, String keySection, String precode) { + final List result = getGestSetupList(connection, + Collections.singletonList(new StbGestSetup(gestName, section, keySection)), null, null, precode); + + if (result == null || result.isEmpty() || result.get(0).getValue() == null) + return ""; + + return result.get(0).getValue(); + } + + public List getGestSetupList(Connection connection, + List stbGestSetups, + @Nullable String username, + @Nullable String codMdep, + @Nullable String precode) { + final IntegryCustomerDB customerDB = IntegryCustomerDB.parse(connection.getDbName()); + final EntityCacheComponent entityCacheComponent = ApplicationContextProvider.getApplicationContext().getBean(EntityCacheComponent.class); + + List stbGestSetupDb = entityCacheComponent.getCachedEntitiesList(customerDB, StbGestSetup.ENTITY, + x -> stbGestSetups.stream().anyMatch(y -> { + String gestName = y.getGestName(); + if (!UtilityString.isNullOrEmpty(precode)) { + gestName = precode + "_" + gestName; + } + + return x.getGestName().equals(gestName) && + x.getSection().equals(y.getSection()) && + x.getKeySection().equals(y.getKeySection()); + } + )); + + + for (StbGestSetup stbGestSetup : stbGestSetupDb) { + StbGestSetupDepo depoSetup = entityCacheComponent.getCachedEntitiesList(customerDB, StbGestSetupDepo.ENTITY, + x -> stbGestSetup.getGestName().equals(x.getGestName()) && + stbGestSetup.getSection().equals(x.getSection()) && + stbGestSetup.getKeySection().equals(x.getKeySection()) && + (x.getCodMdep().equals(codMdep)) + ).stream() + .findFirst() + .orElse(null); + + + WtbGestSetupUser userSetup = entityCacheComponent.getCachedEntitiesList(customerDB, WtbGestSetupUser.ENTITY, + x -> stbGestSetup.getGestName().equals(x.getGestName()) && + stbGestSetup.getSection().equals(x.getSection()) && + stbGestSetup.getKeySection().equals(x.getKeySection()) && + x.getUserName().equals(username) + ).stream() + .findFirst() + .orElse(null); + + + if (stbGestSetup.isFlagSetupUserDepo()) { + if (depoSetup != null) + stbGestSetup.setValue(UtilityString.isNull(depoSetup.getValue(), stbGestSetup.getValue())); + } else if (stbGestSetup.isFlagSetupUserWeb()) { + if (userSetup != null) + stbGestSetup.setValue(UtilityString.isNull(userSetup.getValue(), stbGestSetup.getValue())); + } } -// String finalGestName = gestName; -// -// final List stbGestSetups = dynamicCacheService.getObject(DynamicCacheService.Keys.STB_GEST_SETUP_KEY, connection.getCatalog()); -// final StbGestSetup stbGestSetup = stbGestSetups.parallelStream().filter(x -> x.getGestName().equalsIgnoreCase(finalGestName) && -// x.getSection().equalsIgnoreCase(section) && -// x.getKeySection().equalsIgnoreCase(keySection)) -// .findFirst() -// .orElse(null); -// -// if(stbGestSetup == null || stbGestSetup.getValue() == null) -// return ""; -// -// return stbGestSetup.getValue(); - String query = "SELECT ISNULL(value, '') AS value FROM stb_gest_setup" - + " WHERE gest_name = " + UtilityDB.valueToString(gestName) - + " AND section = " + UtilityDB.valueToString(section) - + " AND key_section = " + UtilityDB.valueToString(keySection); - - return UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(connection, query); + return stbGestSetupDb; } diff --git a/ems-engine/src/main/java/it/integry/ems/system/controller/SystemController.java b/ems-engine/src/main/java/it/integry/ems/system/controller/SystemController.java index 45c2cce988..1761aa1668 100644 --- a/ems-engine/src/main/java/it/integry/ems/system/controller/SystemController.java +++ b/ems-engine/src/main/java/it/integry/ems/system/controller/SystemController.java @@ -347,7 +347,9 @@ public class SystemController { @RequestParam(required = false) String codMdep, @RequestBody List stbGestSetupList) throws Exception { - return ServiceRestResponse.createPositiveResponse(systemService.getGestSetupList(stbGestSetupList, requestDataDTO.getUsername(), codMdep)); + return ServiceRestResponse.createPositiveResponse( + setupGest.getGestSetupList(multiDBTransactionManager.getPrimaryConnection(), + stbGestSetupList, requestDataDTO.getUsername(), codMdep, null)); } @RequestMapping(value = "updateGestSetup", method = RequestMethod.POST) diff --git a/ems-engine/src/main/java/it/integry/ems/system/service/SystemService.java b/ems-engine/src/main/java/it/integry/ems/system/service/SystemService.java index d49e94a879..1ede237ae8 100644 --- a/ems-engine/src/main/java/it/integry/ems/system/service/SystemService.java +++ b/ems-engine/src/main/java/it/integry/ems/system/service/SystemService.java @@ -8,6 +8,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import it.integry.ems._context.ApplicationContextProvider; +import it.integry.ems.dynamic_cache.EntityCacheComponent; import it.integry.ems.javabeans.RequestDataDTO; import it.integry.ems.license.LicenseStatusDTO; import it.integry.ems.media.MediaImageService; @@ -126,6 +127,9 @@ public class SystemService { @Autowired private SetupGest setupGest; + @Autowired + private EntityCacheComponent entityCacheComponent; + public ServiceRestResponse getActivityTree(String activityParent, String codJcom, String activityTypeId) throws Exception { String sql = "SELECT parent_activity_id, activity_id, activity_description, flag_ins_attivita " + " FROM f_getTreeViewActivity(" + UtilityDB.valueToString(activityParent) + ", " + @@ -186,7 +190,7 @@ public class SystemService { HashMap resultMap = null; - try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(connectionModel)){ + try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(connectionModel)) { String sql = "SELECT stb_user.user_name," + " stb_user.key_group," + @@ -357,7 +361,7 @@ public class SystemService { if (foundUser == null) { logger.error(String.format("Credenziali non valide utente: %s ( %s) ", - UtilityString.isNull(username,md5User), UtilityString.isNull(profileDB,multiDBTransactionManager.getPrimaryConnection().getCatalog()) + " )")); + UtilityString.isNull(username, md5User), UtilityString.isNull(profileDB, multiDBTransactionManager.getPrimaryConnection().getCatalog()) + " )")); throw new Exception("Credenziali non valide"); } else if (!foundUser.isAttivo()) { throw new Exception("Utente non attivo"); @@ -574,50 +578,8 @@ public class SystemService { } } - - public List getGestSetupList(List stbGestSetups, String username, String codMdep) throws Exception { -/* for (StbGestSetup stbGestSetup : stbGestSetups) { - stbGestSetup.setOperation(OperationType.SELECT_OBJECT); - entityProcessor.processEntity(stbGestSetup, multiDBTransactionManager); - }*/ - - - String baseQuery = "select stb_gest_setup.gest_name,\n" + - " stb_gest_setup.section,\n" + - " stb_gest_setup.key_section,\n" + - " case when flag_setup_depo = 'S' then ISNULL(sgsd.value,stb_gest_setup.value)\n" + - " else\n" + - " case when flag_setup_user_web = 'S' THEN ISNULL(wgsu.value,stb_gest_setup.value) else stb_gest_setup.value end\n" + - " end as value,\n" + - " description,\n" + - " stb_gest_setup.flag_sync,\n" + - " query_default,\n" + - " flag_user_view,\n" + - " data_modifica,\n" + - " modificato_da,\n" + - " flag_setup_depo,\n" + - " flag_setup_user_web,\n" + - " flag_tipo_json\n" + - "from stb_gest_setup\n" + - " left outer join stb_gest_setup_depo sgsd on stb_gest_setup.gest_name = sgsd.gest_name and stb_gest_setup.section = sgsd.section and stb_gest_setup.key_section = sgsd.key_section and cod_mdep = ISNULL(" + UtilityDB.valueToString(codMdep) + ",'')\n" + - " left outer join wtb_gest_setup_user wgsu on stb_gest_setup.gest_name = wgsu.gest_name and stb_gest_setup.section = wgsu.section and stb_gest_setup.key_section = wgsu.key_section and user_name = ISNULL(" + UtilityDB.valueToString(username) + ",'')\n" + - " where "; - - List> whereCondMap = Stream.of(stbGestSetups).map(setup -> { - HashMap data = new HashMap<>(); - data.put("stb_gest_setup.gest_name", setup.getGestName()); - data.put("stb_gest_setup.section", setup.getSection()); - data.put("stb_gest_setup.key_section", setup.getKeySection()); - return data; - }).toList(); - - baseQuery = baseQuery.concat(UtilityQuery.concatFieldListInWhereCond(whereCondMap)); - - return UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), baseQuery, StbGestSetup.class); - } - public EntityBase updateGestSetup(StbGestSetup stbGestSetup, String username) throws Exception { - if (username != null){ + if (username != null) { WtbGestSetupUser wtbGestSetupUser = new WtbGestSetupUser(); wtbGestSetupUser.setGestName(stbGestSetup.getGestName()); wtbGestSetupUser.setKeySection(stbGestSetup.getKeySection());