diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserService.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserService.java index 3b92ef44a..83d49f609 100644 --- a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserService.java +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserService.java @@ -31,9 +31,14 @@ public class DeleteInactiveSessionsAndUserService { private final @NonNull SessionRepository sessionRepository; private final @NonNull DeleteUserAccountService deleteUserAccountService; private final @NonNull WorkflowErrorMailService workflowErrorMailService; + private final @NonNull WorkflowErrorLogService workflowErrorLogService; private final @NonNull DeleteSessionService deleteSessionService; private final @NonNull InactivePrivateGroupsProvider inactivePrivateGroupsProvider; + private static final String USER_NOT_FOUND_REASON = "User could not be found."; + private static final String RC_SESSION_GROUP_NOT_FOUND_REASON = + "Session with rc group id could not be found."; + /** * Deletes all inactive sessions and even the asker accounts, if there are no more active * sessions. @@ -49,15 +54,28 @@ public void deleteInactiveSessionsAndUsers() { .flatMap(Collection::stream) .collect(Collectors.toList()); - sendWorkflowErrorsMail(workflowErrors); + findWorkflowErrorByReason(workflowErrors); } - private void sendWorkflowErrorsMail(List workflowErrors) { + private void findWorkflowErrorByReason(List workflowErrors) { if (isNotEmpty(workflowErrors)) { - this.workflowErrorMailService.buildAndSendErrorMail(workflowErrors); + List rcSessionGroupNotFoundWorkflowErrors = + getSameReasonWorkflowErrors(workflowErrors, RC_SESSION_GROUP_NOT_FOUND_REASON); + List workflowErrorsExceptSessionGroupNotFound = + new ArrayList<>(workflowErrors); + workflowErrorsExceptSessionGroupNotFound.removeAll(rcSessionGroupNotFoundWorkflowErrors); + this.workflowErrorLogService.logWorkflowErrors(rcSessionGroupNotFoundWorkflowErrors); + this.workflowErrorMailService.buildAndSendErrorMail(workflowErrorsExceptSessionGroupNotFound); } } + private static List getSameReasonWorkflowErrors( + List workflowErrors, String reason) { + return workflowErrors.stream() + .filter(error -> reason.equals(error.getReason())) + .collect(Collectors.toList()); + } + private List performDeletionWorkflow( Entry> userInactiveGroupEntry) { @@ -73,7 +91,7 @@ private List performDeletionWorkflow( .deletionSourceType(ASKER) .deletionTargetType(ALL) .identifier(userInactiveGroupEntry.getKey()) - .reason("User could not be found.") + .reason(USER_NOT_FOUND_REASON) .timestamp(nowInUtc()) .build())); @@ -115,7 +133,7 @@ private List performSessionDeletion( .deletionSourceType(ASKER) .deletionTargetType(ALL) .identifier(rcGroupId) - .reason("Session with rc group id could not be found.") + .reason(RC_SESSION_GROUP_NOT_FOUND_REASON) .timestamp(nowInUtc()) .build())); diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogService.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogService.java new file mode 100644 index 000000000..3960b4525 --- /dev/null +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogService.java @@ -0,0 +1,35 @@ +package de.caritas.cob.userservice.api.workflow.delete.service; + +import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; + +import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** Service class to log all deletion workflow errors. */ +@Slf4j +@Service +@RequiredArgsConstructor +public class WorkflowErrorLogService { + + public void logWorkflowErrors(List workflowErrors) { + if (isNotEmpty(workflowErrors)) { + workflowErrors.forEach( + workflowError -> + log.warn( + "Errors during deletion workflow:" + + " SourceType = {}; " + + "TargetType = {}; " + + "Identifier = {}; " + + "Reason = {}; " + + "Timestamp = {}.", + workflowError.getDeletionSourceType(), + workflowError.getDeletionTargetType(), + workflowError.getIdentifier(), + workflowError.getReason(), + workflowError.getTimestamp())); + } + } +} diff --git a/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserServiceTest.java b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserServiceTest.java index 625cad2c1..92b1a151e 100644 --- a/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserServiceTest.java +++ b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteInactiveSessionsAndUserServiceTest.java @@ -1,7 +1,10 @@ package de.caritas.cob.userservice.api.workflow.delete.service; -import static org.mockito.ArgumentMatchers.any; +import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc; +import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionSourceType.ASKER; +import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionTargetType.ALL; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +34,7 @@ public class DeleteInactiveSessionsAndUserServiceTest { @InjectMocks private DeleteInactiveSessionsAndUserService deleteInactiveSessionsAndUserService; @Mock private WorkflowErrorMailService workflowErrorMailService; + @Mock private WorkflowErrorLogService workflowErrorLogService; @Mock private UserRepository userRepository; @Mock private SessionRepository sessionRepository; @Mock private DeleteUserAccountService deleteUserAccountService; @@ -38,7 +42,8 @@ public class DeleteInactiveSessionsAndUserServiceTest { @Mock private InactivePrivateGroupsProvider inactivePrivateGroupsProvider; @Test - public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { + public void + deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail_When_userNotFoundReason() { EasyRandom easyRandom = new EasyRandom(); User user = easyRandom.nextObject(User.class); @@ -60,7 +65,9 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers(); - verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any()); + verify(workflowErrorLogService, Mockito.times(1)).logWorkflowErrors(Collections.emptyList()); + verify(workflowErrorMailService, Mockito.times(1)) + .buildAndSendErrorMail(argThat(list -> !list.isEmpty())); } @Test @@ -115,7 +122,7 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { @Test public void - deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorMail_WhenUserHasActiveAndInactiveSessionsAndHasErrors() { + deleteInactiveSessionsAndUsers_Should_logWorkflowErrorMail_WhenUserHasActiveAndInactiveSessionsAndHasErrors() { EasyRandom easyRandom = new EasyRandom(); User user = easyRandom.nextObject(User.class); @@ -132,18 +139,28 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { when(userRepository.findByRcUserIdAndDeleteDateIsNull(anyString())) .thenReturn(Optional.of(user)); when(sessionRepository.findByUser(user)).thenReturn(Arrays.asList(session1, session2)); - DeletionWorkflowError deletionWorkflowError = Mockito.mock(DeletionWorkflowError.class); + DeletionWorkflowError deletionWorkflowError = + DeletionWorkflowError.builder() + .deletionSourceType(ASKER) + .deletionTargetType(ALL) + .identifier(null) + .reason("Session with rc group id could not be found.") + .timestamp(nowInUtc()) + .build(); when(deleteSessionService.performSessionDeletion(session1)) .thenReturn(Collections.singletonList(deletionWorkflowError)); deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers(); - verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any()); + verify(workflowErrorLogService, Mockito.times(1)) + .logWorkflowErrors(argThat(list -> !list.isEmpty())); + verify(workflowErrorMailService, Mockito.times(1)) + .buildAndSendErrorMail(Collections.emptyList()); } @Test public void - deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorMail_WhenSessionCouldNotBeFound() { + deleteInactiveSessionsAndUsers_Should_logWorkflowErrorMail_WhenSessionCouldNotBeFound() { EasyRandom easyRandom = new EasyRandom(); User user = easyRandom.nextObject(User.class); @@ -164,7 +181,10 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers(); - verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any()); + verify(workflowErrorLogService, Mockito.times(1)) + .logWorkflowErrors(argThat(list -> !list.isEmpty())); + verify(workflowErrorMailService, Mockito.times(1)) + .buildAndSendErrorMail(Collections.emptyList()); } @Test @@ -187,6 +207,8 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() { deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers(); - verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any()); + verify(workflowErrorLogService, Mockito.times(1)).logWorkflowErrors(Collections.emptyList()); + verify(workflowErrorMailService, Mockito.times(1)) + .buildAndSendErrorMail(argThat(list -> !list.isEmpty())); } } diff --git a/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogServiceTest.java b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogServiceTest.java new file mode 100644 index 000000000..43274c0e5 --- /dev/null +++ b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/service/WorkflowErrorLogServiceTest.java @@ -0,0 +1,76 @@ +package de.caritas.cob.userservice.api.workflow.delete.service; + +import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc; +import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionSourceType.ASKER; +import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionTargetType.ROCKET_CHAT; +import static java.util.Collections.emptyList; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError; +import java.util.ArrayList; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class WorkflowErrorLogServiceTest { + + @InjectMocks private WorkflowErrorLogService workflowErrorLogService; + + private ListAppender listAppender; + + @Before + public void setUp() { + Logger logger = (Logger) LoggerFactory.getLogger(WorkflowErrorLogService.class); + listAppender = new ListAppender<>(); + listAppender.start(); + logger.addAppender(listAppender); + } + + @Test + public void logWorkflowErrors_Should_logNoErrors_When_workflowErrorsAreNull() { + + // when + this.workflowErrorLogService.logWorkflowErrors(null); + + // then + Assertions.assertThat(listAppender.list).isEmpty(); + } + + @Test + public void logWorkflowErrors_Should_logNoErrors_When_workflowErrorsAreEmpty() { + + // when + this.workflowErrorLogService.logWorkflowErrors(emptyList()); + + // then + Assertions.assertThat(listAppender.list).isEmpty(); + } + + @Test + public void logWorkflowErrors_Should_logErrors_When_workflowErrorsExists() { + // given + List workflowErrors = new ArrayList<>(); + workflowErrors.add( + DeletionWorkflowError.builder() + .deletionSourceType(ASKER) + .deletionTargetType(ROCKET_CHAT) + .timestamp(nowInUtc()) + .reason("reason") + .identifier("id") + .build()); + + // when + this.workflowErrorLogService.logWorkflowErrors(workflowErrors); + + // then + Assertions.assertThat(listAppender.list).hasSize(1); + } +}