From 4e97fa1d56d15e7cccb66abb206fa41924ac9232 Mon Sep 17 00:00:00 2001 From: MarcoE Date: Thu, 24 Apr 2025 11:02:53 +0200 Subject: [PATCH] Ripristinati lock e unlock --- .../it/integry/common/var/EmsDBConst.java | 24 +-- .../service/UnitaTerritorialiService.java | 7 +- .../BasicConnectionPool.java | 33 ++- .../MultiDBTransactionManager.java | 76 +++---- .../ems/user/service/UserCacheService.java | 194 ++++++++++-------- 5 files changed, 173 insertions(+), 161 deletions(-) diff --git a/ems-core/src/main/java/it/integry/common/var/EmsDBConst.java b/ems-core/src/main/java/it/integry/common/var/EmsDBConst.java index e276a1d516..280952ffe9 100644 --- a/ems-core/src/main/java/it/integry/common/var/EmsDBConst.java +++ b/ems-core/src/main/java/it/integry/common/var/EmsDBConst.java @@ -12,7 +12,7 @@ import java.util.concurrent.locks.ReentrantLock; @Service public class EmsDBConst { -// private final ReentrantLock datiAziendaLock = new ReentrantLock(); + private final ReentrantLock datiAziendaLock = new ReentrantLock(); private HashMap datiAziendaBindingTable = new HashMap() {{ }}; @@ -28,24 +28,24 @@ public class EmsDBConst { public Const getConsts(String dbName) { String aziendaUp = dbName.toUpperCase(); -// datiAziendaLock.lock(); - if (!datiAziendaBindingTable.containsKey(aziendaUp)) { - datiAziendaBindingTable.put(aziendaUp, new Const()); + datiAziendaLock.lock(); + try { + if (!datiAziendaBindingTable.containsKey(aziendaUp)) { + datiAziendaBindingTable.put(aziendaUp, new Const()); + } + + return datiAziendaBindingTable.get(aziendaUp); + } finally { + datiAziendaLock.unlock(); } - - final Const aConst = datiAziendaBindingTable.get(aziendaUp); -// datiAziendaLock.unlock(); - - return aConst; } public void destroyAll() { -// datiAziendaLock.lock(); + datiAziendaLock.lock(); datiAziendaBindingTable = new HashMap<>(); -// datiAziendaLock.unlock(); + datiAziendaLock.unlock(); } - public static class Const { private String applicationDbName; diff --git a/ems-core/src/main/java/it/integry/ems/service/comuni/service/UnitaTerritorialiService.java b/ems-core/src/main/java/it/integry/ems/service/comuni/service/UnitaTerritorialiService.java index 9a17211d04..0580679ddb 100644 --- a/ems-core/src/main/java/it/integry/ems/service/comuni/service/UnitaTerritorialiService.java +++ b/ems-core/src/main/java/it/integry/ems/service/comuni/service/UnitaTerritorialiService.java @@ -19,6 +19,7 @@ import java.util.Comparator; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @Service @@ -32,7 +33,7 @@ public class UnitaTerritorialiService { // Data di ultima modifica private Instant lastModifiedSource = Instant.MIN; // Locker per la sincronizzazione -// private final ReentrantLock updateLocker = new ReentrantLock(); + private final ReentrantLock updateLocker = new ReentrantLock(); // Dati transcodificati private List dataSource = new ArrayList<>(); private List regioni = new ArrayList<>(); @@ -77,13 +78,13 @@ public class UnitaTerritorialiService { return; } -// updateLocker.lock(); + updateLocker.lock(); try (InputStream streamIstat = connectionIstat.getInputStream()) { if (updateServiceData(streamIstat)) { lastModifiedSource = Instant.now(); // Recupera la data di modifica dal server } } finally { -// updateLocker.unlock(); + updateLocker.unlock(); } } diff --git a/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/BasicConnectionPool.java b/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/BasicConnectionPool.java index 205d668a99..aa22ca24ad 100644 --- a/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/BasicConnectionPool.java +++ b/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/BasicConnectionPool.java @@ -15,6 +15,7 @@ import java.sql.SQLException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; @Component public class BasicConnectionPool { @@ -29,21 +30,21 @@ public class BasicConnectionPool { private final ConcurrentHashMap extraConnectionCounters = new ConcurrentHashMap<>(); private final ConcurrentHashMap> activeConnectionNames = new ConcurrentHashMap<>(); -// private final ReentrantLock poolLock = new ReentrantLock(); + private final ReentrantLock poolLock = new ReentrantLock(); public void init() throws Exception { -// poolLock.lock(); + poolLock.lock(); try { closeAllConnections(); int poolSize = calculatePoolSize(); initializeConnections(poolSize); } finally { -// poolLock.unlock(); + poolLock.unlock(); } } private void closeAllConnections() { -// poolLock.lock(); + poolLock.lock(); try { // Chiude tutte le connessioni esistenti connectionPool.values().forEach(connections -> @@ -57,7 +58,7 @@ public class BasicConnectionPool { extraConnectionCounters.clear(); activeConnectionNames.clear(); } finally { -// poolLock.unlock(); + poolLock.unlock(); } } @@ -127,21 +128,16 @@ public class BasicConnectionPool { return null; } -// poolLock.lock(); + poolLock.lock(); try { - if (!connectionPool.containsKey(dbName)|| connectionPool.get(dbName).isEmpty()) { + if (!connectionPool.containsKey(dbName) || connectionPool.get(dbName).isEmpty()) { return createExtraConnection(profileName); } List pool = connectionPool.get(dbName); List used = usedConnections.get(dbName); - DataSource ds; - try { - ds = pool.remove(0); - } catch (IndexOutOfBoundsException ex) { - return createExtraConnection(profileName); - } + DataSource ds = pool.remove(0); if (ds.isClosed()) { String oldName = ds.getApplicationName(); @@ -157,7 +153,7 @@ public class BasicConnectionPool { logger.trace("Assigned connection: {} for database: {}", ds.getApplicationName(), dbName); return ds; } finally { -// poolLock.unlock(); + poolLock.unlock(); } } @@ -167,7 +163,7 @@ public class BasicConnectionPool { return false; } -// poolLock.lock(); + poolLock.lock(); try { String currentCatalog = ds.getConnection().getCatalog(); AvailableConnectionsModel model = findConnectionModel(profileName); @@ -183,13 +179,13 @@ public class BasicConnectionPool { return handleConnectionRelease(ds); } finally { -// poolLock.unlock(); + poolLock.unlock(); } } private DataSource createExtraConnection(String profileName) throws Exception { String dbName = settingsModel.getDbNameFromProfileDb(profileName); -// poolLock.lock(); + poolLock.lock(); try { // Calcola il numero totale di connessioni esistenti int baseCount = connectionPool.get(dbName).size() + usedConnections.get(dbName).size(); @@ -201,7 +197,6 @@ public class BasicConnectionPool { // Verifica se la connessione esiste giĆ  if (activeConnectionNames.get(dbName).contains(connectionName)) { logger.warn("Extra connection name collision detected: {}", connectionName); -// extraConnectionCounters.get(dbName).decrementAndGet(); return createExtraConnection(profileName); // Riprova con un nuovo nome } @@ -212,7 +207,7 @@ public class BasicConnectionPool { logger.trace("Created extra connection: {} for database: {}", connectionName, dbName); return ds; } finally { -// poolLock.unlock(); + poolLock.unlock(); } } diff --git a/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/MultiDBTransactionManager.java b/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/MultiDBTransactionManager.java index 5c75160b9f..cb95066504 100644 --- a/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/MultiDBTransactionManager.java +++ b/ems-core/src/main/java/it/integry/ems/sync/MultiDBTransaction/MultiDBTransactionManager.java @@ -23,6 +23,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @Service @@ -35,7 +36,7 @@ public class MultiDBTransactionManager implements AutoCloseable { private List dbDatasources = new ArrayList<>(); private DataSource dataSource; -// private final ReentrantLock datasourcesLock = new ReentrantLock(); + private final ReentrantLock datasourcesLock = new ReentrantLock(); @Autowired private BasicConnectionPool connectionPool; @@ -89,7 +90,6 @@ public class MultiDBTransactionManager implements AutoCloseable { this.setPrimaryDs(profileDb); } catch (Exception ex) { logger.error("Errore durante la connessione al DB.", ex); -// throw ex; } } @@ -135,20 +135,22 @@ public class MultiDBTransactionManager implements AutoCloseable { } } -// datasourcesLock.lock(); - dbDatasources.add(new AdvancedDataSource(profileName, dataSource, isDistributore, isInternalDb)); + datasourcesLock.lock(); + try { + dbDatasources.add(new AdvancedDataSource(profileName, dataSource, isDistributore, isInternalDb)); - if (isDistributore) { - dbDatasources = dbDatasources.stream() - .sorted((o1, o2) -> { - if (o1.getIsDistributore() && !o2.getIsDistributore()) return -1; - else if (!o1.getIsDistributore() && o2.getIsDistributore()) return 1; - else return 0; - }) - .collect(Collectors.toList()); + if (isDistributore) { + dbDatasources = dbDatasources.stream() + .sorted((o1, o2) -> { + if (o1.getIsDistributore() && !o2.getIsDistributore()) return -1; + else if (!o1.getIsDistributore() && o2.getIsDistributore()) return 1; + else return 0; + }) + .collect(Collectors.toList()); + } + } finally { + datasourcesLock.unlock(); } - -// datasourcesLock.unlock(); } } @@ -243,34 +245,36 @@ public class MultiDBTransactionManager implements AutoCloseable { } public void closeAll() throws Exception { -// datasourcesLock.lock(); - if (dbDatasources != null && !dbDatasources.isEmpty()) { - for (AdvancedDataSource advancedDataSource : dbDatasources) { + datasourcesLock.lock(); + try { + if (dbDatasources != null && !dbDatasources.isEmpty()) { + for (AdvancedDataSource advancedDataSource : dbDatasources) { - if (requestData != null && requestData.getRequestURI() != null) { - String methodName = " [" + requestData.getRequestURI() + "]"; - if (shouldPrintLog(requestData.getRequestURI())) - logger.debug("Closing automatically: " + advancedDataSource.getDataSource().getProfile() + " (#" + advancedDataSource.getDataSource().getSessionID() + ")" + methodName); - } else if (enableLog) { - logger.debug("Closing manually: " + advancedDataSource.getDataSource().getProfile() + " (#" + advancedDataSource.getDataSource().getSessionID() + ")"); - } - advancedDataSource.commit(); + if (requestData != null && requestData.getRequestURI() != null) { + String methodName = " [" + requestData.getRequestURI() + "]"; + if (shouldPrintLog(requestData.getRequestURI())) + logger.debug("Closing automatically: " + advancedDataSource.getDataSource().getProfile() + " (#" + advancedDataSource.getDataSource().getSessionID() + ")" + methodName); + } else if (enableLog) { + logger.debug("Closing manually: " + advancedDataSource.getDataSource().getProfile() + " (#" + advancedDataSource.getDataSource().getSessionID() + ")"); + } + advancedDataSource.commit(); + + try { + connectionPool.releaseConnection(advancedDataSource.getProfileName(), advancedDataSource.getDataSource()); + } catch (UnexpectedConnectionSwitchException e) { + logger.error("UnexpectedConnectionSwitchException: " + advancedDataSource.getProfileName(), e); + } + + if (dbPrimary != null && advancedDataSource.getDataSource() == dbPrimary.getDataSource()) + dbPrimary = null; - try { - connectionPool.releaseConnection(advancedDataSource.getProfileName(), advancedDataSource.getDataSource()); - } catch (UnexpectedConnectionSwitchException e) { - logger.error("UnexpectedConnectionSwitchException: " + advancedDataSource.getProfileName(), e); } - if(dbPrimary != null && advancedDataSource.getDataSource() == dbPrimary.getDataSource()) - dbPrimary = null; - + dbDatasources.clear(); } - - dbDatasources.clear(); + } finally { + datasourcesLock.unlock(); } - -// datasourcesLock.unlock(); } diff --git a/ems-core/src/main/java/it/integry/ems/user/service/UserCacheService.java b/ems-core/src/main/java/it/integry/ems/user/service/UserCacheService.java index 44717680c1..ca38b7a38e 100644 --- a/ems-core/src/main/java/it/integry/ems/user/service/UserCacheService.java +++ b/ems-core/src/main/java/it/integry/ems/user/service/UserCacheService.java @@ -38,13 +38,13 @@ public class UserCacheService { private final HashMap> cachedUsers = new HashMap<>(); - //private final ReentrantLock cacheLock = new ReentrantLock(); + private final ReentrantLock cacheLock = new ReentrantLock(); boolean canStart = false; @PostContextConstruct(priority = 10) private void init() { - if(UtilityDebug.isDebugExecution()) internalCacheUpdate(true); + if (UtilityDebug.isDebugExecution()) internalCacheUpdate(true); canStart = !UtilityDebug.isDebugExecution(); } @@ -54,7 +54,7 @@ public class UserCacheService { } private void internalCacheUpdate(boolean forceStart) { - if(!forceStart && !canStart) return; + if (!forceStart && !canStart) return; List availableConnectionsModels = settingsModel.getAvailableConnectionsWithoutDuplicatedProfiles(true); @@ -103,127 +103,139 @@ public class UserCacheService { } public @Nullable UserDTO retrieveUser(String dbName, String md5User) { - //cacheLock.lock(); - List users = cachedUsers.getOrDefault(dbName, null); + cacheLock.lock(); + try { + List users = cachedUsers.getOrDefault(dbName, null); - if (users == null || users.isEmpty()) - return null; + if (users == null || users.isEmpty()) + return null; - if (md5User == null || md5User.isEmpty()) - return null; + if (md5User == null || md5User.isEmpty()) + return null; - final Optional foundUser = users.stream() - .filter(x -> { - String md5Hash = UtilityHash.generateMd5(String.format("%s%s", x.getUsername().toLowerCase(), x.getPassword().toLowerCase())); - return md5Hash.contentEquals(md5User); - }) - .findFirst(); + final Optional foundUser = users.stream() + .filter(x -> { + String md5Hash = UtilityHash.generateMd5(String.format("%s%s", x.getUsername().toLowerCase(), x.getPassword().toLowerCase())); + return md5Hash.contentEquals(md5User); + }) + .findFirst(); - //cacheLock.unlock(); - return foundUser.orElse(null); + return foundUser.orElse(null); + } finally { + cacheLock.unlock(); + } } public @Nullable UserDTO retrieveUser(String dbName, String username, String password, IntegryApplicationEnum application) { - //cacheLock.lock(); - List users = cachedUsers.getOrDefault(dbName, null); + cacheLock.lock(); + try { + List users = cachedUsers.getOrDefault(dbName, null); - if (users == null || users.isEmpty()) - return null; + if (users == null || users.isEmpty()) + return null; - if (password == null || password.isEmpty()) - return null; + if (password == null || password.isEmpty()) + return null; - String finalPasswordHex = UtilityHash.generateHash(password.toUpperCase()); - final Optional foundUser = users.stream() - .filter(x -> x.getUsername().equalsIgnoreCase(username) && - x.isAttivo() && - x.getPasswordHash().contentEquals(finalPasswordHex) && - (application == null || - (application == IntegryApplicationEnum.PVM && x.isWeb()) || - (application == IntegryApplicationEnum.CONSEGNA && x.isWeb()) || - (application == IntegryApplicationEnum.WMS && x.isWeb()) || - (application == IntegryApplicationEnum.GESTIONALE_BASE && x.isInternal()))) - .findFirst(); + String finalPasswordHex = UtilityHash.generateHash(password.toUpperCase()); + final Optional foundUser = users.stream() + .filter(x -> x.getUsername().equalsIgnoreCase(username) && + x.isAttivo() && + x.getPasswordHash().contentEquals(finalPasswordHex) && + (application == null || + (application == IntegryApplicationEnum.PVM && x.isWeb()) || + (application == IntegryApplicationEnum.CONSEGNA && x.isWeb()) || + (application == IntegryApplicationEnum.WMS && x.isWeb()) || + (application == IntegryApplicationEnum.GESTIONALE_BASE && x.isInternal()))) + .findFirst(); - //cacheLock.unlock(); - return foundUser.orElse(null); + return foundUser.orElse(null); + } finally { + cacheLock.unlock(); + } } public @Nullable UserDTO retrieveUserData(String profileDb, String username, IntegryApplicationEnum application) { - String dbName = settingsModel.getDbNameFromProfileDb(profileDb); + cacheLock.lock(); + try { + String dbName = settingsModel.getDbNameFromProfileDb(profileDb); - //cacheLock.lock(); - List users = cachedUsers.getOrDefault(dbName, null); + List users = cachedUsers.getOrDefault(dbName, null); - if (users == null || users.isEmpty()) - return null; + if (users == null || users.isEmpty()) + return null; - final Optional foundUser = users.stream() - .filter(x -> x.getUsername().equalsIgnoreCase(username) && - (application == null || - (application == IntegryApplicationEnum.PVM && x.isWeb()) || - (application == IntegryApplicationEnum.CONSEGNA && x.isWeb()) || - (application == IntegryApplicationEnum.WMS && x.isWeb()) || - (application == IntegryApplicationEnum.GESTIONALE_BASE && x.isInternal()))) - .findFirst(); - //cacheLock.unlock(); + final Optional foundUser = users.stream() + .filter(x -> x.getUsername().equalsIgnoreCase(username) && + (application == null || + (application == IntegryApplicationEnum.PVM && x.isWeb()) || + (application == IntegryApplicationEnum.CONSEGNA && x.isWeb()) || + (application == IntegryApplicationEnum.WMS && x.isWeb()) || + (application == IntegryApplicationEnum.GESTIONALE_BASE && x.isInternal()))) + .findFirst(); - return foundUser.orElse(null); + return foundUser.orElse(null); + } finally { + cacheLock.unlock(); + } } public void discoverAllUsers(MultiDBTransactionManager multiDBTransactionManager) throws Exception { - //cacheLock.lock(); - List> calls = new ArrayList<>(); + cacheLock.lock(); + try { + List> calls = new ArrayList<>(); - for (final AdvancedDataSource advancedDataSource : multiDBTransactionManager.getActiveConnections()) { - calls.add(() -> { - try { - Connection conn = advancedDataSource.getConnection(); + for (final AdvancedDataSource advancedDataSource : multiDBTransactionManager.getActiveConnections()) { + calls.add(() -> { + try { + Connection conn = advancedDataSource.getConnection(); - String sql = "SELECT su.user_name,\n" + - " dbo.sys_dcd_pss(su.password) AS password, \n" + - " CONVERT(varchar(max), HASHBYTES('SHA2_512', UPPER(dbo.sys_dcd_pss(su.password))),2) AS password_hash,\n" + - " su.key_group,\n" + - " su.full_name,\n" + - " su.e_mail,\n" + - " su.last_access_datetime,\n" + - " su.password_endtime,\n" + - " CAST(IIF(su.destruction_datetime IS NOT NULL AND\n" + - " DATEDIFF(DAY, su.destruction_datetime, GETDATE()) > 0 AND su.flag_password_expiring = 'S', 1,\n" + - " 0) AS BIT) AS is_password_expired,\n" + - " IIF(su.key_group = '3' AND su.user_code IS NULL, wc.cod_anag, su.user_code) AS user_code,\n" + - " wd.cod_mdep,\n" + - " CAST(IIF(ISNULL(su.flag_attivo, 'N') = 'S', 1, 0) AS BIT) AS is_attivo,\n" + - " CAST(IIF(su.flag_intra_user = 'S' OR su.flag_dba = 'S', 1, 0) AS BIT) AS is_internal,\n" + - " CAST(IIF(su.flag_intra_user = 'S' OR su.flag_extra_user = 'S', 1, 0) AS BIT) AS is_web\n" + - "FROM " + StbUser.ENTITY + " su " + - " LEFT OUTER JOIN wtb_clie wc ON su.user_name = wc.user_name\n" + - " LEFT OUTER JOIN wtb_depo wd ON su.user_name = wd.user_name\n" + - " LEFT OUTER JOIN mtb_depo md ON wd.cod_mdep = md.cod_mdep\n" + - "WHERE dbo.sys_dcd_pss(su.password) IS NOT NULL"; + String sql = "SELECT su.user_name,\n" + + " dbo.sys_dcd_pss(su.password) AS password, \n" + + " CONVERT(varchar(max), HASHBYTES('SHA2_512', UPPER(dbo.sys_dcd_pss(su.password))),2) AS password_hash,\n" + + " su.key_group,\n" + + " su.full_name,\n" + + " su.e_mail,\n" + + " su.last_access_datetime,\n" + + " su.password_endtime,\n" + + " CAST(IIF(su.destruction_datetime IS NOT NULL AND\n" + + " DATEDIFF(DAY, su.destruction_datetime, GETDATE()) > 0 AND su.flag_password_expiring = 'S', 1,\n" + + " 0) AS BIT) AS is_password_expired,\n" + + " IIF(su.key_group = '3' AND su.user_code IS NULL, wc.cod_anag, su.user_code) AS user_code,\n" + + " wd.cod_mdep,\n" + + " CAST(IIF(ISNULL(su.flag_attivo, 'N') = 'S', 1, 0) AS BIT) AS is_attivo,\n" + + " CAST(IIF(su.flag_intra_user = 'S' OR su.flag_dba = 'S', 1, 0) AS BIT) AS is_internal,\n" + + " CAST(IIF(su.flag_intra_user = 'S' OR su.flag_extra_user = 'S', 1, 0) AS BIT) AS is_web\n" + + "FROM " + StbUser.ENTITY + " su " + + " LEFT OUTER JOIN wtb_clie wc ON su.user_name = wc.user_name\n" + + " LEFT OUTER JOIN wtb_depo wd ON su.user_name = wd.user_name\n" + + " LEFT OUTER JOIN mtb_depo md ON wd.cod_mdep = md.cod_mdep\n" + + "WHERE dbo.sys_dcd_pss(su.password) IS NOT NULL"; - final List userDTOS = UtilityDB.executeSimpleQueryDTO(conn, sql, UserDTO.class); + final List userDTOS = UtilityDB.executeSimpleQueryDTO(conn, sql, UserDTO.class); - if (userDTOS != null) - userDTOS.forEach(x -> cache(advancedDataSource.getDataSource().getDbName(), x)); - } catch (Exception ex) { - logger.error(String.format("Errore durante la retrieve degli utenti su \"%s\". %s", advancedDataSource.getProfileName(), ex.getMessage()), ex); - } + if (userDTOS != null) + userDTOS.forEach(x -> cache(advancedDataSource.getDataSource().getDbName(), x)); + } catch (Exception ex) { + logger.error(String.format("Errore durante la retrieve degli utenti su \"%s\". %s", advancedDataSource.getProfileName(), ex.getMessage()), ex); + } - return null; - }); + return null; + }); + } + + taskExecutorService.executeTasks(calls); + } finally { + cacheLock.unlock(); } - - taskExecutorService.executeTasks(calls); - //cacheLock.unlock(); } public void invalidateCache() { - //cacheLock.lock(); + cacheLock.lock(); this.cachedUsers.clear(); - //cacheLock.unlock(); + cacheLock.unlock(); this.internalCacheUpdate(); }