Refactoring UserCacheService, adesso sfrutta EntityCache più che il caching integrato.
All checks were successful
IntegryManagementSystem_Multi/pipeline/head This commit looks good

This commit is contained in:
2025-12-01 13:05:59 +01:00
parent 6c2eaaa37a
commit 8d35f9284a
10 changed files with 271 additions and 270 deletions

View File

@@ -69,7 +69,6 @@ public class EmsCoreDBLoader {
try (MultiDBTransactionManager multiDBTransactionManager = new MultiDBTransactionManager(connectionPool)){
discoverAllConnections(multiDBTransactionManager);
setupAzienda(multiDBTransactionManager);
userCacheService.discoverAllUsers(multiDBTransactionManager);
if (onComplete != null) onComplete.run(multiDBTransactionManager);
} catch (Exception ex) {

View File

@@ -35,9 +35,10 @@ public class DbmsChangeTrackerComponent {
add(StbEditLimit.ENTITY);
add(StbGestSetup.ENTITY);
add(StbGestSetupDepo.ENTITY);
add(WtbGestSetupUser.ENTITY);
add(StbUser.ENTITY);
add(WtbClie.ENTITY);
add(WtbDepo.ENTITY);
add(WtbGestSetupUser.ENTITY);
}};

View File

@@ -44,6 +44,14 @@ public class EntityCacheComponent implements ApplicationListener {
private final HashMap<IntegryCustomerDB, ConcurrentHashMap<String, ConcurrentHashMap<HashMap<String, Object>, EntityBase>>> entityCache = new HashMap<>();
// Lock per IntegryCustomerDB per garantire accessi sincronizzati alla cache di quel customer
private final ConcurrentHashMap<IntegryCustomerDB, Object> cacheLocks = new ConcurrentHashMap<>();
private Object getCacheLock(IntegryCustomerDB customerDB) {
cacheLocks.putIfAbsent(customerDB, new Object());
return cacheLocks.get(customerDB);
}
private final HashMap<String, Class<? extends EntityBase>> enabledEntities = new HashMap<String, Class<? extends EntityBase>>() {{
put(MtbAart.ENTITY, MtbAart.class);
put(MtbAartBarCode.ENTITY, MtbAartBarCode.class);
@@ -52,9 +60,10 @@ public class EntityCacheComponent implements ApplicationListener {
put(StbEditLimit.ENTITY, StbEditLimit.class);
put(StbGestSetup.ENTITY, StbGestSetup.class);
put(StbGestSetupDepo.ENTITY, StbGestSetupDepo.class);
put(WtbGestSetupUser.ENTITY, WtbGestSetupUser.class);
put(StbUser.ENTITY, StbUser.class);
put(WtbDepo.ENTITY, WtbDepo.class);
put(WtbGestSetupUser.ENTITY, WtbGestSetupUser.class);
put(WtbClie.ENTITY, WtbClie.class);
}};
public EntityCacheComponent(DbmsChangeTrackerComponent dbmsChangeTrackerComponent, EntityPropertyHolder entityPropertyHolder) {
@@ -103,6 +112,8 @@ public class EntityCacheComponent implements ApplicationListener {
}
private void refreshCacheForEntity(Connection connection, IntegryCustomerDB customerDB, String tableName) throws Exception {
// Sincronizziamo l'intera operazione di refresh per il customerDB per evitare accessi concorrenti
synchronized (getCacheLock(customerDB)) {
Class<? extends EntityBase> clazz = enabledEntities.get(tableName);
// if (clazz == null)
// throw new RuntimeException("Entity cache is not enabled for table " + tableName);
@@ -118,6 +129,7 @@ public class EntityCacheComponent implements ApplicationListener {
entities.size(),
clazz.getSimpleName()));
}
}
public <T extends EntityBase> List<T> getCachedEntitiesList(IntegryCustomerDB customerDB, String tableName, Predicate<T> filterPredicate) {
return getCachedEntitiesStream(customerDB, tableName, filterPredicate)
@@ -125,6 +137,9 @@ public class EntityCacheComponent implements ApplicationListener {
}
public <T extends EntityBase> Stream<T> getCachedEntitiesStream(IntegryCustomerDB customerDB, String tableName, Predicate<T> filterPredicate) {
// Per evitare accessi concorrenti leggiamo/snapshottiamo la cache sotto lock per quel customerDB
List<T> snapshot;
synchronized (getCacheLock(customerDB)) {
if (!isCacheEnabled(customerDB, tableName)) {
try {
refreshCacheForEntity(customerDB, tableName);
@@ -133,12 +148,16 @@ public class EntityCacheComponent implements ApplicationListener {
}
}
return entityCache.get(customerDB).get(tableName)
// prendo un'istantanea degli oggetti clonati per poter lavorare fuori dal lock
snapshot = entityCache.get(customerDB)
.get(tableName)
.values()
.parallelStream()
.map(x -> (T) x)
.filter(filterPredicate)
.map(x -> (T) x.clone());
.stream()
.map(x -> (T) x.clone())
.collect(Collectors.toList());
}
return snapshot.stream().filter(filterPredicate);
}
@@ -176,9 +195,12 @@ public class EntityCacheComponent implements ApplicationListener {
event.getPrimaryKey());
// sincronizziamo la modifica per il customerDB
synchronized (getCacheLock(event.getCustomerDB())) {
entityCache.get(event.getCustomerDB())
.get(event.getTableName())
.put(entityPrimaryKey, newItem);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -195,9 +217,13 @@ public class EntityCacheComponent implements ApplicationListener {
enabledEntities.get(event.getTableName()),
event.getPrimaryKey());
// sincronizziamo la modifica per il customerDB
synchronized (getCacheLock(event.getCustomerDB())) {
entityCache.get(event.getCustomerDB())
.get(event.getTableName())
.put(entityPrimaryKey, newItem);
}
} catch (Exception e) {
throw new RuntimeException(e);
@@ -210,12 +236,17 @@ public class EntityCacheComponent implements ApplicationListener {
HashMap<String, Object> entityPrimaryKey = convertSqlMapToEntityMap(event.getPrimaryKey(), enabledEntities.get(event.getTableName()));
final EntityBase removedItem = entityCache.get(event.getCustomerDB())
// sincronizziamo la rimozione per il customerDB
final EntityBase removedItem;
synchronized (getCacheLock(event.getCustomerDB())) {
removedItem = entityCache.get(event.getCustomerDB())
.get(event.getTableName())
.remove(entityPrimaryKey);
}
}
private void handleTableTrackingResetted(TableTrackingResettedEvent event) throws Exception {
// reset e refresh sono eseguiti in modo sincronizzato per quel customer
resetTablesCache(event.getCustomerDB());
refreshCacheGlobal(event.getCustomerDB());
}
@@ -267,15 +298,20 @@ public class EntityCacheComponent implements ApplicationListener {
private void resetTableCache(IntegryCustomerDB customerDB, String tableName) {
synchronized (getCacheLock(customerDB)) {
if (entityCache.containsKey(customerDB) && entityCache.get(customerDB).containsKey(tableName)) {
entityCache.get(customerDB).remove(tableName);
}
}
}
private void resetTablesCache(IntegryCustomerDB customerDB) {
// sincronizziamo la rimozione dell'intera cache per il customer
synchronized (getCacheLock(customerDB)) {
entityCache.remove(customerDB);
}
}
private boolean isCacheEnabled(IntegryCustomerDB customerDB, String tableName) {

View File

@@ -6,6 +6,7 @@ import it.integry.ems_model.entity.StbUser;
import it.integry.ems_model.entity.WtbUsers;
import it.integry.ems_model.types.OperationType;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityLocalDate;
import it.integry.ems_model.utility.UtilityString;
import it.integry.security.utility.CryptoUtils;
@@ -57,7 +58,7 @@ public class Migration_20220413102657 extends BaseMigration implements Migration
.setUserCode(wtbUser.getUserCode())
.setDetails(wtbUser.getDetails())
.setLastAccessDatetime(wtbUser.getLastAccessDatetime())
.setPasswordEndtime(wtbUser.getPasswordEndtime())
.setPasswordEndtime(UtilityLocalDate.localDateTimeFromDate(wtbUser.getPasswordEndtime()))
.setUrlCss(wtbUser.getUrlCss())
.setCodLang(wtbUser.getCodLang())
.setCreationDatetime(wtbUser.getCreationDatetime())

View File

@@ -1,29 +1,26 @@
package it.integry.ems.user.service;
import it.integry.annotations.PostContextConstruct;
import it.integry.ems.dynamic_cache.EntityCacheComponent;
import it.integry.ems.migration._base.IntegryCustomerDB;
import it.integry.ems.model.IntegryApplicationEnum;
import it.integry.ems.settings.Model.AvailableConnectionModel;
import it.integry.ems.settings.Model.SettingsModel;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.task.TaskExecutorService;
import it.integry.ems.user.dto.UserDTO;
import it.integry.ems_model.entity.StbUser;
import it.integry.ems_model.entity.WtbClie;
import it.integry.ems_model.entity.WtbDepo;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHash;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class UserCacheService {
@@ -31,73 +28,22 @@ public class UserCacheService {
@Autowired
private SettingsModel settingsModel;
@Autowired
private TaskExecutorService taskExecutorService;
@Autowired
private EntityCacheComponent entityCacheComponent;
private final Logger logger = LogManager.getLogger();
private final HashMap<String, List<UserDTO>> cachedUsers = new HashMap<>();
private final ReentrantLock cacheLock = new ReentrantLock();
boolean canStart = false;
@PostContextConstruct(priority = 10)
private void init() {
canStart = true; //!UtilityDebug.isDebugExecution();
}
@Scheduled(fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
private void internalCacheUpdate() {
internalCacheUpdate(false);
}
private void internalCacheUpdate(boolean forceStart) {
if (!forceStart && !canStart) return;
List<AvailableConnectionModel> availableConnectionModels =
settingsModel.getAvailableConnectionsWithoutDuplicatedProfiles(true);
try (MultiDBTransactionManager multiDBTransactionManager = new MultiDBTransactionManager()) {
for (AvailableConnectionModel model : availableConnectionModels) {
try {
multiDBTransactionManager.addConnection(model);
} catch (Exception ex) {
logger.info(String.format("Cannot find %s database", model.getDbName()), ex);
}
}
this.discoverAllUsers(multiDBTransactionManager);
} catch (Exception ex) {
logger.error("Refresh user cache", ex);
}
}
private void cache(String dbName, UserDTO user) {
cachedUsers.putIfAbsent(dbName, new ArrayList<>());
List<UserDTO> users = cachedUsers.get(dbName);
Optional<UserDTO> existentUser = users.stream()
.filter(x -> x.getUsername().equalsIgnoreCase(user.getUsername()))
.findFirst();
existentUser.ifPresent(users::remove);
users.add(user);
}
public List<String> retrieveProfilesOfUser(String username, String password, IntegryApplicationEnum application) {
ArrayList<String> profiles = new ArrayList<>();
for (Map.Entry<String, List<UserDTO>> users : cachedUsers.entrySet()) {
final UserDTO foundUser = retrieveUser(users.getKey(), username, password, application);
final List<AvailableConnectionModel> availableConnections = settingsModel.getAvailableConnectionsWithoutDuplicatedProfiles(true);
for (AvailableConnectionModel availableConnection : availableConnections) {
final UserDTO foundUser = retrieveUser(availableConnection.getDbName(), username, password, application);
if (foundUser != null) {
profiles.add(settingsModel.getProfileDbFromDbName(users.getKey()));
profiles.add(availableConnection.getProfileName());
}
}
@@ -105,9 +51,7 @@ public class UserCacheService {
}
public @Nullable UserDTO retrieveUser(String dbName, String md5User) {
cacheLock.lock();
try {
List<UserDTO> users = cachedUsers.getOrDefault(dbName, null);
List<UserDTO> users = internalUsersRetrieve(IntegryCustomerDB.parse(dbName), null);
if (users == null || users.isEmpty())
return null;
@@ -123,15 +67,11 @@ public class UserCacheService {
.findFirst();
return foundUser.orElse(null);
} finally {
cacheLock.unlock();
}
}
public @Nullable UserDTO retrieveUser(String dbName, String username, String password, IntegryApplicationEnum application) {
cacheLock.lock();
try {
List<UserDTO> users = cachedUsers.getOrDefault(dbName, null);
List<UserDTO> users = internalUsersRetrieve(IntegryCustomerDB.parse(dbName), username);
if (users == null || users.isEmpty())
return null;
@@ -141,8 +81,7 @@ public class UserCacheService {
String finalPasswordHex = UtilityHash.generateHash(password.toUpperCase());
final Optional<UserDTO> foundUser = users.stream()
.filter(x -> x.getUsername().equalsIgnoreCase(username) &&
x.isAttivo() &&
.filter(x -> x.isAttivo() &&
x.getPasswordHash().contentEquals(finalPasswordHex) &&
(application == null ||
(application == IntegryApplicationEnum.PVM && x.isWeb()) ||
@@ -155,24 +94,19 @@ public class UserCacheService {
.findFirst();
return foundUser.orElse(null);
} finally {
cacheLock.unlock();
}
}
public @Nullable UserDTO retrieveUserData(String profileDb, String username, IntegryApplicationEnum application) {
cacheLock.lock();
try {
String dbName = settingsModel.getDbNameFromProfileDb(profileDb);
List<UserDTO> users = cachedUsers.getOrDefault(dbName, null);
List<UserDTO> users = internalUsersRetrieve(IntegryCustomerDB.parse(dbName), username);
if (users == null || users.isEmpty())
return null;
final Optional<UserDTO> foundUser = users.stream()
.filter(x -> x.getUsername().equalsIgnoreCase(username) &&
(application == null ||
.filter(x -> (application == null ||
(application == IntegryApplicationEnum.PVM && x.isWeb()) ||
(application == IntegryApplicationEnum.CONSEGNA && x.isWeb()) ||
(application == IntegryApplicationEnum.WMS && x.isWeb()) ||
@@ -183,74 +117,52 @@ public class UserCacheService {
.findFirst();
return foundUser.orElse(null);
} finally {
cacheLock.unlock();
}
}
public void discoverAllUsers(MultiDBTransactionManager multiDBTransactionManager) throws Exception {
cacheLock.lock();
try {
List<Callable<Void>> calls = new ArrayList<>();
for (final Connection connection : multiDBTransactionManager.getActiveConnections()) {
calls.add(() -> {
try {
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" +
" su.cod_lang,\n" +
" su.flag_password_expiring,\n" +
" CAST(IIF(su.password_endtime IS NOT NULL AND\n" +
" DATEDIFF(DAY, su.password_endtime, 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" +
" 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" +
" '" + connection.getProfileName() + "' AS profile_db\n" +
"FROM " + StbUser.ENTITY + " su " +
" LEFT OUTER JOIN wtb_clie wc ON su.user_name = wc.user_name\n" +
"WHERE dbo.sys_dcd_pss(su.password) IS NOT NULL";
private List<UserDTO> internalUsersRetrieve(IntegryCustomerDB customerDB, String username) {
return entityCacheComponent.<StbUser>getCachedEntitiesStream(
customerDB,
StbUser.ENTITY,
x -> x.getPasswordDecoded() != null && (username == null || x.getUserName().equalsIgnoreCase(username)))
.map(x -> {
UserDTO userDTO = new UserDTO()
.setProfileDb(settingsModel.getProfileDbFromDbName(customerDB.getValue()))
.setUsername(x.getUserName())
.setPassword(x.getPasswordDecoded())
.setPasswordHash(UtilityHash.generateHash(x.getPasswordDecoded().toUpperCase()))
.setKeyGroup(x.getKeyGroup())
.setFullname(x.getFullName())
.setEmail(x.geteMail())
.setLastAccessDatetime(x.getLastAccessDatetime())
.setPasswordEndtime(x.getPasswordEndtime())
.setCodLang(x.getCodLang())
.setFlagPasswordExpiring(x.getFlagPasswordExpiring() != null ? x.getFlagPasswordExpiring().charAt(0) : null)
.setPasswordExpired(x.getPasswordEndtime() != null
&& LocalDateTime.now().isAfter(x.getPasswordEndtime())
&& "S".equalsIgnoreCase(x.getFlagPasswordExpiring()))
.setUserCode(x.getUserCode()) //To be customized
.setAttivo("S".equalsIgnoreCase(x.getFlagAttivo()))
.setInternal("S".equalsIgnoreCase(x.getFlagIntraUser()) || "S".equalsIgnoreCase(x.getFlagDba()))
.setWeb("S".equalsIgnoreCase(x.getFlagIntraUser()) || "S".equalsIgnoreCase(x.getFlagExtraUser()));
final List<UserDTO> userDTOS = UtilityDB.executeSimpleQueryDTO(connection, sql, UserDTO.class);
if (userDTO.getKeyGroup() != null && userDTO.getKeyGroup() == 3) {
final List<WtbClie> wtbClie = entityCacheComponent.getCachedEntitiesList(customerDB, WtbClie.ENTITY,
y -> y.getUserName().equalsIgnoreCase(userDTO.getUsername()));
if (userDTOS != null)
userDTOS.forEach(x -> {
List<WtbDepo> availableDepoList = entityCacheComponent.getCachedEntitiesList(connection.getIntegryCustomerDB(), WtbDepo.ENTITY,
if (!wtbClie.isEmpty())
userDTO.setUserCode(wtbClie.get(0).getCodAnag());
}
List<WtbDepo> availableDepoList = entityCacheComponent.getCachedEntitiesList(customerDB, WtbDepo.ENTITY,
y -> x.getUsername().equalsIgnoreCase(y.getUserName())
);
x.setAvailableDepoList(availableDepoList);
userDTO.setAvailableDepoList(availableDepoList);
cache(connection.getDbName(), x);
});
} catch (Exception ex) {
logger.error(String.format("Errore durante la retrieve degli utenti su \"%s\". %s", connection.getProfileName(), ex.getMessage()), ex);
return userDTO;
})
.collect(Collectors.toList());
}
return null;
});
}
taskExecutorService.executeTasks(calls);
} finally {
cacheLock.unlock();
}
}
public void invalidateCache() {
cacheLock.lock();
this.cachedUsers.clear();
cacheLock.unlock();
this.internalCacheUpdate(true);
}
}

View File

@@ -45,7 +45,7 @@ public class UserRegistrationService {
.setPassword(userRegistrationDTO.getPassword())
.seteMail(userRegistrationDTO.getEmail())
.setUserNameRif(userRegistrationDTO.getCodAzienda())
.setPasswordEndtime(EmsRestConstants.DATE_NULL)
.setPasswordEndtime(EmsRestConstants.LOCAL_DATE_TIME_NULL)
.setKeyGroup(userRegistrationDTO.getKeyGroup())
.setFlagExtraUser("S")
.setCryptPassword(true);

View File

@@ -15,14 +15,17 @@ import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.entity.StbFilesAttached;
import it.integry.ems_model.entity.StbUser;
import it.integry.ems_model.types.OperationType;
import it.integry.ems_model.utility.*;
import it.integry.ems_model.utility.Query;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityLocalDate;
import it.integry.ems_model.utility.UtilityString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.List;
@Service
@@ -61,8 +64,6 @@ public class UserService {
UtilityEntity.throwEntityException(stbUser);
userCacheService.invalidateCache();
return stbUser;
}
@@ -91,11 +92,11 @@ public class UserService {
entityProcessor.processEntity(stbUser, multiDBTransactionManager);
Date passwordEndtime = EmsRestConstants.DATE_NULL;
LocalDateTime passwordEndtime = EmsRestConstants.LOCAL_DATE_TIME_NULL;
if (stbUser.getFlagPasswordExpiring().equalsIgnoreCase("S") &&
stbUser.getPasswordExpiresDays() != 0) {
passwordEndtime = UtilityDate.dateAdd(new Date(), stbUser.getPasswordExpiresDays());
passwordEndtime = LocalDateTime.now().plusDays(stbUser.getPasswordExpiresDays());
}
stbUser
@@ -111,8 +112,6 @@ public class UserService {
UtilityEntity.throwEntityException(stbUser);
userCacheService.invalidateCache();
return stbUser;
}
@@ -143,18 +142,7 @@ public class UserService {
}
public List<String> retrieveAvailableProfiles(String username, String password) {
List<String> profiles;
profiles = userCacheService.retrieveProfilesOfUser(username, password, requestDataDTO.getApplication());
if (profiles.isEmpty()) {
// SELEZIONE CICLICA IN TUTTI I DB SPECIFICATI
userCacheService.invalidateCache();
profiles = userCacheService.retrieveProfilesOfUser(username, password, requestDataDTO.getApplication());
}
return profiles;
return userCacheService.retrieveProfilesOfUser(username, password, requestDataDTO.getApplication());
}
public String getSignatureIdAttach(String username) throws Exception {

View File

@@ -1,5 +1,6 @@
package it.integry.ems_model.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import it.integry.common.var.CommonConstants;
@@ -7,6 +8,7 @@ import it.integry.ems_model.annotation.*;
import it.integry.ems_model.base.EntityBase;
import it.integry.ems_model.utility.Query;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityPassword;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kie.api.definition.type.PropertyReactive;
@@ -96,7 +98,7 @@ public class StbUser extends EntityBase {
private String lastPasswords;
@SqlField(value = "password_endtime")
private Date passwordEndtime;
private LocalDateTime passwordEndtime;
@SqlField(value = "password_expires_days", defaultObjectValue = "180")
private Integer passwordExpiresDays;
@@ -422,11 +424,11 @@ public class StbUser extends EntityBase {
return this;
}
public Date getPasswordEndtime() {
public LocalDateTime getPasswordEndtime() {
return passwordEndtime;
}
public StbUser setPasswordEndtime(Date passwordEndtime) {
public StbUser setPasswordEndtime(LocalDateTime passwordEndtime) {
this.passwordEndtime = passwordEndtime;
return this;
}
@@ -670,4 +672,12 @@ public class StbUser extends EntityBase {
JrlFlavUsers jrlFlavUsers = new JrlFlavUsers();
jrlFlavUsers.deleteAllEntities(connection, this);
}
@JsonIgnore
public String getPasswordDecoded() {
if (this.password != null)
return UtilityPassword.sysDcdPss(this.password);
return null;
}
}

View File

@@ -0,0 +1,60 @@
package it.integry.ems_model.utility;
public class UtilityPassword {
/**
* Replica della funzione SQL Server dbo.sys_dcd_pss in Java 1.8.
*
* @param input stringa in ingresso (equivalente a @input VARCHAR(MAX))
* @return stringa "decrypted" (equivalente al RETURN VARCHAR(MAX))
*/
public static String sysDcdPss(String input) {
if (input == null || input.isEmpty()) {
return input;
}
// In SQL:
// DECLARE @decrypted AS VARCHAR(MAX)
// SELECT @decrypted = SUBSTRING(@input, 1, 1)
StringBuilder decrypted = new StringBuilder();
decrypted.append(input.charAt(0));
int minAscii = 0;
int maxAscii = 122;
// DECLARE @firstCharAscii AS INT = ASCII(@decrypted);
int firstCharAscii = (int) decrypted.charAt(0);
// In SQL l'indice @i parte da 0 e il WHILE usa DATALENGTH(@input)
// con caratteri 1-based: substring(@input, @i, 1).
// In Java useremo un for su index 1-based per aderire alla logica.
int dataLength = input.length(); // DATALENGTH per VARCHAR = numero di caratteri
int i = 0;
while (i < dataLength) {
i = i + 1;
// IF @i = 1 CONTINUE
if (i == 1) {
continue;
}
// substring(@input, @i, 1) -> input.charAt(i - 1) in Java (0-based)
int currentCharAscii = (int) input.charAt(i - 1);
if (currentCharAscii <= maxAscii) {
currentCharAscii = currentCharAscii - firstCharAscii;
if (currentCharAscii <= minAscii) {
currentCharAscii = currentCharAscii + maxAscii;
}
} else {
currentCharAscii = currentCharAscii - firstCharAscii;
}
decrypted.append((char) currentCharAscii);
}
return decrypted.toString();
}
}

View File

@@ -158,8 +158,7 @@ public class SystemController {
@RequestParam(value = "dataInizio") Date dataInizio,
@RequestParam(value = "dataFine") Date dataFine) throws Exception {
String configuration = "INTEGRY";
MultiDBTransactionManager dbIntegry = new MultiDBTransactionManager(configuration);
try (MultiDBTransactionManager dbIntegry = new MultiDBTransactionManager(configuration)) {
String query =
"SELECT dbo.f_escape_json(log.processo) as 'processo', "
@@ -172,17 +171,12 @@ public class SystemController {
+ "ORDER BY 3, 1, 2 ";
List<ChangeLogDTO> changeLog = null;
try {
changeLog = UtilityDB.executeSimpleQueryDTO(dbIntegry.getPrimaryConnection(), query, ChangeLogDTO.class);
} finally {
dbIntegry.close();
}
List<ChangeLogDTO> changeLog = UtilityDB.executeSimpleQueryDTO(dbIntegry.getPrimaryConnection(), query, ChangeLogDTO.class);
if (changeLog != null && !changeLog.isEmpty()) {
return ServiceRestResponse.createPositiveResponse(changeLog);
}
}
return ServiceRestResponse.createPositiveResponse();
}