Finish FirebaseRefactoring
All checks were successful
IntegryManagementSystem_Multi/pipeline/head This commit looks good

This commit is contained in:
2025-03-11 16:10:13 +01:00
7 changed files with 135 additions and 144 deletions

View File

@@ -158,29 +158,21 @@ public class NotificationController {
ServiceRestResponse sendNotification(HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String configuration,
@RequestBody MessageDTO messageDTO) {
if (!firebaseService.isActive()) {
return ServiceRestResponse.createNegativeResponse("Servizio notifiche non attivo.");
}
Message.Builder builder = messageDTO.toBuilder();
if (messageDTO.getUserName() != null) {
builder.setTopic(firebaseService.getUserTopic(messageDTO.getUserName(), configuration));
}
ServiceRestResponse response;
try {
firebaseService.sendMessage(builder.build());
Message.Builder builder = messageDTO.toBuilder();
response = ServiceRestResponse.createPositiveResponse("Notifica inviata.");
if (messageDTO.getUserName() != null) {
builder.setTopic(firebaseService.getUserTopic(multiDBTransactionManager.getPrimaryDatasource(), messageDTO.getUserName()));
}
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), builder.build());
return ServiceRestResponse.createPositiveResponse("Notifica inviata.");
} catch (Exception e) {
logger.error(request.getRequestURI(), e);
response = ServiceRestResponse.createNegativeResponse(e);
return ServiceRestResponse.createNegativeResponse(e);
}
return response;
}
@RequestMapping(value = EmsRestConstants.PATH_NOTIF_SEND_USER_DEVICES, method = RequestMethod.POST)
@@ -188,10 +180,6 @@ public class NotificationController {
ServiceRestResponse sendNotificationToUserDevices(HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String configuration,
@RequestBody MessageDTO messageDTO) {
if (!firebaseService.isActive()) {
return ServiceRestResponse.createNegativeResponse("Servizio notifiche non attivo.");
}
ServiceRestResponse response;
try {
@@ -201,7 +189,7 @@ public class NotificationController {
.setToken(device.getDeviceToken())
.build();
firebaseService.sendMessage(message);
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), message);
} catch (FirebaseMessagingException fireEx) {
if (fireEx.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
deviceTokenService.removeDeviceToken(device);
@@ -225,10 +213,6 @@ public class NotificationController {
public ServiceRestResponse sendNotificheCRM(HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String configuration,
@RequestParam int expiryMins) {
if (!firebaseService.isActive()) {
return ServiceRestResponse.createNegativeResponse("Servizio notifiche non attivo.");
}
String titoloNotificheCRM = null;
try {
titoloNotificheCRM = setupGest.getSetup("FIREBASE", "NOTIFICATION", "TITOLO_NOTIFICHE_CRM");
@@ -277,7 +261,7 @@ public class NotificationController {
.build();
try {
firebaseService.sendMessage(message);
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), message);
} catch (FirebaseMessagingException e) {
if (e.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
deviceTokenService.removeDeviceToken(userDevice);

View File

@@ -0,0 +1,7 @@
package it.integry.firebase.exception;
public class FirebaseNotReadyException extends RuntimeException {
public FirebaseNotReadyException() {
super("Firebase not ready. Please initialize it first.");
}
}

View File

@@ -55,16 +55,16 @@ public class DeviceTokenService {
String userName = UtilityHashMap.getValueIfExists(result, "user_name");
if (userName != null && !userDeviceToken.getUserName().equals(userName)) {
firebaseService.unsubscribeFromUser(userDeviceToken.getDeviceToken(), userName, multiDBTransactionManager.getPrimaryDatasource().getProfile());
firebaseService.unsubscribeFromUser(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), userName);
WtbDeviceTokenTopic deviceTokenTopic = new WtbDeviceTokenTopic();
deviceTokenTopic.setOperation(OperationType.DELETE);
deviceTokenTopic.setTopicName(firebaseService.getUserTopic(userName, multiDBTransactionManager.getPrimaryDatasource().getProfile()));
deviceTokenTopic.setTopicName(firebaseService.getUserTopic(multiDBTransactionManager.getPrimaryDatasource(), userName));
userDeviceToken.addWtbDeviceTokenTopic(deviceTokenTopic);
firebaseService.subscribeToUser(userDeviceToken.getDeviceToken(), userDeviceToken.getUserName(), multiDBTransactionManager.getPrimaryDatasource().getProfile());
firebaseService.subscribeToUser(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), userDeviceToken.getUserName());
}
this.manageSubscriptionToTopics(userDeviceToken, SubscribeOperation.SUBSCRIBE, deleteOldTopics);
@@ -93,7 +93,7 @@ public class DeviceTokenService {
entityProcessor.processEntity(userDeviceToken, multiDBTransactionManager);
firebaseService.unsubscribeFromUser(userDeviceToken.getDeviceToken(), userDeviceToken.getUserName(), multiDBTransactionManager.getPrimaryDatasource().getProfile());
firebaseService.unsubscribeFromUser(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), userDeviceToken.getUserName());
this.manageSubscriptionToTopics(userDeviceToken, SubscribeOperation.UNSUBSCRIBE);
@@ -116,7 +116,7 @@ public class DeviceTokenService {
entityProcessor.processEntity(userDeviceToken, multiDBTransactionManager);
firebaseService.unsubscribeFromUser(userDeviceToken.getDeviceToken(), userDeviceToken.getUserName(), multiDBTransactionManager.getPrimaryDatasource().getProfile());
firebaseService.unsubscribeFromUser(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), userDeviceToken.getUserName());
this.manageSubscriptionToTopics(userDeviceToken, SubscribeOperation.UNSUBSCRIBE);
@@ -207,7 +207,7 @@ public class DeviceTokenService {
}
}
final String userTopic = firebaseService.getUserTopic(userDeviceToken.getUserName(), multiDBTransactionManager.getPrimaryDatasource().getProfile());
final String userTopic = firebaseService.getUserTopic(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getUserName());
if (userDeviceToken.getTopics() == null) {
userDeviceToken.setWtbDeviceTokenTopicFromTopics(Collections.singletonList(userTopic));
@@ -218,13 +218,13 @@ public class DeviceTokenService {
switch (operation) {
case SUBSCRIBE:
for (WtbDeviceTokenTopic deviceTokenTopic : userDeviceToken.getWtbDeviceTokenTopic()) {
firebaseService.subscribeToTopic(userDeviceToken.getDeviceToken(), deviceTokenTopic.getTopicName());
firebaseService.subscribeToTopic(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), deviceTokenTopic.getTopicName());
}
break;
case UNSUBSCRIBE:
for (WtbDeviceTokenTopic deviceTokenTopic : userDeviceToken.getWtbDeviceTokenTopic()) {
firebaseService.unsubscribeFromTopic(userDeviceToken.getDeviceToken(), deviceTokenTopic.getTopicName());
firebaseService.unsubscribeFromTopic(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), deviceTokenTopic.getTopicName());
}
break;
@@ -295,7 +295,7 @@ public class DeviceTokenService {
ps.close();
firebaseService.unsubscribeFromTopic(userDeviceToken.getDeviceToken(), topic);
firebaseService.unsubscribeFromTopic(multiDBTransactionManager.getPrimaryDatasource(), userDeviceToken.getDeviceToken(), topic);
}
break;

View File

@@ -6,180 +6,184 @@ import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.TopicManagementResponse;
import it.integry.annotations.PostContextAutowired;
import it.integry.annotations.PostContextConstruct;
import it.integry.ems.datasource.DataSource;
import it.integry.ems.migration._base.IntegryCustomerDB;
import it.integry.ems.settings.Model.SettingsModel;
import it.integry.ems.settings.SettingsController;
import it.integry.ems.sync.MultiDBTransaction.AdvancedDataSource;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.utility.UtilityDebug;
import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.firebase.exception.FirebaseNotReadyException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@Service
@Scope("request")
public class FirebaseService {
public static final String NOTIF_USER_TOPIC_PREFIX = "user_";
@Autowired
private SettingsController settingsController;
@Autowired
private SettingsModel settingsModel;
@Autowired
private SetupGest setupGest;
private boolean dryRun = UtilityDebug.isDebugExecution();
@PostContextAutowired
private MultiDBTransactionManager multiDBTransactionManager;
private final HashMap<String, Boolean> initializedInstances = new HashMap<>();
private final Logger logger = LogManager.getLogger();
private boolean initialize() throws Exception {
boolean isDryRunCheckEnabled = !setupGest.getSetupBoolean("FIREBASE", "NOTIFICATION", "DISABLE_DRY_RUN_CHECK");
dryRun = UtilityDebug.isDebugExecution() && isDryRunCheckEnabled;
if (!FirebaseApp.getApps().isEmpty()) {
return true;
@PostContextConstruct(priority = 10)
private void initialize() throws Exception {
for (AdvancedDataSource advancedDataSource : multiDBTransactionManager.getActiveConnections()) {
initializedInstances.put(advancedDataSource.getDataSource().getDbName(), false);
final HashMap<String, String> setupSection = setupGest.getSetupSection(advancedDataSource.getConnection(), "FIREBASE", "NOTIFICATION");
if (!"S".equalsIgnoreCase(UtilityHashMap.getValueIfExists(setupSection, "ATTIVO")))
return;
InputStream refreshToken;
try {
String endpoint = UtilityHashMap.getValueIfExists(setupSection, "CONFIGURATION_ENDPOINT");
URL url = new URL(endpoint);
refreshToken = url.openStream();
} catch (Exception e) {
logger.error(e);
throw e;
}
if (refreshToken == null)
return;
FirebaseOptions options;
try {
options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(refreshToken))
.build();
} catch (Exception e) {
logger.error(e);
throw e;
}
FirebaseApp.initializeApp(options, advancedDataSource.getDataSource().getDbName());
initializedInstances.put(advancedDataSource.getDataSource().getDbName(), true);
}
if (!this.isActive()) {
return false;
}
InputStream refreshToken;
try {
URL url = new URL(this.getFirebaseEndpoint());
refreshToken = url.openStream();
} catch (Exception e) {
logger.error(e);
throw e;
}
if (refreshToken == null) {
return false;
}
FirebaseOptions options;
try {
options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(refreshToken))
.build();
} catch (Exception e) {
logger.error(e);
throw e;
}
FirebaseApp.initializeApp(options);
return true;
}
public String getFirebaseEndpoint() throws Exception {
return setupGest.getSetup("FIREBASE", "NOTIFICATION", "CONFIGURATION_ENDPOINT");
}
public String sendMessage(Message message) throws Exception {
if (this.initialize()) {
return FirebaseMessaging.getInstance().send(message, this.dryRun);
public String sendMessage(DataSource datasource, Message message) throws Exception {
if (!this.isInitialized(datasource)) {
throw new FirebaseNotReadyException();
}
return null;
return FirebaseMessaging.getInstance().send(message, this.isDryRun(datasource));
}
public TopicManagementResponse subscribeToTopic(String deviceToken, String topic) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse subscribeToTopic(DataSource datasource, String deviceToken, String topic) throws Exception {
if (!this.isInitialized(datasource)) {
throw new FirebaseNotReadyException();
}
return FirebaseMessaging.getInstance().subscribeToTopic(Collections.singletonList(deviceToken), topic);
}
public TopicManagementResponse subscribeToTopic(List<String> deviceTokens, String topic) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse subscribeToTopic(DataSource datasource, List<String> deviceTokens, String topic) throws Exception {
if (!this.isInitialized(datasource)) {
throw new FirebaseNotReadyException();
}
return FirebaseMessaging.getInstance().subscribeToTopic(deviceTokens, topic);
}
public void subscribeToTopics(String deviceToken, List<String> topics) throws Exception {
public void subscribeToTopics(DataSource datasource, String deviceToken, List<String> topics) throws Exception {
for (String topic : topics) {
this.subscribeToTopic(deviceToken, topic);
this.subscribeToTopic(datasource, deviceToken, topic);
}
}
public TopicManagementResponse subscribeToUser(String deviceToken, String userName, String profileDb) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse subscribeToUser(DataSource datasource, String deviceToken, String userName) throws Exception {
if (!this.isInitialized(datasource)) {
throw new FirebaseNotReadyException();
}
return this.subscribeToTopic(deviceToken, getUserTopic(userName, profileDb));
return this.subscribeToTopic(datasource, deviceToken, getUserTopic(datasource, userName));
}
public TopicManagementResponse subscribeToUser(List<String> deviceTokens, String userName, String profileDb) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse subscribeToUser(DataSource datasource, List<String> deviceTokens, String userName) throws Exception {
if (!this.isInitialized(datasource)) {
throw new FirebaseNotReadyException();
}
return this.subscribeToTopic(deviceTokens, getUserTopic(userName, profileDb));
return this.subscribeToTopic(datasource, deviceTokens, getUserTopic(datasource, userName));
}
public TopicManagementResponse unsubscribeFromTopic(String deviceToken, String topic) throws Exception {
if (!this.initialize()) {
return null;
}
public TopicManagementResponse unsubscribeFromTopic(DataSource dataSource, String deviceToken, String topic) throws Exception {
if (!this.isInitialized(dataSource))
throw new FirebaseNotReadyException();
return FirebaseMessaging.getInstance().unsubscribeFromTopic(Collections.singletonList(deviceToken), topic);
}
public TopicManagementResponse unsubscribeFromTopic(List<String> deviceTokens, String topic) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse unsubscribeFromTopic(DataSource dataSource, List<String> deviceTokens, String topic) throws Exception {
if (!this.isInitialized(dataSource)) {
throw new FirebaseNotReadyException();
}
return FirebaseMessaging.getInstance().unsubscribeFromTopic(deviceTokens, topic);
}
public void unsubscribeFromTopics(String deviceToken, List<String> topics) throws Exception {
public void unsubscribeFromTopics(DataSource dataSource, String deviceToken, List<String> topics) throws Exception {
for (String topic : topics) {
this.unsubscribeFromTopic(deviceToken, topic);
this.unsubscribeFromTopic(dataSource, deviceToken, topic);
}
}
public TopicManagementResponse unsubscribeFromUser(String deviceToken, String userName, String profileDb) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse unsubscribeFromUser(DataSource dataSource, String deviceToken, String userName) throws Exception {
if (!this.isInitialized(dataSource)) {
throw new FirebaseNotReadyException();
}
return this.unsubscribeFromTopic(deviceToken, getUserTopic(userName, profileDb));
return this.unsubscribeFromTopic(dataSource, deviceToken, getUserTopic(dataSource, userName));
}
public TopicManagementResponse unsubscribeFromUser(List<String> deviceTokens, String userName, String profileDb) throws Exception {
if (!this.initialize()) {
return null;
public TopicManagementResponse unsubscribeFromUser(DataSource dataSource, List<String> deviceTokens, String userName) throws Exception {
if (!this.isInitialized(dataSource)) {
throw new FirebaseNotReadyException();
}
return this.unsubscribeFromTopic(deviceTokens, getUserTopic(userName, profileDb));
return this.unsubscribeFromTopic(dataSource, deviceTokens, getUserTopic(dataSource, userName));
}
public boolean isDryRun() {
return dryRun;
private boolean isInitialized(DataSource advancedDataSource) {
String dbName = advancedDataSource.getDbName();
return initializedInstances.getOrDefault(dbName, false);
}
public void setDryRun(boolean dryRun) {
this.dryRun = dryRun;
public boolean isDryRun(DataSource advancedDataSource) {
return !IntegryCustomerDB.Integry_Studioml.getValue().equalsIgnoreCase(advancedDataSource.getDbName()) &&
(UtilityDebug.isDebugExecution() || UtilityDebug.isIntegryServer());
}
public boolean isActive() {
boolean attivo = false;
try {
attivo = setupGest.getSetupBoolean("FIREBASE", "NOTIFICATION", "ATTIVO");
} catch (Exception e) {
logger.error(e);
}
return attivo;
}
public String getUserTopic(String userName, String profileDb) {
return (NOTIF_USER_TOPIC_PREFIX + userName + "_" + profileDb).toLowerCase();
public String getUserTopic(DataSource dataSource, String userName) {
return (NOTIF_USER_TOPIC_PREFIX + userName + "_" + dataSource.getProfile()).toLowerCase();
}
}

View File

@@ -40,7 +40,7 @@ public class NotificationSenderComponent {
@Autowired
private ResponseJSONObjectMapper responseJSONObjectMapper;
@PostContextConstruct(priority = 10)
@PostContextConstruct(priority = 11)
private void init() {
if (!UtilityDebug.isDebugExecution())
looperService.add(this::sendNotifications, 15 * 60 * 1000, NotificationSenderComponent.class.getName());

View File

@@ -401,11 +401,11 @@ public class NotificationService {
builder.setToken(deviceToken);
try {
if (firebaseService.isDryRun()) {
if (firebaseService.isDryRun(multiDBTransactionManager.getPrimaryDatasource())) {
logger.debug("Invio notifica Firebase in dry run: \n" + notification);
}
firebaseService.sendMessage(builder.build());
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), builder.build());
deviceNotification = new WtbDeviceNotification();
@@ -533,17 +533,13 @@ public class NotificationService {
}
public void sendNotification(MessageDTO messageDTO) throws Exception {
if (!firebaseService.isActive()) {
throw new Exception("Servizio notifiche non attivo.");
}
Message.Builder builder = messageDTO.toBuilder();
if (messageDTO.getUserName() != null) {
builder.setTopic(firebaseService.getUserTopic(messageDTO.getUserName(), multiDBTransactionManager.getPrimaryDatasource().getProfile()));
builder.setTopic(firebaseService.getUserTopic(multiDBTransactionManager.getPrimaryDatasource(), messageDTO.getUserName()));
}
firebaseService.sendMessage(builder.build());
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), builder.build());
}
public void sendNotificationToUserDevices(MessageDTO messageDTO) throws Exception {
@@ -557,7 +553,7 @@ public class NotificationService {
.setToken(device.getDeviceToken())
.build();
firebaseService.sendMessage(message);
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), message);
} catch (FirebaseMessagingException fireEx) {
if (fireEx.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
deviceTokenService.removeDeviceToken(device);

View File

@@ -2662,7 +2662,7 @@ public class PvmService {
message.setWebpush(webpushConfigDTO);
try {
firebaseService.sendMessage(message.toBuilder().build());
firebaseService.sendMessage(multiDBTransactionManager.getPrimaryDatasource(), message.toBuilder().build());
} catch (FirebaseMessagingException fireEx) {
if (fireEx.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
// deviceTokenService.removeDeviceToken(deviceToken);