Notification service upgrade to Spring Boot 3, fixing startup and dependency issues

This commit is contained in:
Thomas Georgios Giannos 2024-01-16 19:13:07 +02:00
parent b04c0aebab
commit aab7571763
109 changed files with 1322 additions and 710 deletions

View File

@ -9,6 +9,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@Configuration
@EnableConfigurationProperties({InboxProperties.class})

View File

@ -9,6 +9,7 @@ import eu.eudat.commons.enums.notification.NotificationTrackingState;
import eu.eudat.commons.validation.ValidatorFactory;
import eu.eudat.data.UserContactInfoEntity;
import eu.eudat.data.UserEntity;
import eu.eudat.integrationevent.outbox.OutboxIntegrationEvent;
import eu.eudat.integrationevent.outbox.OutboxService;
import eu.eudat.model.persist.notification.NotificationPersist;
import eu.eudat.query.UserContactInfoQuery;
@ -26,6 +27,7 @@ import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
@Component
@RequestScope
@ -58,30 +60,30 @@ public class NotificationIntegrationEventHandlerImpl implements NotificationInte
@Override
public void handle(NotificationIntegrationEvent event) throws InvalidApplicationException {
// OutboxIntegrationEvent message = new OutboxIntegrationEvent();
// message.setMessageId(UUID.randomUUID());
// message.setType(OutboxIntegrationEvent.NOTIFY);
// message.setEvent(event);
// this.outboxService.publish(message);
NotificationPersist persist = new NotificationPersist();
persist.setType(event.getNotificationType());
persist.setUserId(event.getUserId());
persist.setContactHint(event.getContactHint());
persist.setContactTypeHint(event.getContactTypeHint());
persist.setData(event.getData());
persist.setNotifyState(NotificationNotifyState.PENDING);
persist.setNotifiedWith(event.getContactTypeHint());
persist.setRetryCount(0);
persist.setTrackingState(NotificationTrackingState.UNDEFINED);
persist.setTrackingProcess(NotificationTrackingProcess.PENDING);
persist.setTrackingData(null);
persist.setProvenanceRef(event.getProvenanceRef());
persist.setNotifiedAt(Instant.now());
validatorFactory.validator(NotificationPersist.NotificationPersistValidator.class).validateForce(persist);
if (isNotificationConsistent(persist)) {
notificationService.persist(persist, null);
auditService.track(AuditableAction.Notification_Persist, "notification_event", event);
}
OutboxIntegrationEvent message = new OutboxIntegrationEvent();
message.setMessageId(UUID.randomUUID());
message.setType(OutboxIntegrationEvent.NOTIFY);
message.setEvent(event);
this.outboxService.publish(message);
// NotificationPersist persist = new NotificationPersist();
// persist.setType(event.getNotificationType());
// persist.setUserId(event.getUserId());
// persist.setContactHint(event.getContactHint());
// persist.setContactTypeHint(event.getContactTypeHint());
// persist.setData(event.getData());
// persist.setNotifyState(NotificationNotifyState.PENDING);
// persist.setNotifiedWith(event.getContactTypeHint());
// persist.setRetryCount(0);
// persist.setTrackingState(NotificationTrackingState.UNDEFINED);
// persist.setTrackingProcess(NotificationTrackingProcess.PENDING);
// persist.setTrackingData(null);
// persist.setProvenanceRef(event.getProvenanceRef());
// persist.setNotifiedAt(Instant.now());
// validatorFactory.validator(NotificationPersist.NotificationPersistValidator.class).validateForce(persist);
// if (isNotificationConsistent(persist)) {
// notificationService.persist(persist, null);
// auditService.track(AuditableAction.Notification_Persist, "notification_event", event);
// }
}
private boolean isNotificationConsistent(NotificationPersist notification) {

View File

@ -8,15 +8,16 @@
<groupId>gr.cite</groupId>
<artifactId>notification-service-parent</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
<relativePath>../../notification-service/pom.xml</relativePath>
</parent>
<artifactId>notification-web</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.release>21</maven.compiler.release>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
@ -24,10 +25,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.6.4</version>
</dependency>
<dependency>
@ -35,15 +40,21 @@
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>notification</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>oidc-authz</artifactId>
@ -64,15 +75,6 @@
<artifactId>cors-web</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.6.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -3,19 +3,24 @@ package gr.cite.notification.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@ComponentScan({
"gr.cite.notification",
"gr.cite.tools",
"gr.cite.commons"})
@SpringBootApplication(
scanBasePackages = {
"eu.eudat",
"gr.cite",
"gr.cite.queueoutbox",
"gr.cite.queueinbox",
"gr.cite.notification.integrationevent",
"gr.cite.tools",
"gr.cite.commons"})
@EntityScan({
"gr.cite.notification.data"})
"gr.cite.notification.data"})
@EnableAsync
public class NotificationApplication {
public static void main(String[] args) {
SpringApplication.run(NotificationApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(NotificationApplication.class, args);
}
}

View File

@ -18,18 +18,20 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public class SecurityConfiguration {
private final WebSecurityProperties webSecurityProperties;
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
@ -47,20 +49,19 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
this.ownedAuthorizationHandler = ownedAuthorizationHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors()
.and()
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
HttpSecurity tempHttp = http
.csrf(AbstractHttpConfigurer::disable)
.cors(httpSecurityCorsConfigurer -> {})
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class)
.authorizeRequests()
.antMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous()
.antMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.authorizeHttpRequests(authRequest ->
authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous()
.requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated())
.sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER))
.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
return tempHttp.build();
}
@Bean

View File

@ -34,7 +34,7 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import java.util.*;
@RestController

View File

@ -2,10 +2,8 @@ package gr.cite.notification.web.controllers;
import gr.cite.notification.audit.AuditableAction;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.NotificationEntity;
import gr.cite.notification.model.Notification;
import gr.cite.notification.model.SendNotificationResult;
import gr.cite.notification.model.builder.NotificationBuilder;
import gr.cite.notification.model.censorship.NotificationCensor;
import gr.cite.notification.model.persist.NotificationPersist;
@ -24,6 +22,7 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.MyValidate;
import jakarta.transaction.Transactional;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
@ -31,7 +30,6 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import java.util.*;
@RestController

View File

@ -29,7 +29,7 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import java.util.*;
@RestController

View File

@ -32,8 +32,8 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import javax.validation.Valid;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import java.util.*;
@RestController

View File

@ -10,11 +10,9 @@ import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.notification.model.builder.UserNotificationPreferenceBuilder;
import gr.cite.notification.model.censorship.UserNotificationPreferenceCensor;
import gr.cite.notification.model.persist.UserNotificationPreferencePersist;
import gr.cite.notification.model.persist.tenantconfiguration.TenantConfigurationNotifierListPersist;
import gr.cite.notification.query.UserNotificationPreferenceQuery;
import gr.cite.notification.query.lookup.NotifierListLookup;
import gr.cite.notification.query.lookup.UserNotificationPreferenceLookup;
import gr.cite.notification.service.tenantconfiguration.TenantConfigurationService;
import gr.cite.notification.service.userNotificationPreference.UserNotificationPreferenceService;
import gr.cite.notification.web.model.QueryResult;
import gr.cite.tools.auditing.AuditService;
@ -27,15 +25,14 @@ import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import jakarta.validation.Valid;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import javax.validation.Valid;
import jakarta.transaction.Transactional;
import java.util.*;
@RestController

