Resolving issues with notification service user integration (on user creation)
This commit is contained in:
parent
2ba9e146e5
commit
8f7a3cf768
|
@ -14,6 +14,8 @@ public class UserTouchedIntegrationEvent extends TrackedEvent {
|
|||
|
||||
private String name;
|
||||
|
||||
private String subjectId;
|
||||
|
||||
private UserProfile profile;
|
||||
|
||||
private List<UserContactInfo> userContactInfo;
|
||||
|
@ -42,6 +44,14 @@ public class UserTouchedIntegrationEvent extends TrackedEvent {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSubjectId() {
|
||||
return subjectId;
|
||||
}
|
||||
|
||||
public void setSubjectId(String subjectId) {
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
public UserProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
|
|
@ -62,10 +62,15 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
List<UserContactInfoEntity> userContactInfoEntities = this.queryFactory.query(UserContactInfoQuery.class).userIds(userId)
|
||||
.collectAs(new BaseFieldSet().ensure(UserContactInfo._type).ensure(UserContactInfo._ordinal).ensure(UserContactInfo._value));
|
||||
|
||||
List<UserCredentialEntity> userCredentialEntities = this.queryFactory.query(UserCredentialQuery.class).userIds(userId)
|
||||
.collectAs(new BaseFieldSet().ensure(UserCredential._id, UserCredential._externalId));
|
||||
|
||||
UserTouchedIntegrationEvent event = new UserTouchedIntegrationEvent();
|
||||
event.setId(userId);
|
||||
event.setTenant(null); //TODO
|
||||
event.setName(user.getName());
|
||||
if (userCredentialEntities != null && !userCredentialEntities.isEmpty())
|
||||
event.setSubjectId(userCredentialEntities.getFirst().getExternalId());
|
||||
event.setProfile(new UserTouchedIntegrationEvent.UserProfile());
|
||||
AdditionalInfoEntity definition = this.jsonHandlingService.fromJsonSafe(AdditionalInfoEntity.class, user.getAdditionalInfo());
|
||||
if (definition != null) {
|
||||
|
|
|
@ -170,6 +170,7 @@ permissions:
|
|||
BrowseInAppNotification:
|
||||
roles:
|
||||
- Admin
|
||||
- User
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
|
|
|
@ -323,6 +323,7 @@ public class InboxRepositoryImpl implements InboxRepository {
|
|||
|
||||
private EventProcessingStatus processMessage(String routingKey, String messageId, String appId, String message) {
|
||||
IntegrationEventHandler handler;
|
||||
logger.debug("Processing message with routing key '{}'", routingKey);
|
||||
if (this.routingKeyMatched(routingKey, this.inboxProperties.getNotifyTopic()))
|
||||
handler = this.applicationContext.getBean(NotifyIntegrationEventHandler.class);
|
||||
else if (this.routingKeyMatched(routingKey, this.inboxProperties.getTenantRemovalTopic()))
|
||||
|
@ -333,8 +334,10 @@ public class InboxRepositoryImpl implements InboxRepository {
|
|||
handler = this.applicationContext.getBean(UserRemovalIntegrationEventHandler.class);
|
||||
else if (this.routingKeyMatched(routingKey, this.inboxProperties.getUserTouchedTopic()))
|
||||
handler = this.applicationContext.getBean(UserTouchedIntegrationEventHandler.class);
|
||||
else
|
||||
else {
|
||||
logger.error("No handler found for message routing key '{}'. Discarding.", routingKey);
|
||||
handler = null;
|
||||
}
|
||||
|
||||
if (handler == null)
|
||||
return EventProcessingStatus.Discard;
|
||||
|
|
|
@ -67,7 +67,7 @@ public class NotifyIntegrationEventHandlerImpl implements NotifyIntegrationEvent
|
|||
if (event.getUserId() == null) {
|
||||
throw new MyValidationException(this.errors.getModelValidation().getCode(), "userId", messageSource.getMessage("Validation_Required", new Object[]{"userId"}, LocaleContextHolder.getLocale()));
|
||||
}
|
||||
logger.debug("Handling NotifyIntegrationEvent");
|
||||
logger.debug("Handling {}", NotifyIntegrationEvent.class.getSimpleName());
|
||||
|
||||
NotificationPersist model = new NotificationPersist();
|
||||
model.setType(event.getNotificationType());
|
||||
|
|
|
@ -67,6 +67,8 @@ public class UserRemovalIntegrationEventHandlerImpl implements UserRemovalIntegr
|
|||
if (event.getUserId() == null)
|
||||
throw new MyValidationException(this.errors.getModelValidation().getCode(), "userId", messageSource.getMessage("Validation_Required", new Object[]{"userId"}, LocaleContextHolder.getLocale()));
|
||||
|
||||
logger.debug("Handling {}", UserRemovalIntegrationEvent.class.getSimpleName());
|
||||
|
||||
EntityManager entityManager = null;
|
||||
EntityTransaction transaction = null;
|
||||
try (FakeRequestScope ignored = new FakeRequestScope()) {
|
||||
|
@ -134,6 +136,6 @@ public class UserRemovalIntegrationEventHandlerImpl implements UserRemovalIntegr
|
|||
} catch (Exception ex) {
|
||||
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
|
||||
}
|
||||
return null;
|
||||
return EventProcessingStatus.Success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,43 @@
|
|||
package gr.cite.notification.integrationevent.inbox.usertouched;
|
||||
|
||||
import gr.cite.notification.common.enums.ContactInfoType;
|
||||
import gr.cite.notification.common.validation.BaseValidator;
|
||||
import gr.cite.notification.convention.ConventionService;
|
||||
import gr.cite.notification.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.notification.integrationevent.TrackedEvent;
|
||||
import gr.cite.notification.model.persist.UserTouchedIntegrationEventPersist;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserTouchedIntegrationEvent extends TrackedEvent {
|
||||
|
||||
private UUID id;
|
||||
|
||||
public static final String _id = "id";
|
||||
|
||||
private UUID tenant;
|
||||
|
||||
private String firstName;
|
||||
private String name;
|
||||
|
||||
private String lastName;
|
||||
public static final String _name = "name";
|
||||
|
||||
public static final int _nameLength = 200;
|
||||
|
||||
private String subjectId;
|
||||
|
||||
public static final String _subjectId = "subjectId";
|
||||
|
||||
private UserProfile profile;
|
||||
|
||||
private List<UserContactInfo> userContactInfo;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
|
@ -30,19 +55,140 @@ public class UserTouchedIntegrationEvent extends TrackedEvent {
|
|||
this.tenant = tenant;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
public String getSubjectId() {
|
||||
return subjectId;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
public void setSubjectId(String subjectId) {
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
public UserProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setProfile(UserProfile profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public List<UserContactInfo> getUserContactInfo() {
|
||||
return userContactInfo;
|
||||
}
|
||||
|
||||
public void setUserContactInfo(List<UserContactInfo> userContactInfo) {
|
||||
this.userContactInfo = userContactInfo;
|
||||
}
|
||||
|
||||
public static class UserProfile {
|
||||
|
||||
private String timezone;
|
||||
|
||||
private String culture;
|
||||
|
||||
private String language;
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public String getCulture() {
|
||||
return culture;
|
||||
}
|
||||
|
||||
public void setCulture(String culture) {
|
||||
this.culture = culture;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserContactInfo {
|
||||
|
||||
private ContactInfoType type;
|
||||
|
||||
private String value;
|
||||
|
||||
private int ordinal;
|
||||
|
||||
public ContactInfoType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(ContactInfoType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getOrdinal() {
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
public void setOrdinal(int ordinal) {
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
@Component(UserTouchedIntegrationEvent.UserTouchedIntegrationEventValidator.ValidatorName)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public static class UserTouchedIntegrationEventValidator extends BaseValidator<UserTouchedIntegrationEvent> {
|
||||
|
||||
public static final String ValidatorName = "UserTouchedIntegrationEventValidator";
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
protected UserTouchedIntegrationEventValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
|
||||
super(conventionService, errors);
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserTouchedIntegrationEvent> modelClass() {
|
||||
return UserTouchedIntegrationEvent.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Specification> specifications(UserTouchedIntegrationEvent item) {
|
||||
return Arrays.asList(
|
||||
this.spec()
|
||||
.iff(() -> !this.isNull(item.getId()))
|
||||
.must(() -> this.isValidGuid(item.getId()))
|
||||
.failOn(UserTouchedIntegrationEvent._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEvent._id}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isEmpty(item.getName()))
|
||||
.failOn(UserTouchedIntegrationEvent._name).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEvent._name}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> !this.isEmpty(item.getName()))
|
||||
.must(() -> this.lessEqualLength(item.getName(), UserTouchedIntegrationEventPersist._nameLength))
|
||||
.failOn(UserTouchedIntegrationEvent._name).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{UserTouchedIntegrationEvent._name}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isEmpty(item.getSubjectId()))
|
||||
.failOn(UserTouchedIntegrationEvent._subjectId).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEvent._subjectId}, LocaleContextHolder.getLocale()))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import gr.cite.notification.integrationevent.inbox.EventProcessingStatus;
|
|||
import gr.cite.notification.integrationevent.inbox.InboxPrincipal;
|
||||
import gr.cite.notification.integrationevent.inbox.IntegrationEventProperties;
|
||||
import gr.cite.notification.model.Tenant;
|
||||
import gr.cite.notification.model.persist.UserTouchedIntegrationEventPersist;
|
||||
import gr.cite.notification.query.TenantQuery;
|
||||
import gr.cite.notification.service.user.UserService;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
|
@ -40,8 +39,8 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
protected final ApplicationContext applicationContext;
|
||||
|
||||
private final JsonHandlingService jsonHandlingService;
|
||||
private final ValidatorFactory validatorFactory;
|
||||
|
||||
private final ValidatorFactory validatorFactory;
|
||||
|
||||
public UserTouchedIntegrationEventHandlerImpl(
|
||||
JsonHandlingService jsonHandlingService,
|
||||
|
@ -58,11 +57,9 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
if (event == null)
|
||||
return EventProcessingStatus.Error;
|
||||
|
||||
UserTouchedIntegrationEventPersist model = new UserTouchedIntegrationEventPersist();
|
||||
model.setId(event.getId());
|
||||
model.setFirstName(event.getFirstName());
|
||||
model.setLastName(event.getLastName());
|
||||
this.validatorFactory.validator(UserTouchedIntegrationEventPersist.UserTouchedIntegrationEventPersistValidator.class).validateForce(model);
|
||||
logger.debug("Handling {}", UserTouchedIntegrationEvent.class.getSimpleName());
|
||||
|
||||
this.validatorFactory.validator(UserTouchedIntegrationEvent.UserTouchedIntegrationEventValidator.class).validateForce(event);
|
||||
|
||||
EntityManager entityManager = null;
|
||||
EntityTransaction transaction = null;
|
||||
|
@ -96,12 +93,12 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
|
||||
try {
|
||||
UserService userService = this.applicationContext.getBean(UserService.class);
|
||||
userService.persist(model, null);
|
||||
userService.persist(event, null);
|
||||
|
||||
AuditService auditService = this.applicationContext.getBean(AuditService.class);
|
||||
|
||||
auditService.track(AuditableAction.User_Persist, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", model)
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", event)
|
||||
));
|
||||
|
||||
transaction.commit();
|
||||
|
@ -111,8 +108,6 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
} finally {
|
||||
currentPrincipalResolver.pop();
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -129,6 +124,6 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
} catch (Exception ex) {
|
||||
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
|
||||
}
|
||||
return null;
|
||||
return EventProcessingStatus.Success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import gr.cite.notification.common.validation.BaseValidator;
|
|||
|
||||
import gr.cite.notification.convention.ConventionService;
|
||||
import gr.cite.notification.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.notification.integrationevent.inbox.usertouched.UserTouchedIntegrationEvent;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
|
@ -20,14 +21,11 @@ public class UserTouchedIntegrationEventPersist {
|
|||
private UUID id;
|
||||
public static final String _id = "id";
|
||||
|
||||
private String firstName;
|
||||
public static final String _firstName = "firstName";
|
||||
public static final int _firstNameLength = 200;
|
||||
private String name;
|
||||
|
||||
private String lastName;
|
||||
public static final String _lastName = "lastName";
|
||||
public static final int _lastNameLength = 200;
|
||||
public static final String _name = "name";
|
||||
|
||||
public static final int _nameLength = 200;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
|
@ -37,20 +35,12 @@ public class UserTouchedIntegrationEventPersist {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Component(UserTouchedIntegrationEventPersist.UserTouchedIntegrationEventPersistValidator.ValidatorName)
|
||||
|
@ -77,21 +67,14 @@ public class UserTouchedIntegrationEventPersist {
|
|||
this.spec()
|
||||
.iff(() -> !this.isNull(item.getId()))
|
||||
.must(() -> this.isValidGuid(item.getId()))
|
||||
.failOn(UserTouchedIntegrationEventPersist._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEventPersist._id}, LocaleContextHolder.getLocale())),
|
||||
.failOn(UserTouchedIntegrationEvent._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEventPersist._id}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isEmpty(item.getFirstName()))
|
||||
.failOn(UserTouchedIntegrationEventPersist._firstName).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEventPersist._firstName}, LocaleContextHolder.getLocale())),
|
||||
.must(() -> !this.isEmpty(item.getName()))
|
||||
.failOn(UserTouchedIntegrationEvent._name).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEventPersist._name}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> !this.isEmpty(item.getFirstName()))
|
||||
.must(() -> this.lessEqualLength(item.getFirstName(), UserTouchedIntegrationEventPersist._firstNameLength))
|
||||
.failOn(UserTouchedIntegrationEventPersist._firstName).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{UserTouchedIntegrationEventPersist._firstName}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isEmpty(item.getLastName()))
|
||||
.failOn(UserTouchedIntegrationEventPersist._lastName).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserTouchedIntegrationEventPersist._lastName}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> !this.isEmpty(item.getLastName()))
|
||||
.must(() -> this.lessEqualLength(item.getLastName(), UserTouchedIntegrationEventPersist._lastNameLength))
|
||||
.failOn(UserTouchedIntegrationEventPersist._lastName).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{UserTouchedIntegrationEventPersist._lastName}, LocaleContextHolder.getLocale()))
|
||||
.iff(() -> !this.isEmpty(item.getName()))
|
||||
.must(() -> this.lessEqualLength(item.getName(), UserTouchedIntegrationEvent._nameLength))
|
||||
.failOn(UserTouchedIntegrationEvent._name).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{UserTouchedIntegrationEventPersist._name}, LocaleContextHolder.getLocale()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package gr.cite.notification.service.user;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import gr.cite.notification.integrationevent.inbox.usertouched.UserTouchedIntegrationEvent;
|
||||
import gr.cite.notification.model.User;
|
||||
import gr.cite.notification.model.persist.UserTouchedIntegrationEventPersist;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
|
@ -14,7 +15,7 @@ import java.util.UUID;
|
|||
|
||||
public interface UserService {
|
||||
|
||||
User persist(UserTouchedIntegrationEventPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException;
|
||||
User persist(UserTouchedIntegrationEvent model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException;
|
||||
|
||||
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException;
|
||||
|
||||
|
|
|
@ -8,13 +8,17 @@ import gr.cite.notification.authorization.Permission;
|
|||
import gr.cite.notification.common.JsonHandlingService;
|
||||
import gr.cite.notification.common.enums.IsActive;
|
||||
import gr.cite.notification.convention.ConventionService;
|
||||
import gr.cite.notification.data.UserContactInfoEntity;
|
||||
import gr.cite.notification.data.UserCredentialEntity;
|
||||
import gr.cite.notification.data.UserEntity;
|
||||
import gr.cite.notification.integrationevent.inbox.usertouched.UserTouchedIntegrationEvent;
|
||||
import gr.cite.notification.model.User;
|
||||
import gr.cite.notification.model.builder.UserBuilder;
|
||||
import gr.cite.notification.model.deleter.UserDeleter;
|
||||
import gr.cite.notification.model.persist.UserTouchedIntegrationEventPersist;
|
||||
import gr.cite.notification.query.UserContactInfoQuery;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
|
@ -24,16 +28,13 @@ import gr.cite.tools.fieldset.FieldSet;
|
|||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.time.Instant;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
@ -50,23 +51,32 @@ public class UserServiceImpl implements UserService {
|
|||
|
||||
private final BuilderFactory builderFactory;
|
||||
|
||||
private final QueryFactory queryFactory;
|
||||
|
||||
private final JsonHandlingService jsonHandlingService;
|
||||
|
||||
public UserServiceImpl(AuthorizationService authorizationService,
|
||||
DeleterFactory deleterFactory,
|
||||
ConventionService conventionService,
|
||||
EntityManager entityManager,
|
||||
BuilderFactory builderFactory) {
|
||||
BuilderFactory builderFactory,
|
||||
QueryFactory queryFactory,
|
||||
JsonHandlingService jsonHandlingService) {
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
this.conventionService = conventionService;
|
||||
this.entityManager = entityManager;
|
||||
this.builderFactory = builderFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.jsonHandlingService = jsonHandlingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User persist(UserTouchedIntegrationEventPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
|
||||
@Transactional
|
||||
public User persist(UserTouchedIntegrationEvent model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
|
||||
logger.debug(new MapLogEntry("persisting user").And("model", model).And("fields", fields));
|
||||
|
||||
this.authorizationService.authorizeAtLeastOneForce(model.getId() != null ? List.of(new OwnedResource(model.getId())) : null, Permission.EditUser);
|
||||
// this.authorizationService.authorizeAtLeastOneForce(model.getId() != null ? List.of(new OwnedResource(model.getId())) : null, Permission.EditUser);
|
||||
|
||||
Boolean isValid = this.conventionService.isValidGuid(model.getId());
|
||||
|
||||
|
@ -76,18 +86,73 @@ public class UserServiceImpl implements UserService {
|
|||
if (data == null) {
|
||||
data = new UserEntity();
|
||||
data.setId(model.getId());
|
||||
data.setName(model.getFirstName() + " " + model.getLastName());
|
||||
data.setName(model.getName());
|
||||
data.setAdditionalInfo(this.jsonHandlingService.toJson(model.getProfile()));
|
||||
data.setCreatedAt(Instant.now());
|
||||
data.setUpdatedAt(Instant.now());
|
||||
data.setIsActive(IsActive.Active);
|
||||
|
||||
this.entityManager.persist(data);
|
||||
|
||||
for (UserTouchedIntegrationEvent.UserContactInfo eventC : model.getUserContactInfo()) {
|
||||
this.entityManager.persist(this.buildContactInfoEntityFromEventData(eventC, model.getId()));
|
||||
}
|
||||
|
||||
this.entityManager.persist(this.buildUserCredentialEntityFromEventData(model));
|
||||
} else {
|
||||
data.setName(model.getFirstName() + " " + model.getLastName());
|
||||
data.setName(model.getName());
|
||||
data.setAdditionalInfo(this.jsonHandlingService.toJson(model.getProfile()));
|
||||
data.setUpdatedAt(Instant.now());
|
||||
data.setIsActive(IsActive.Active);
|
||||
|
||||
this.entityManager.merge(data);
|
||||
|
||||
List<UserContactInfoEntity> contactInfoList = this.queryFactory.query(UserContactInfoQuery.class).userIds(model.getId()).collect();
|
||||
|
||||
List<UserContactInfoEntity> updatedContacts = new ArrayList<>();
|
||||
for (UserContactInfoEntity c : contactInfoList) {
|
||||
boolean updated = false;
|
||||
|
||||
//Contact found on the existing, update it
|
||||
for (UserTouchedIntegrationEvent.UserContactInfo eventC : model.getUserContactInfo()) {
|
||||
if (c.getType() == eventC.getType() && Objects.equals(c.getValue(), eventC.getValue())) {
|
||||
c.setUserId(model.getId());
|
||||
c.setType(c.getType());
|
||||
c.setValue(c.getValue());
|
||||
c.setOrdinal(c.getOrdinal());
|
||||
c.setUpdatedAt(Instant.now());
|
||||
c.setIsActive(IsActive.Active);
|
||||
|
||||
this.entityManager.merge(c);
|
||||
|
||||
updatedContacts.add(c);
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Contact was not found on the event data, remove it
|
||||
if (!updated) {
|
||||
c.setIsActive(IsActive.Inactive);
|
||||
this.entityManager.merge(c);
|
||||
}
|
||||
}
|
||||
|
||||
for (UserTouchedIntegrationEvent.UserContactInfo eventC : model.getUserContactInfo()) {
|
||||
boolean updated = false;
|
||||
for (UserContactInfoEntity c : updatedContacts) {
|
||||
if (c.getType() == eventC.getType() && Objects.equals(c.getValue(), eventC.getValue())) {
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//New contact detected since it came with the event data and was not existing in the database, add it
|
||||
if (!updated) {
|
||||
this.entityManager.persist(this.buildContactInfoEntityFromEventData(eventC, model.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
throw new MyApplicationException("Not valid user id");
|
||||
|
@ -107,4 +172,30 @@ public class UserServiceImpl implements UserService {
|
|||
this.deleterFactory.deleter(UserDeleter.class).deleteAndSaveByIds(List.of(id));
|
||||
}
|
||||
|
||||
private UserContactInfoEntity buildContactInfoEntityFromEventData(UserTouchedIntegrationEvent.UserContactInfo eventC, UUID userId) {
|
||||
UserContactInfoEntity contactInfo = new UserContactInfoEntity();
|
||||
contactInfo.setId(UUID.randomUUID());
|
||||
contactInfo.setUserId(userId);
|
||||
contactInfo.setType(eventC.getType());
|
||||
contactInfo.setValue(eventC.getValue());
|
||||
contactInfo.setOrdinal(eventC.getOrdinal());
|
||||
contactInfo.setCreatedAt(Instant.now());
|
||||
contactInfo.setUpdatedAt(Instant.now());
|
||||
contactInfo.setIsActive(IsActive.Active);
|
||||
|
||||
return contactInfo;
|
||||
}
|
||||
|
||||
private UserCredentialEntity buildUserCredentialEntityFromEventData(UserTouchedIntegrationEvent event) {
|
||||
UserCredentialEntity credentialEntity = new UserCredentialEntity();
|
||||
credentialEntity.setId(UUID.randomUUID());
|
||||
credentialEntity.setUserId(event.getId());
|
||||
credentialEntity.setExternalId(event.getSubjectId());
|
||||
credentialEntity.setCreatedAt(Instant.now());
|
||||
credentialEntity.setUpdatedAt(Instant.now());
|
||||
credentialEntity.setIsActive(IsActive.Active);
|
||||
|
||||
return credentialEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue