-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DST-16098 Send Domain Event when username is changed #797
Changes from 4 commits
d79b9f6
92fc5e0
47d5a35
2843043
396895d
da3e43a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package uk.co.bconline.ndelius.model.entity; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
|
||
@Getter | ||
@Entity | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Table(name = "DOMAIN_EVENT") | ||
public class DomainEventEntity | ||
{ | ||
@Id | ||
@Column(name = "DOMAIN_EVENT_ID") | ||
@SequenceGenerator(name = "DOMAIN_EVENT_ID_SEQ", sequenceName = "DOMAIN_EVENT_ID_SEQ", allocationSize = 1) | ||
@GeneratedValue(generator = "DOMAIN_EVENT_ID_SEQ") | ||
private Long id; | ||
|
||
@Column(name = "MESSAGE_BODY") | ||
private String messageBody; | ||
|
||
@Column(name = "MESSAGE_ATTRIBUTES") | ||
private String messageAttributes; | ||
|
||
@ManyToOne() | ||
@JoinColumn(name = "DOMAIN_EVENT_TYPE_ID", insertable = false, updatable = false) | ||
private ReferenceDataEntity domainEventType; | ||
|
||
@Column(name = "DOMAIN_EVENT_TYPE_ID") | ||
private Long domainEventTypeId; | ||
|
||
@Column(name = "CREATED_DATETIME") | ||
private LocalDateTime createdDateTime; | ||
|
||
@Column(name = "FAILED_PUBLISHING") | ||
private Boolean failedPublishing; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package uk.co.bconline.ndelius.model.notification; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
public class DomainEvent | ||
{ | ||
private Long id; | ||
private String messageBody; | ||
private String messageAttributes; | ||
private Long domainEventTypeId; | ||
private LocalDateTime createdDateTime; | ||
private Boolean failedPublishing; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package uk.co.bconline.ndelius.model.notification; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.Map; | ||
|
||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
public class HmppsDomainEvent | ||
{ | ||
private String eventType; | ||
private int version; | ||
private String description; | ||
private String occurredAt; | ||
private Map<String, String> additionalInformation; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package uk.co.bconline.ndelius.model.notification; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public enum HmppsDomainEventType | ||
{ | ||
UMT_USERNAME_CHANGED("probation-user.username.changed", "The username for a probation user has been changed"); | ||
|
||
private final String eventType; | ||
private final String eventDescription; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package uk.co.bconline.ndelius.repository.db; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import uk.co.bconline.ndelius.model.entity.DomainEventEntity; | ||
|
||
public interface DomainEventRepository extends JpaRepository<DomainEventEntity, Long> | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package uk.co.bconline.ndelius.service; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import uk.co.bconline.ndelius.model.notification.HmppsDomainEventType; | ||
|
||
import java.util.Map; | ||
|
||
public interface DomainEventService | ||
{ | ||
void insertDomainEvent(HmppsDomainEventType eventType, Map<String, String> attributes) throws JsonProcessingException; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package uk.co.bconline.ndelius.service.impl; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import lombok.extern.slf4j.Slf4j; | ||
import lombok.val; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
import uk.co.bconline.ndelius.model.entity.DomainEventEntity; | ||
import uk.co.bconline.ndelius.model.notification.HmppsDomainEvent; | ||
import uk.co.bconline.ndelius.model.notification.HmppsDomainEventType; | ||
import uk.co.bconline.ndelius.repository.db.DomainEventRepository; | ||
import uk.co.bconline.ndelius.repository.db.ReferenceDataRepository; | ||
import uk.co.bconline.ndelius.service.DomainEventService; | ||
|
||
import java.time.LocalDateTime; | ||
import java.time.ZonedDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Map; | ||
|
||
@Slf4j | ||
@Service | ||
public class DomainEventServiceImpl implements DomainEventService | ||
{ | ||
private final ReferenceDataRepository referenceDataRepository; | ||
|
||
private final DomainEventRepository domainEventRepository; | ||
|
||
private final ObjectMapper mapper; | ||
|
||
private static final String DOMAIN_EVENT_TYPE_REF_DATA_CODE_SET = "DOMAIN EVENT TYPE"; | ||
|
||
@Autowired | ||
public DomainEventServiceImpl( | ||
ReferenceDataRepository referenceDataRepository, | ||
DomainEventRepository domainEventRepository, | ||
ObjectMapper mapper) { | ||
this.referenceDataRepository = referenceDataRepository; | ||
this.domainEventRepository = domainEventRepository; | ||
this.mapper = mapper; | ||
} | ||
|
||
@Override | ||
public void insertDomainEvent(HmppsDomainEventType eventType, Map<String, String> additionalInformation) throws JsonProcessingException | ||
{ | ||
val type = referenceDataRepository.findByCodeAndReferenceDataMasterCodeSetName(eventType.getEventType(), DOMAIN_EVENT_TYPE_REF_DATA_CODE_SET) | ||
.orElseThrow(() -> new IllegalStateException("Reference data for domain event type " + eventType.getEventType() + " not found")); | ||
val message = HmppsDomainEvent.builder() | ||
.eventType(eventType.getEventType()) | ||
.description(eventType.getEventDescription()) | ||
.occurredAt(ZonedDateTime.now().format(DateTimeFormatter.ISO_ZONED_DATE_TIME)) | ||
.additionalInformation(additionalInformation) | ||
.version(1) | ||
.build(); | ||
val attributes = Map.of("eventType", Map.of("Type", "String", "Value", eventType.getEventType())); | ||
val entity = DomainEventEntity.builder() | ||
.messageBody(mapper.writeValueAsString(message)) | ||
.messageAttributes(mapper.writeValueAsString(attributes)) | ||
.domainEventTypeId(type.getId()) | ||
.createdDateTime(LocalDateTime.now()) | ||
.build(); | ||
|
||
domainEventRepository.save(entity); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||||||
package uk.co.bconline.ndelius.service.impl; | ||||||||||
|
||||||||||
import com.fasterxml.jackson.core.JsonProcessingException; | ||||||||||
import com.google.common.collect.Sets; | ||||||||||
import lombok.extern.slf4j.Slf4j; | ||||||||||
import lombok.val; | ||||||||||
|
@@ -20,15 +21,18 @@ | |||||||||
import uk.co.bconline.ndelius.model.entry.UserEntry; | ||||||||||
import uk.co.bconline.ndelius.model.entry.UserPreferencesEntry; | ||||||||||
import uk.co.bconline.ndelius.model.entry.projections.UserHomeAreaProjection; | ||||||||||
import uk.co.bconline.ndelius.model.notification.HmppsDomainEventType; | ||||||||||
import uk.co.bconline.ndelius.repository.ldap.UserEntryRepository; | ||||||||||
import uk.co.bconline.ndelius.repository.ldap.UserPreferencesRepository; | ||||||||||
import uk.co.bconline.ndelius.service.DomainEventService; | ||||||||||
import uk.co.bconline.ndelius.service.GroupService; | ||||||||||
import uk.co.bconline.ndelius.service.UserEntryService; | ||||||||||
import uk.co.bconline.ndelius.service.UserRoleService; | ||||||||||
import uk.co.bconline.ndelius.transformer.SearchResultTransformer; | ||||||||||
import uk.co.bconline.ndelius.util.SearchUtils; | ||||||||||
|
||||||||||
import javax.naming.Name; | ||||||||||
import java.util.HashMap; | ||||||||||
import java.util.List; | ||||||||||
import java.util.Map; | ||||||||||
import java.util.Optional; | ||||||||||
|
@@ -68,6 +72,7 @@ public class UserEntryServiceImpl implements UserEntryService, UserDetailsServic | |||||||||
private final LdapTemplate ldapTemplate; | ||||||||||
private final LdapTemplate exportLdapTemplate; | ||||||||||
private final SearchResultTransformer searchResultTransformer; | ||||||||||
private final DomainEventService domainEventService; | ||||||||||
|
||||||||||
@Autowired | ||||||||||
public UserEntryServiceImpl( | ||||||||||
|
@@ -77,14 +82,16 @@ public UserEntryServiceImpl( | |||||||||
GroupService groupService, | ||||||||||
LdapTemplate ldapTemplate, | ||||||||||
@Qualifier("exportLdapTemplate") LdapTemplate exportLdapTemplate, | ||||||||||
SearchResultTransformer searchResultTransformer) { | ||||||||||
SearchResultTransformer searchResultTransformer, | ||||||||||
DomainEventService domainEventService) { | ||||||||||
this.userRepository = userRepository; | ||||||||||
this.preferencesRepository = preferencesRepository; | ||||||||||
this.userRoleService = userRoleService; | ||||||||||
this.groupService = groupService; | ||||||||||
this.ldapTemplate = ldapTemplate; | ||||||||||
this.exportLdapTemplate = exportLdapTemplate; | ||||||||||
this.searchResultTransformer = searchResultTransformer; | ||||||||||
this.domainEventService = domainEventService; | ||||||||||
} | ||||||||||
|
||||||||||
@Override | ||||||||||
|
@@ -253,7 +260,8 @@ public void save(UserEntry user) { | |||||||||
} | ||||||||||
|
||||||||||
@Override | ||||||||||
public void save(String existingUsername, UserEntry user) { | ||||||||||
public void save(String existingUsername, UserEntry user) throws JsonProcessingException | ||||||||||
{ | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry - could we annotate
Suggested change
|
||||||||||
// Keep hold of the new username, if it's different we'll rename it later | ||||||||||
val newUsername = user.getUsername(); | ||||||||||
user.setUsername(existingUsername); | ||||||||||
|
@@ -267,6 +275,13 @@ public void save(String existingUsername, UserEntry user) { | |||||||||
val newDn = LdapNameBuilder.newInstance(getDn(newUsername)).build(); | ||||||||||
log.debug("Renaming LDAP entry from {} to {}", oldDn, newDn); | ||||||||||
ldapTemplate.rename(oldDn, newDn); | ||||||||||
|
||||||||||
// Send Domain event | ||||||||||
val additionalInformation = Map.of( | ||||||||||
"fromUsername", existingUsername, | ||||||||||
"toUsername", newUsername | ||||||||||
); | ||||||||||
domainEventService.insertDomainEvent(HmppsDomainEventType.UMT_USERNAME_CHANGED, additionalInformation); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package uk.co.bconline.ndelius.transformer; | ||
|
||
import org.springframework.stereotype.Component; | ||
import uk.co.bconline.ndelius.model.entity.DomainEventEntity; | ||
import uk.co.bconline.ndelius.model.notification.DomainEvent; | ||
|
||
import static java.util.Optional.ofNullable; | ||
|
||
@Component | ||
public class DomainEventTransformer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we delete this class now? |
||
{ | ||
public DomainEventEntity map(DomainEvent domainEvent) | ||
{ | ||
return ofNullable(domainEvent) | ||
.map(de -> DomainEventEntity.builder() | ||
.messageBody(de.getMessageBody()) | ||
.messageAttributes(de.getMessageAttributes()) | ||
.domainEventTypeId(de.getDomainEventTypeId()) | ||
.createdDateTime(de.getCreatedDateTime()) | ||
.failedPublishing(de.getFailedPublishing()) | ||
.build()) | ||
.orElse(null); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we delete this now too?