View File

@ -35,8 +35,8 @@ import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

View File

@ -26,13 +26,13 @@ import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import java.util.List;
import java.util.Locale;

View File

@ -22,12 +22,12 @@ import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import java.util.List;
import java.util.UUID;

View File

@ -17,12 +17,12 @@ import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import java.util.List;
import java.util.UUID;

View File

@ -21,12 +21,12 @@
//import org.springframework.web.context.request.WebRequestInterceptor;
//
//import javax.management.InvalidApplicationException;
//import javax.persistence.EntityManager;
//import javax.persistence.PersistenceContext;
//import javax.persistence.Tuple;
//import javax.persistence.criteria.CriteriaBuilder;
//import javax.persistence.criteria.CriteriaQuery;
//import javax.persistence.criteria.Root;
//import jakarta.persistence.EntityManager;
//import jakarta.persistence.PersistenceContext;
//import jakarta.persistence.Tuple;
//import jakarta.persistence.criteria.CriteriaBuilder;
//import jakarta.persistence.criteria.CriteriaQuery;
//import jakarta.persistence.criteria.Root;
//import java.time.Instant;
//import java.util.List;
//import java.util.UUID;

View File

@ -16,5 +16,6 @@ spring:
optional:classpath:config/cors.yml[.yml], optional:classpath:config/cors-${spring.profiles.active}.yml[.yml], optional:file:../config/cors-${spring.profiles.active}.yml[.yml],
optional:classpath:config/notification.yml[.yml], optional:classpath:config/notification-${spring.profiles.active}.yml[.yml], optional:file:../config/notification-${spring.profiles.active}.yml[.yml],
optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml],
optional:classpath:config/queue.yml[.yml], optional:classpath:config/queue-${spring.profiles.active}.yml[.yml], optional:file:../config/queue-${spring.profiles.active}.yml[.yml],
optional:classpath:config/cipher.yml[.yml], optional:classpath:config/cipher-${spring.profiles.active}.yml[.yml], optional:file:../config/cipher-${spring.profiles.active}.yml[.yml],
optional:classpath:config/formatting.yml[.yml], optional:classpath:config/formatting-${spring.profiles.active}.yml[.yml], optional:file:../config/formatting-${spring.profiles.active}.yml[.yml]

View File

@ -1,5 +1,6 @@
queue:
rabbitmq:
enable: true
durable: true
queue: cite_dmp_devel_notification_inbox_queue
exchange: cite_dmp_devel_queue
@ -7,11 +8,13 @@ queue:
publisherEnabled: true
task:
publisher:
enable: true
options:
exchange: cite_dmp_devel_queue
rabbitmq:
enable: true
listener:
enable: true
options:
exchange: cite_dmp_devel_queue
rabbitmq:

View File

@ -43,9 +43,9 @@ queue:
exchange: null
notify-topic: notification.notify
tenant-removal-topic: tenant.remove
tenant-touch-topic: tenant.touch
tenant-touched-topic: tenant.touch
user-removal-topic: user.remove
user-touch-topic: user.touch
user-touched-topic: user.touch
rabbitmq:
enable: false
interval-seconds: 30

View File

@ -16,5 +16,6 @@ spring:
optional:classpath:config/cors.yml[.yml], optional:classpath:config/cors-${spring.profiles.active}.yml[.yml], optional:file:../config/cors-${spring.profiles.active}.yml[.yml],
optional:classpath:config/notification.yml[.yml], optional:classpath:config/notification-${spring.profiles.active}.yml[.yml], optional:file:../config/notification-${spring.profiles.active}.yml[.yml],
optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml],
optional:classpath:config/queue.yml[.yml], optional:classpath:config/queue-${spring.profiles.active}.yml[.yml], optional:file:../config/queue-${spring.profiles.active}.yml[.yml],
optional:classpath:config/cipher.yml[.yml], optional:classpath:config/cipher-${spring.profiles.active}.yml[.yml], optional:file:../config/cipher-${spring.profiles.active}.yml[.yml],
optional:classpath:config/formatting.yml[.yml], optional:classpath:config/formatting-${spring.profiles.active}.yml[.yml], optional:file:../config/formatting-${spring.profiles.active}.yml[.yml]

View File

@ -1,5 +1,6 @@
queue:
rabbitmq:
enable: true
durable: true
queue: cite_dmp_devel_notification_inbox_queue
exchange: cite_dmp_devel_queue
@ -7,11 +8,13 @@ queue:
publisherEnabled: true
task:
publisher:
enable: true
options:
exchange: cite_dmp_devel_queue
rabbitmq:
enable: true
listener:
enable: true
options:
exchange: cite_dmp_devel_queue
rabbitmq:

View File

@ -43,9 +43,9 @@ queue:
exchange: null
notify-topic: notification.notify
tenant-removal-topic: tenant.remove
tenant-touch-topic: tenant.touch
tenant-touched-topic: tenant.touch
user-removal-topic: user.remove
user-touch-topic: user.touch
user-touched-topic: user.touch
rabbitmq:
enable: false
interval-seconds: 30

View File

@ -7,16 +7,17 @@
<groupId>gr.cite</groupId>
<artifactId>notification-service-parent</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
<relativePath>../../notification-service/pom.xml</relativePath>
</parent>
<artifactId>notification</artifactId>
<version>1.0.0</version>
<properties>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -45,16 +46,11 @@
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<!-- check if this is needed here or in tools-data -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>data-tools</artifactId>
<version>1.0.0</version>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
@ -84,16 +80,14 @@
<dependency>
<groupId>gr.cite</groupId>
<artifactId>validation</artifactId>
<version>1.0.0</version>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>cipher</artifactId>

View File

@ -10,10 +10,10 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.management.InvalidApplicationException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

View File

@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
@Component

View File

@ -1,10 +1,10 @@
package gr.cite.notification.common.types.tenant;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)

View File

@ -1,6 +1,6 @@
package gr.cite.notification.common.types.tenant;
import javax.xml.bind.annotation.*;
import jakarta.xml.bind.annotation.*;
import java.util.List;

View File

@ -1,6 +1,6 @@
package gr.cite.notification.common.types.tenant;
import javax.xml.bind.annotation.*;
import jakarta.xml.bind.annotation.*;
import java.util.List;

View File

@ -1,6 +1,6 @@
package gr.cite.notification.common.types.tenant;
import javax.xml.bind.annotation.*;
import jakarta.xml.bind.annotation.*;
import java.util.List;

View File

@ -1,7 +1,7 @@
package gr.cite.notification.common.validation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class EnumNotNull implements ConstraintValidator<ValidEnum,Object> {
@Override

View File

@ -1,8 +1,8 @@
package gr.cite.notification.common.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Constraint( validatedBy = { FieldNotNullIfOtherSetValidator.class } )

View File

@ -2,8 +2,8 @@ package gr.cite.notification.common.validation;
import org.springframework.beans.BeanWrapperImpl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Objects;
public class FieldNotNullIfOtherSetValidator implements ConstraintValidator<FieldNotNullIfOtherSet, Object> {

View File

@ -1,7 +1,7 @@
package gr.cite.notification.common.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

View File

@ -2,8 +2,8 @@ package gr.cite.notification.common.validation;
import org.springframework.beans.BeanWrapperImpl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class FieldsValueMatchValidator implements ConstraintValidator<FieldsValueMatch, Object> {

View File

@ -1,7 +1,7 @@
package gr.cite.notification.common.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

View File

@ -1,8 +1,8 @@
package gr.cite.notification.common.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Constraint( validatedBy = { ValidIdValidator.class } )

View File

@ -3,8 +3,8 @@ package gr.cite.notification.common.validation;
import gr.cite.notification.convention.ConventionService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.UUID;
public class ValidIdValidator implements ConstraintValidator<ValidId, Object> {

View File

@ -8,7 +8,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import javax.validation.Validator;
import jakarta.validation.Validator;
import java.util.List;
import java.util.Map;

View File

@ -1,11 +1,10 @@
package gr.cite.notification.config.email;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
@ConstructorBinding
@ConfigurationProperties(prefix = "email")
public class EmailProperties {
private final String address;
public EmailProperties(String address) {

View File

@ -1,38 +1,38 @@
package gr.cite.notification.config.formatting;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
@ConstructorBinding
@ConfigurationProperties(prefix = "formatting.options")
public class FormattingServiceProperties {
private final String integerFormat;
private final String decimalFormat;
private final String dateTimeFormat;
private final Integer decimalDigitsRound;
private final String integerFormat;
public FormattingServiceProperties(String integerFormat, String decimalFormat, String dateTimeFormat, Integer decimalDigitsRound) {
this.integerFormat = integerFormat;
this.decimalFormat = decimalFormat;
this.dateTimeFormat = dateTimeFormat;
this.decimalDigitsRound = decimalDigitsRound;
}
private final String decimalFormat;
public String getIntegerFormat() {
return integerFormat;
}
private final String dateTimeFormat;
public String getDecimalFormat() {
return decimalFormat;
}
private final Integer decimalDigitsRound;
public String getDateTimeFormat() {
return dateTimeFormat;
}
public FormattingServiceProperties(String integerFormat, String decimalFormat, String dateTimeFormat, Integer decimalDigitsRound) {
this.integerFormat = integerFormat;
this.decimalFormat = decimalFormat;
this.dateTimeFormat = dateTimeFormat;
this.decimalDigitsRound = decimalDigitsRound;
}
public Integer getDecimalDigitsRound() {
return decimalDigitsRound;
}
public String getIntegerFormat() {
return integerFormat;
}
public String getDecimalFormat() {
return decimalFormat;
}
public String getDateTimeFormat() {
return dateTimeFormat;
}
public Integer getDecimalDigitsRound() {
return decimalDigitsRound;
}
}

View File

@ -5,6 +5,7 @@ import gr.cite.notification.schedule.NotificationScheduleTask;
import gr.cite.notification.service.message.common.MessageBuilderBase;
import gr.cite.notification.service.notificationscheduling.NotificationSchedulingService;
import gr.cite.notification.service.notificationscheduling.NotificationSchedulingServiceImpl;
import gr.cite.queueinbox.task.rabbitmq.QueueListenerProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -32,11 +33,13 @@ public class NotificationConfig {
}
private final ApplicationContext applicationContext;
private final NotificationProperties properties;
private final QueueListenerProperties queueListenerProperties;
@Autowired
public NotificationConfig(ApplicationContext applicationContext, NotificationProperties properties) {
public NotificationConfig(ApplicationContext applicationContext, NotificationProperties properties, QueueListenerProperties queueListenerProperties) {
this.applicationContext = applicationContext;
this.properties = properties;
this.queueListenerProperties = queueListenerProperties;
}
@Bean(BeanQualifier.GLOBAL_POLICIES_MAP)

View File

@ -1,348 +1,385 @@
package gr.cite.notification.config.notification;
import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.common.enums.EmailOverrideMode;
import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.common.types.notification.FieldInfo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ConstructorBinding
@ConfigurationProperties(prefix = "notification")
public class NotificationProperties {
private final Task task;
private final Resolver resolver;
private final Map<String, Template> message;
private final Template overrideCache;
private final StaticFieldItems staticFields;
public NotificationProperties(Task task, Resolver resolver, Map<String, Template> message, Template overrideCache, StaticFieldItems staticFields) {
this.task = task;
this.resolver = resolver;
this.message = message;
this.overrideCache = overrideCache;
this.staticFields = staticFields;
}
public Task getTask() {
return task;
}
public Resolver getResolver() {
return resolver;
}
public Map<String, Template> getMessage() {
return message;
}
public Template getOverrideCache() {
return overrideCache;
}
public StaticFieldItems getStaticFields() {
return staticFields;
}
public static class Task {
private final Processor processor;
public Task(Processor processor) {
this.processor = processor;
}
public Processor getProcessor() {
return processor;
}
public static class Processor {
private final Boolean enable;
private final Long intervalSeconds;
private final Options options;
private final List<String> overrides;
public Processor(Boolean enable, Long intervalSeconds, Options options, List<String> overrides) {
this.enable = enable;
this.intervalSeconds = intervalSeconds;
this.options = options;
this.overrides = overrides;
}
public Boolean getEnable() {
return enable;
}
public Long getIntervalSeconds() {
return intervalSeconds;
}
public Options getOptions() {
return options;
}
public List<String> getOverrides() {
return overrides;
}
public static class Options {
private final Long retryThreshold;
private final Long maxRetryDelaySeconds;
private final Long tooOldToSendSeconds;
private final Long tooOldToTrackSeconds;
public Options(Long retryThreshold, Long maxRetryDelaySeconds, Long tooOldToSendSeconds, Long tooOldToTrackSeconds) {
this.retryThreshold = retryThreshold;
this.maxRetryDelaySeconds = maxRetryDelaySeconds;
this.tooOldToSendSeconds = tooOldToSendSeconds;
this.tooOldToTrackSeconds = tooOldToTrackSeconds;
}
public Long getRetryThreshold() {
return retryThreshold;
}
public Long getMaxRetryDelaySeconds() {
return maxRetryDelaySeconds;
}
public Long getTooOldToSendSeconds() {
return tooOldToSendSeconds;
}
public Long getTooOldToTrackSeconds() {
return tooOldToTrackSeconds;
}
}
}
}
public static class Resolver {
private final List<GlobalPolicy> globalPolicies;
public Resolver(List<GlobalPolicy> globalPolicies) {
this.globalPolicies = globalPolicies;
}
public List<GlobalPolicy> getGlobalPolicies() {
return globalPolicies;
}
public static class GlobalPolicy {
private final UUID type;
private final List<NotificationContactType> contacts;
public GlobalPolicy(UUID type, List<NotificationContactType> contacts) {
this.type = type;
this.contacts = contacts;
}
public UUID getType() {
return type;
}
public List<NotificationContactType> getContacts() {
return contacts;
}
}
}
public static class Template {
private final TemplateCache templateCache;
private final List<Flow> flows;
public Template(TemplateCache templateCache, List<Flow> flows) {
this.templateCache = templateCache;
this.flows = flows;
}
public TemplateCache getTemplateCache() {
return templateCache;
}
public List<Flow> getFlows() {
return flows;
}
public static class TemplateCache {
private final String prefix;
private final String keyPattern;
public TemplateCache(String prefix, String keyPattern) {
this.prefix = prefix;
this.keyPattern = keyPattern;
}
public String getPrefix() {
return prefix;
}
public String getKeyPattern() {
return keyPattern;
}
}
}
public static class StaticFieldItems {
private final List<Field> Fields;
public StaticFieldItems(List<Field> fields) {
Fields = fields;
}
public List<Field> getFields() {
return Fields;
}
}
public static class Field {
private final String key;
private final String type;
private final String value;
public Field(String key, String type, String value) {
this.key = key;
this.type = type;
this.value = value;
}
public String getKey() {
return key;
}
public String getType() {
return type;
}
public String getValue() {
return value;
}
}
public static class Flow {
private final UUID key;
private final String subjectPath;
private final String subjectKey;
private final FieldOption subjectFieldOptions;
private final String bodyPath;
private final String bodyKey;
private final FieldOption bodyFieldOptions;
private final List<String> cc;
private final EmailOverrideMode ccMode;
private final List<String> bcc;
private final EmailOverrideMode bccMode;
private final Boolean allowAttachments;
private final List<String> cipherFields;
private final String priorityKey;
private final List<String> extraDataKeys;
public Flow(UUID key, String subjectPath, String subjectKey, FieldOption subjectFieldOptions, String bodyPath, String bodyKey, FieldOption bodyFieldOptions, List<String> cc, EmailOverrideMode ccMode, List<String> bcc, EmailOverrideMode bccMode, Boolean allowAttachments, List<String> cipherFields, String priorityKey, List<String> extraDataKeys) {
this.key = key;
this.subjectPath = subjectPath;
this.subjectKey = subjectKey;
this.subjectFieldOptions = subjectFieldOptions;
this.bodyPath = bodyPath;
this.bodyKey = bodyKey;
this.bodyFieldOptions = bodyFieldOptions;
this.cc = cc;
this.ccMode = ccMode;
this.bcc = bcc;
this.bccMode = bccMode;
this.allowAttachments = allowAttachments;
this.cipherFields = cipherFields;
this.priorityKey = priorityKey;
this.extraDataKeys = extraDataKeys;
}
public UUID getKey() {
return key;
}
public String getSubjectPath() {
return subjectPath;
}
public String getSubjectKey() {
return subjectKey;
}
public FieldOption getSubjectFieldOptions() {
return subjectFieldOptions;
}
public String getBodyPath() {
return bodyPath;
}
public String getBodyKey() {
return bodyKey;
}
public FieldOption getBodyFieldOptions() {
return bodyFieldOptions;
}
public List<String> getCc() {
return cc;
}
public EmailOverrideMode getCcMode() {
return ccMode;
}
public List<String> getBcc() {
return bcc;
}
public EmailOverrideMode getBccMode() {
return bccMode;
}
public Boolean getAllowAttachments() {
return allowAttachments;
}
public List<String> getCipherFields() {
return cipherFields;
}
public String getPriorityKey() {
return priorityKey;
}
public List<String> getExtraDataKeys() {
return extraDataKeys;
}
public static class FieldOption {
private final List<String> mandatory;
private final List<FieldInfo> optional;
private final Map<String, String> formatting;
public FieldOption(List<String> mandatory, List<FieldInfo> optional, Map<String, String> formatting) {
this.mandatory = mandatory;
this.optional = optional;
this.formatting = formatting;
}
public List<String> getMandatory() {
return mandatory;
}
public List<FieldInfo> getOptional() {
return optional;
}
public Map<String, String> getFormatting() {
return formatting;
}
}
}
private final Task task;
private final Resolver resolver;
private final Map<String, Template> message;
private final Template overrideCache;
private final StaticFieldItems staticFields;
public NotificationProperties(Task task, Resolver resolver, Map<String, Template> message, Template overrideCache, StaticFieldItems staticFields) {
this.task = task;
this.resolver = resolver;
this.message = message;
this.overrideCache = overrideCache;
this.staticFields = staticFields;
}
public Task getTask() {
return task;
}
public Resolver getResolver() {
return resolver;
}
public Map<String, Template> getMessage() {
return message;
}
public Template getOverrideCache() {
return overrideCache;
}
public StaticFieldItems getStaticFields() {
return staticFields;
}
public static class Task {
private final Processor processor;
public Task(Processor processor) {
this.processor = processor;
}
public Processor getProcessor() {
return processor;
}
public static class Processor {
private final Boolean enable;
private final Long intervalSeconds;
private final Options options;
private final List<String> overrides;
public Processor(Boolean enable, Long intervalSeconds, Options options, List<String> overrides) {
this.enable = enable;
this.intervalSeconds = intervalSeconds;
this.options = options;
this.overrides = overrides;
}
public Boolean getEnable() {
return enable;
}
public Long getIntervalSeconds() {
return intervalSeconds;
}
public Options getOptions() {
return options;
}
public List<String> getOverrides() {
return overrides;
}
public static class Options {
private final Long retryThreshold;
private final Long maxRetryDelaySeconds;
private final Long tooOldToSendSeconds;
private final Long tooOldToTrackSeconds;
public Options(Long retryThreshold, Long maxRetryDelaySeconds, Long tooOldToSendSeconds, Long tooOldToTrackSeconds) {
this.retryThreshold = retryThreshold;
this.maxRetryDelaySeconds = maxRetryDelaySeconds;
this.tooOldToSendSeconds = tooOldToSendSeconds;
this.tooOldToTrackSeconds = tooOldToTrackSeconds;
}
public Long getRetryThreshold() {
return retryThreshold;
}
public Long getMaxRetryDelaySeconds() {
return maxRetryDelaySeconds;
}
public Long getTooOldToSendSeconds() {
return tooOldToSendSeconds;
}
public Long getTooOldToTrackSeconds() {
return tooOldToTrackSeconds;
}
}
}
}
public static class Resolver {
private final List<GlobalPolicy> globalPolicies;
public Resolver(List<GlobalPolicy> globalPolicies) {
this.globalPolicies = globalPolicies;
}
public List<GlobalPolicy> getGlobalPolicies() {
return globalPolicies;
}
public static class GlobalPolicy {
private final UUID type;
private final List<NotificationContactType> contacts;
public GlobalPolicy(UUID type, List<NotificationContactType> contacts) {
this.type = type;
this.contacts = contacts;
}
public UUID getType() {
return type;
}
public List<NotificationContactType> getContacts() {
return contacts;
}
}
}
public static class Template {
private final TemplateCache templateCache;
private final List<Flow> flows;
public Template(TemplateCache templateCache, List<Flow> flows) {
this.templateCache = templateCache;
this.flows = flows;
}
public TemplateCache getTemplateCache() {
return templateCache;
}
public List<Flow> getFlows() {
return flows;
}
public static class TemplateCache {
private final String prefix;
private final String keyPattern;
public TemplateCache(String prefix, String keyPattern) {
this.prefix = prefix;
this.keyPattern = keyPattern;
}
public String getPrefix() {
return prefix;
}
public String getKeyPattern() {
return keyPattern;
}
}
}
public static class StaticFieldItems {
private final List<Field> Fields;
public StaticFieldItems(List<Field> fields) {
Fields = fields;
}
public List<Field> getFields() {
return Fields;
}
}
public static class Field {
private final String key;
private final String type;
private final String value;
public Field(String key, String type, String value) {
this.key = key;
this.type = type;
this.value = value;
}
public String getKey() {
return key;
}
public String getType() {
return type;
}
public String getValue() {
return value;
}
}
public static class Flow {
private final UUID key;
private final String subjectPath;
private final String subjectKey;
private final FieldOption subjectFieldOptions;
private final String bodyPath;
private final String bodyKey;
private final FieldOption bodyFieldOptions;
private final List<String> cc;
private final EmailOverrideMode ccMode;
private final List<String> bcc;
private final EmailOverrideMode bccMode;
private final Boolean allowAttachments;
private final List<String> cipherFields;
private final String priorityKey;
private final List<String> extraDataKeys;
public Flow(UUID key, String subjectPath, String subjectKey, FieldOption subjectFieldOptions, String bodyPath, String bodyKey, FieldOption bodyFieldOptions, List<String> cc, EmailOverrideMode ccMode, List<String> bcc, EmailOverrideMode bccMode, Boolean allowAttachments, List<String> cipherFields, String priorityKey, List<String> extraDataKeys) {
this.key = key;
this.subjectPath = subjectPath;
this.subjectKey = subjectKey;
this.subjectFieldOptions = subjectFieldOptions;
this.bodyPath = bodyPath;
this.bodyKey = bodyKey;
this.bodyFieldOptions = bodyFieldOptions;
this.cc = cc;
this.ccMode = ccMode;
this.bcc = bcc;
this.bccMode = bccMode;
this.allowAttachments = allowAttachments;
this.cipherFields = cipherFields;
this.priorityKey = priorityKey;
this.extraDataKeys = extraDataKeys;
}
public UUID getKey() {
return key;
}
public String getSubjectPath() {
return subjectPath;
}
public String getSubjectKey() {
return subjectKey;
}
public FieldOption getSubjectFieldOptions() {
return subjectFieldOptions;
}
public String getBodyPath() {
return bodyPath;
}
public String getBodyKey() {
return bodyKey;
}
public FieldOption getBodyFieldOptions() {
return bodyFieldOptions;
}
public List<String> getCc() {
return cc;
}
public EmailOverrideMode getCcMode() {
return ccMode;
}
public List<String> getBcc() {
return bcc;
}
public EmailOverrideMode getBccMode() {
return bccMode;
}
public Boolean getAllowAttachments() {
return allowAttachments;
}
public List<String> getCipherFields() {
return cipherFields;
}
public String getPriorityKey() {
return priorityKey;
}
public List<String> getExtraDataKeys() {
return extraDataKeys;
}
public static class FieldOption {
private final List<String> mandatory;
private final List<FieldInfo> optional;
private final Map<String, String> formatting;
public FieldOption(List<String> mandatory, List<FieldInfo> optional, Map<String, String> formatting) {
this.mandatory = mandatory;
this.optional = optional;
this.formatting = formatting;
}
public List<String> getMandatory() {
return mandatory;
}
public List<FieldInfo> getOptional() {
return optional;
}
public Map<String, String> getFormatting() {
return formatting;
}
}
}
}

View File

@ -8,7 +8,7 @@ import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.conventers.NotificationInAppTrackingConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.*;
import gr.cite.notification.data.conventers.*;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.*;
import gr.cite.notification.data.conventers.*;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -5,7 +5,7 @@ import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.queueinbox.entity.QueueInbox;
import gr.cite.queueinbox.entity.QueueInboxStatus;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -6,7 +6,7 @@ import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.queueoutbox.entity.QueueOutbox;
import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -6,7 +6,7 @@ import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.conventers.TenantConfigurationTypeConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.conventers.IsActiveConverter;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -10,10 +10,10 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import jakarta.persistence.EntityManager;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import java.util.UUID;
@Service

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.ContactInfoType;
import gr.cite.notification.data.conventers.ContactInfoTypeConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.conventers.IsActiveConverter;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -5,7 +5,7 @@ import gr.cite.notification.data.composite.CompositeUserNotificationPreferenceId
import gr.cite.notification.data.conventers.NotificationContactTypeConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -2,7 +2,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.ContactInfoType;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class ContactInfoTypeConverter extends DatabaseEnumConverter<ContactInfoType, Short>{

View File

@ -1,8 +1,8 @@
package gr.cite.notification.data.conventers;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
@Converter
public abstract class DatabaseEnumConverter<EnumType extends DatabaseEnum<T>, T> implements AttributeConverter<EnumType, T> {

View File

@ -2,7 +2,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.InAppNotificationPriority;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class InAppNotificationPriorityConverter extends DatabaseEnumConverter<InAppNotificationPriority, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.IsActive;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class IsActiveConverter extends DatabaseEnumConverter<IsActive, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationContactType;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationContactTypeConverter extends DatabaseEnumConverter<NotificationContactType, Short> {

View File

@ -2,7 +2,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationInAppTracking;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationInAppTrackingConverter extends DatabaseEnumConverter<NotificationInAppTracking, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationNotifyState;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationNotifyStateConverter extends DatabaseEnumConverter<NotificationNotifyState, Short> {

View File

@ -4,7 +4,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTemplateChannel;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationTemplateChannelConverter extends DatabaseEnumConverter<NotificationTemplateChannel, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTemplateKind;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationTemplateKindConverter extends DatabaseEnumConverter<NotificationTemplateKind, Short> {

View File

@ -2,7 +2,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTrackingProcess;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationTrackingProcessConverter extends DatabaseEnumConverter<NotificationTrackingProcess, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTrackingState;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class NotificationTrackingStateConverter extends DatabaseEnumConverter<NotificationTrackingState, Short> {

View File

@ -3,7 +3,7 @@ package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.TenantConfigurationType;
import javax.persistence.Converter;
import jakarta.persistence.Converter;
@Converter
public class TenantConfigurationTypeConverter extends DatabaseEnumConverter<TenantConfigurationType, Short> {

View File

@ -12,7 +12,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.management.InvalidApplicationException;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
@Aspect
@Component

View File

@ -8,9 +8,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.management.InvalidApplicationException;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreRemove;
import jakarta.persistence.PreUpdate;
import java.util.UUID;
public class TenantListener {

View File

@ -5,9 +5,9 @@ import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.io.Serializable;
import java.util.UUID;
@ -15,17 +15,22 @@ import java.util.UUID;
//@Getter
//@Setter
//@NoArgsConstructor
@FilterDef(name = TenantScopedBaseEntity.tenantFilter, parameters = {@ParamDef(name = TenantScopedBaseEntity.tenantFilterTenantParam, type = "string")})
@FilterDef(name = TenantScopedBaseEntity.tenantFilter, parameters = {@ParamDef(name = TenantScopedBaseEntity.tenantFilterTenantParam, type = String.class)})
@Filter(name = "tenantFilter", condition = "tenant = (cast(:tenantId as uuid))")
@EntityListeners(TenantListener.class)
public abstract class TenantScopedBaseEntity implements TenantScoped, Serializable {
private static final long serialVersionUID = 1L;
public static final String tenantFilter = "tenantFilter";
public static final String tenantFilterTenantParam = "tenantId";
@Column(name = "tenant", columnDefinition = "uuid", nullable = true)
private UUID tenantId;
public static final String _tenantId = "tenantId";
public UUID getTenantId() {
return tenantId;
}

View File

@ -41,7 +41,7 @@ public class AppRabbitConfigurer extends RabbitConfigurer {
return new InboxBindings(bindingItems);
}
@Bean
@Bean(name = "InboxCreator")
public InboxCreator inboxCreator() {
return (params) -> {
InboxRepository inboxRepository = this.applicationContext.getBean(InboxRepository.class);

View File

@ -0,0 +1,34 @@
package gr.cite.notification.integrationevent;
import gr.cite.notification.integrationevent.inbox.InboxProperties;
import gr.cite.notification.integrationevent.inbox.InboxRepositoryImpl;
import gr.cite.queueinbox.InboxConfigurer;
import gr.cite.queueinbox.repository.InboxRepository;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@Configuration
@EnableConfigurationProperties({InboxProperties.class})
@ConditionalOnProperty(prefix = "queue.task.listener", name = "enable", matchIfMissing = false)
public class InboxIntegrationEventConfigurer extends InboxConfigurer {
private ApplicationContext applicationContext;
private InboxProperties inboxProperties;
public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) {
this.applicationContext = applicationContext;
this.inboxProperties = inboxProperties;
}
@Bean
public InboxRepository inboxRepositoryCreator() {
return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties);
}
}

View File

@ -0,0 +1,68 @@
package gr.cite.notification.integrationevent;
import gr.cite.notification.integrationevent.outbox.OutboxProperties;
import gr.cite.notification.integrationevent.outbox.OutboxRepositoryImpl;
import gr.cite.queueoutbox.IntegrationEventContextCreator;
import gr.cite.queueoutbox.OutboxConfigurer;
import gr.cite.queueoutbox.repository.OutboxRepository;
import gr.cite.rabbitmq.IntegrationEventMessageConstants;
import gr.cite.rabbitmq.RabbitProperties;
import gr.cite.rabbitmq.broker.MessageHydrator;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;
import java.util.UUID;
@Configuration
@EnableConfigurationProperties({OutboxProperties.class})
@ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false)
public class OutboxIntegrationEventConfigurer extends OutboxConfigurer {
private ApplicationContext applicationContext;
private OutboxProperties outboxProperties;
public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties) {
this.applicationContext = applicationContext;
this.outboxProperties = outboxProperties;
}
@Bean
public MessageHydrator messageHydrator(RabbitProperties rabbitProperties) {
return (message, event, eventContext) -> {
MessageProperties messageProperties = message.getMessageProperties();
messageProperties.setAppId(rabbitProperties.getAppId());
messageProperties.setContentEncoding(StandardCharsets.UTF_8.displayName());
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
//messageProperties.setUserId(userContext.getCurrentUser().toString());
messageProperties.setTimestamp(Date.from(Instant.now()));
messageProperties.setMessageId(event.getMessageId().toString());
if (eventContext != null) {
UUID tenant = ((IntegrationEventContextImpl) eventContext).getTenant();
if (tenant != null) {
messageProperties.setHeader(IntegrationEventMessageConstants.TENANT, tenant);
}
}
return message;
};
}
@Bean
public IntegrationEventContextCreator integrationEventContextCreator() {
return (message) -> new IntegrationEventContextImpl();
}
@Bean
public OutboxRepository outboxRepositoryCreator() {
return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties);
}
}

View File

@ -1,33 +1,22 @@
package gr.cite.notification.integrationevent.inbox;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
import java.util.List;
@Validated
@ConfigurationProperties(prefix = "queue.task.listener.options")
@ConstructorBinding
public class InboxProperties {
@NotNull
private final String exchange;
@NotNull
private final List<String> notifyTopic;
@NotNull
private final List<String> tenantRemovalTopic;
@NotNull
private final List<String> tenantTouchedTopic;
@NotNull
private final List<String> userRemovalTopic;
@NotNull
private final List<String> userTouchedTopic;
public InboxProperties(

View File

@ -0,0 +1,19 @@
package gr.cite.notification.integrationevent.outbox;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import gr.cite.notification.integrationevent.TrackedEvent;
import gr.cite.rabbitmq.IntegrationEvent;
@JsonIgnoreProperties(ignoreUnknown = true)
public class OutboxIntegrationEvent extends IntegrationEvent {
private TrackedEvent event;
public TrackedEvent getEvent() {
return event;
}
public void setEvent(TrackedEvent event) {
this.event = event;
}
}

View File

@ -1,60 +1,35 @@
package gr.cite.notification.integrationevent.outbox;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
@Validated
@ConfigurationProperties(prefix = "queue.task.publisher.options")
public class OutboxProperties {
@NotNull
private final String exchange;
@NotNull
private final String tenantTouchTopic;
@NotNull
private final String tenantRemovalTopic;
@NotNull
private final String tenantReactivationTopic;
private final String userTouchTopic;
@NotNull
private final String tenantUserInviteTopic;
private final String userRemovalTopic;
@NotNull
private final String notifyTopic;
@NotNull
private final String forgetMeCompletedTopic;
@NotNull
private final String whatYouKnowAboutMeCompletedTopic;
@NotNull
private final String generateFileTopic;
public OutboxProperties(String exchange,
String tenantTouchTopic,
String tenantRemovalTopic,
String tenantReactivationTopic,
String tenantUserInviteTopic,
String notifyTopic,
String forgetMeCompletedTopic,
String whatYouKnowAboutMeCompletedTopic,
String generateFileTopic
String userTouchTopic,
String userRemovalTopic,
String notifyTopic
) {
this.exchange = exchange;
this.tenantTouchTopic = tenantTouchTopic;
this.tenantRemovalTopic = tenantRemovalTopic;
this.tenantReactivationTopic = tenantReactivationTopic;
this.tenantUserInviteTopic = tenantUserInviteTopic;
this.userTouchTopic = userTouchTopic;
this.userRemovalTopic = userRemovalTopic;
this.notifyTopic = notifyTopic;
this.forgetMeCompletedTopic = forgetMeCompletedTopic;
this.whatYouKnowAboutMeCompletedTopic = whatYouKnowAboutMeCompletedTopic;
this.generateFileTopic = generateFileTopic;
}
public String getExchange() {
@ -69,27 +44,15 @@ public class OutboxProperties {
return tenantRemovalTopic;
}
public String getTenantReactivationTopic() {
return tenantReactivationTopic;
public String getUserTouchTopic() {
return userTouchTopic;
}
public String getTenantUserInviteTopic() {
return tenantUserInviteTopic;
public String getUserRemovalTopic() {
return userRemovalTopic;
}
public String getNotifyTopic() {
return notifyTopic;
}
public String getForgetMeCompletedTopic() {
return forgetMeCompletedTopic;
}
public String getWhatYouKnowAboutMeCompletedTopic() {
return whatYouKnowAboutMeCompletedTopic;
}
public String getGenerateFileTopic() {
return generateFileTopic;
}
}

View File

@ -0,0 +1,397 @@
package gr.cite.notification.integrationevent.outbox;
import gr.cite.notification.common.JsonHandlingService;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.scope.fake.FakeRequestScope;
import gr.cite.notification.data.QueueOutboxEntity;
import gr.cite.notification.query.QueueOutboxQuery;
import gr.cite.queueoutbox.entity.QueueOutbox;
import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus;
import gr.cite.queueoutbox.repository.CandidateInfo;
import gr.cite.queueoutbox.repository.OutboxRepository;
import gr.cite.queueoutbox.task.MessageOptions;
import gr.cite.rabbitmq.IntegrationEvent;
import gr.cite.tools.data.query.Ordering;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.logging.LoggerService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.OptimisticLockException;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
public class OutboxRepositoryImpl implements OutboxRepository {
protected final ApplicationContext applicationContext;
private final Random random = new Random();
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(OutboxRepositoryImpl.class));
private final JsonHandlingService jsonHandlingService;
private final OutboxProperties outboxProperties;
public OutboxRepositoryImpl(
ApplicationContext applicationContext,
OutboxProperties outboxProperties
) {
this.applicationContext = applicationContext;
this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class);
this.outboxProperties = outboxProperties;
}
@Override
public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions messageOptions, Function<QueueOutbox, Boolean> onConfirmTimeout) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
CandidateInfo candidate = null;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class)
.isActives(IsActive.Active)
.notifyStatus(QueueOutboxNotifyStatus.PENDING, QueueOutboxNotifyStatus.WAITING_CONFIRMATION, QueueOutboxNotifyStatus.ERROR)
.retryThreshold(messageOptions.getRetryThreashold())
.confirmTimeout(messageOptions.getConfirmTimeoutSeconds())
.createdAfter(lastCandidateCreationTimestamp)
.ordering(new Ordering().addAscending(QueueOutboxEntity._createdAt))
.first();
if (item != null) {
boolean confirmTimeout = onConfirmTimeout.apply(item);
QueueOutboxNotifyStatus prevState = item.getNotifyStatus();
item.setNotifyStatus(QueueOutboxNotifyStatus.PROCESSING);
entityManager.merge(item);
entityManager.flush();
candidate = new CandidateInfo();
candidate.setId(item.getId());
candidate.setCreatedAt(item.getCreatedAt());
candidate.setPreviousState(prevState);
}
transaction.commit();
} catch (OptimisticLockException ex) {
// we get this if/when someone else already modified the notifications. We want to essentially ignore this, and keep working
logger.debug("Concurrency exception getting queue outbox. Skipping: {} ", ex.getMessage());
if (transaction != null) transaction.rollback();
candidate = null;
} catch (Exception ex) {
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
if (transaction != null) transaction.rollback();
candidate = null;
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
}
return candidate;
}
@Override
public Boolean shouldOmit(CandidateInfo candidate, Function<QueueOutbox, Boolean> shouldOmit) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
boolean success = false;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class).ids(candidate.getId()).first();
if (item == null) {
logger.warn("Could not lookup queue outbox {} to process. Continuing...", candidate.getId());
} else {
if (shouldOmit.apply(item)) {
item.setNotifyStatus(QueueOutboxNotifyStatus.OMITTED);
entityManager.merge(item);
entityManager.flush();
success = true;
}
}
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
success = false;
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
return success;
}
@Override
public Boolean shouldWait(CandidateInfo candidate, Function<QueueOutbox, Boolean> itIsTimeFunc) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
boolean success = false;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class).ids(candidate.getId()).first();
if (item.getRetryCount() != null && item.getRetryCount() >= 1) {
Boolean itIsTime = itIsTimeFunc.apply(item);
if (!itIsTime) {
item.setNotifyStatus(candidate.getPreviousState());
entityManager.merge(item);
entityManager.flush();
success = true;
}
success = !itIsTime;
}
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
success = false;
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
return success;
}
@Override
public Boolean process(CandidateInfo candidateInfo, Boolean isAutoconfirmOnPublish, Function<QueueOutbox, Boolean> publish) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
Boolean success = false;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class).ids(candidateInfo.getId()).first();
if (item == null) {
logger.warn("Could not lookup queue outbox {} to process. Continuing...", candidateInfo.getId());
} else {
success = publish.apply(item);
if (success) {
if (isAutoconfirmOnPublish) {
item.setNotifyStatus(QueueOutboxNotifyStatus.CONFIRMED);
item.setConfirmedAt(Instant.now());
} else {
item.setNotifyStatus(QueueOutboxNotifyStatus.WAITING_CONFIRMATION);
}
item.setPublishedAt(Instant.now());
} else {
item.setNotifyStatus(QueueOutboxNotifyStatus.ERROR);
item.setRetryCount(item.getRetryCount() != null ? item.getRetryCount() + 1 : 0);
item.setPublishedAt(null);
}
entityManager.merge(item);
entityManager.flush();
}
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
success = false;
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
return success;
}
@Override
public void handleConfirm(List<UUID> confirmedMessages) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
List<QueueOutboxEntity> queueOutboxMessages = queryFactory.query(QueueOutboxQuery.class).ids(confirmedMessages).collect();
if (queueOutboxMessages == null) {
logger.warn("Could not lookup messages {} to process. Continuing...", String.join(",", confirmedMessages.stream().map(x -> x.toString()).collect(Collectors.toList())));
} else {
for (QueueOutboxEntity queueOutboxMessage : queueOutboxMessages) {
queueOutboxMessage.setNotifyStatus(QueueOutboxNotifyStatus.CONFIRMED);
queueOutboxMessage.setConfirmedAt(Instant.now());
entityManager.merge(queueOutboxMessage);
}
entityManager.flush();
}
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
}
@Override
public void handleNack(List<UUID> nackedMessages) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class);
List<QueueOutboxEntity> queueOutboxMessages = queryFactory.query(QueueOutboxQuery.class).ids(nackedMessages).collect();
if (queueOutboxMessages == null) {
logger.warn("Could not lookup messages {} to process. Continuing...", String.join(",", nackedMessages.stream().map(x -> x.toString()).collect(Collectors.toList())));
} else {
for (QueueOutboxEntity queueOutboxMessage : queueOutboxMessages) {
queueOutboxMessage.setNotifyStatus(QueueOutboxNotifyStatus.ERROR);
queueOutboxMessage.setRetryCount(queueOutboxMessage.getRetryCount() != null ? queueOutboxMessage.getRetryCount() + 1 : 0);
entityManager.merge(queueOutboxMessage);
}
entityManager.flush();
}
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
}
@Override
public QueueOutbox create(IntegrationEvent item) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
boolean success = false;
QueueOutboxEntity queueMessage = null;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
queueMessage = this.mapEvent((OutboxIntegrationEvent) item);
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(queueMessage);
entityManager.flush();
transaction.commit();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
if (transaction != null) transaction.rollback();
success = false;
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
return queueMessage;
}
private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) {
String routingKey;
switch (event.getType()) {
default: {
logger.error("unrecognized outgoing integration event {}. Skipping...", event.getType());
return null;
}
}
// UUID correlationId = UUID.randomUUID();
// if (event.getEvent() != null) event.getEvent().setTrackingContextTag(correlationId.toString());
// event.setMessage(this.jsonHandlingService.toJsonSafe(event.getEvent()));
// //this._logTrackingService.Trace(correlationId.ToString(), $"Correlating current tracking context with new correlationId {correlationId}");
//
// QueueOutboxEntity queueMessage = new QueueOutboxEntity();
// queueMessage.setId(UUID.randomUUID());
// queueMessage.setTenantId(null);
// queueMessage.setExchange(this.outboxProperties.getExchange());
// queueMessage.setRoute(routingKey);
// queueMessage.setMessageId(event.getMessageId());
// queueMessage.setMessage(this.jsonHandlingService.toJsonSafe(event));
// queueMessage.setIsActive(IsActive.Active);
// queueMessage.setNotifyStatus(QueueOutboxNotifyStatus.PENDING);
// queueMessage.setRetryCount(0);
// queueMessage.setCreatedAt(Instant.now());
// queueMessage.setUpdatedAt(Instant.now());
//
// return queueMessage;
}
}

View File

@ -5,7 +5,7 @@ import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationInAppTracking;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;
public class InAppNotification {

View File

@ -5,8 +5,8 @@ import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.conventers.NotificationTrackingProcessConverter;
import gr.cite.notification.data.conventers.NotificationTrackingStateConverter;
import javax.persistence.Column;
import javax.persistence.Convert;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.data.composite.CompositeUserNotificationPreferenceId;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;

View File

@ -4,7 +4,7 @@ import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.common.enums.NotificationNotifyState;
import gr.cite.notification.common.validation.ValidId;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import java.util.UUID;

View File

@ -6,8 +6,8 @@ import gr.cite.notification.common.validation.ValidEnum;
import gr.cite.notification.common.validation.ValidId;
import gr.cite.notification.model.persist.notificationtemplate.NotificationTemplateValuePersist;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.UUID;
public class NotificationTemplatePersist {

View File

@ -2,9 +2,9 @@ package gr.cite.notification.model.persist;
import gr.cite.notification.common.validation.ValidId;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.UUID;
public class TenantTouchedIntegrationEventPersist {

View File

@ -5,8 +5,8 @@ import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.validation.FieldNotNullIfOtherSet;
import gr.cite.notification.common.validation.ValidId;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import java.util.UUID;

View File

@ -2,9 +2,9 @@ package gr.cite.notification.model.persist;
import gr.cite.notification.common.validation.ValidId;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.UUID;
public class UserTouchedIntegrationEventPersist {

View File

@ -3,8 +3,8 @@ package gr.cite.notification.model.persist.notificationtemplate;
import gr.cite.notification.common.enums.NotificationDataType;
import gr.cite.notification.common.validation.ValidEnum;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
public class FieldInfoPersist {

View File

@ -1,7 +1,7 @@
package gr.cite.notification.model.persist.notificationtemplate;
import javax.validation.Valid;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;

View File

@ -3,9 +3,9 @@ package gr.cite.notification.model.persist.notificationtemplate;
import gr.cite.notification.common.enums.EmailOverrideMode;
import gr.cite.notification.common.validation.ValidEnum;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;
public class NotificationTemplateValuePersist {

View File

@ -1,9 +1,10 @@
package gr.cite.notification.query;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.*;
import gr.cite.notification.common.enums.InAppNotificationPriority;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationInAppTracking;
import gr.cite.notification.data.InAppNotificationEntity;
import gr.cite.notification.data.LanguageEntity;
import gr.cite.notification.model.InAppNotification;
import gr.cite.tools.data.query.FieldResolver;
import gr.cite.tools.data.query.QueryBase;
@ -12,8 +13,8 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -11,9 +11,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -12,8 +12,8 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -12,10 +12,10 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Subquery;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Subquery;
import java.time.Instant;
import java.util.*;
@ -198,9 +198,8 @@ public class NotificationTemplateQuery extends QueryBase<NotificationTemplateEnt
}
if (this.languageQuery != null) {
Subquery<LanguageEntity> subQuery = queryContext.Query.subquery(this.languageQuery.entityClass());
this.applySubQuery(this.languageQuery, queryContext.CriteriaBuilder, subQuery);
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._languageId)).value(subQuery));
QueryContext<LanguageEntity, UUID> subQuery = this.applySubQuery(this.languageQuery, queryContext, UUID.class, root -> root.get(NotificationTemplateEntity._id));
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._languageId)).value(subQuery.Query));
}
if (this.channels != null) {

View File

@ -11,9 +11,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -12,9 +12,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -12,9 +12,9 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -11,8 +11,8 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -17,10 +17,10 @@ import gr.cite.tools.data.query.QueryContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Subquery;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Subquery;
import java.time.Instant;
import java.util.*;
@ -226,12 +226,11 @@ public class UserContactInfoQuery extends QueryBase<UserContactInfoEntity> {
predicates.add(inClause);
}
if (this.userQuery != null) {
Subquery<UserEntity> subQuery = queryContext.Query.subquery(this.userQuery.entityClass());
this.applySubQuery(this.userQuery, queryContext.CriteriaBuilder, subQuery);
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._userId)).value(subQuery));
QueryContext<UserEntity, UUID> subQuery = this.applySubQuery(this.userQuery, queryContext, UUID.class, root -> root.get(UserContactInfoEntity._userId));
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._userId)).value(subQuery.Query));
}
if (predicates.size() > 0) {
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {

View File

@ -13,9 +13,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

View File

@ -10,8 +10,8 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.Predicate;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;

Some files were not shown because too many files have changed in this diff Show More