From d5a003014d8a5f78a50230d55f2b8b76064589c1 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 27 Sep 2024 11:28:06 +0200 Subject: [PATCH 1/4] fix: deletion routine changes --- .../rocketchat/RocketChatService.java | 13 ++-- .../SessionTopicEnrichmentService.java | 2 +- .../asker/DeleteRoomsAndSessionAction.java | 8 ++- .../action/asker/DeleteSingleRoomAction.java | 59 +++++++++++++++++++ .../RocketchatRoomDeletionWorkflowDTO.java | 13 ++++ .../DeleteInactiveSessionsAndUserService.java | 7 ++- .../delete/service/DeleteSessionService.java | 19 ++++++ 7 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomAction.java create mode 100644 src/main/java/de/caritas/cob/userservice/api/workflow/delete/model/RocketchatRoomDeletionWorkflowDTO.java diff --git a/src/main/java/de/caritas/cob/userservice/api/adapters/rocketchat/RocketChatService.java b/src/main/java/de/caritas/cob/userservice/api/adapters/rocketchat/RocketChatService.java index 1bd8d764d..703634e23 100644 --- a/src/main/java/de/caritas/cob/userservice/api/adapters/rocketchat/RocketChatService.java +++ b/src/main/java/de/caritas/cob/userservice/api/adapters/rocketchat/RocketChatService.java @@ -136,6 +136,8 @@ public class RocketChatService implements MessageClient { private static final String USER_LIST_GET_FIELD_SELECTION = "{\"_id\":1}"; private static final Integer PAGE_SIZE = 100; private static final String ERROR_ROOM_NOT_FOUND = "error-room-not-found"; + private static final String COULD_NOT_REMOVE_USER_FROM_ROCKET_CHAT_GROUP = + "Could not remove user %s from Rocket.Chat group with id %s"; private final LocalDateTime localDateTime1900 = LocalDateTime.of(1900, 1, 1, 0, 0); private final LocalDateTime localDateTimeFuture = nowInUtc().plusYears(1L); @@ -662,12 +664,11 @@ public void removeUserFromGroup(String rcUserId, String rcGroupId) rcGroupId, ex); throw new RocketChatRemoveUserFromGroupException( - String.format( - "Could not remove user %s from Rocket.Chat group with id %s", rcUserId, rcGroupId)); + String.format(COULD_NOT_REMOVE_USER_FROM_ROCKET_CHAT_GROUP, rcUserId, rcGroupId)); } if (response != null && !response.isSuccess()) { - var error = "Could not remove user %s from Rocket.Chat group with id %s"; + var error = COULD_NOT_REMOVE_USER_FROM_ROCKET_CHAT_GROUP; throw new RocketChatRemoveUserFromGroupException(String.format(error, rcUserId, rcGroupId)); } } @@ -802,6 +803,7 @@ public List getChatUsers(String chatId) { * @return al members of the group * @deprecated use getChatUsers */ + @Deprecated public List getMembersOfGroup(String rcGroupId) throws RocketChatGetGroupMembersException { @@ -1365,12 +1367,11 @@ public void removeUserFromGroupIgnoreGroupNotFound(String rcUserId, String rcGro rcGroupId, ex); throw new RocketChatRemoveUserFromGroupException( - String.format( - "Could not remove user %s from Rocket.Chat group with id %s", rcUserId, rcGroupId)); + String.format(COULD_NOT_REMOVE_USER_FROM_ROCKET_CHAT_GROUP, rcUserId, rcGroupId)); } if (response != null && !response.isSuccess()) { - var error = "Could not remove user %s from Rocket.Chat group with id %s"; + var error = COULD_NOT_REMOVE_USER_FROM_ROCKET_CHAT_GROUP; throw new RocketChatRemoveUserFromGroupException(String.format(error, rcUserId, rcGroupId)); } } diff --git a/src/main/java/de/caritas/cob/userservice/api/service/session/SessionTopicEnrichmentService.java b/src/main/java/de/caritas/cob/userservice/api/service/session/SessionTopicEnrichmentService.java index 691039828..2f9ae43c0 100644 --- a/src/main/java/de/caritas/cob/userservice/api/service/session/SessionTopicEnrichmentService.java +++ b/src/main/java/de/caritas/cob/userservice/api/service/session/SessionTopicEnrichmentService.java @@ -39,7 +39,7 @@ private boolean shouldEnrichTopic(SessionDTO session) { } private void enrichSession(Map availableTopics, SessionDTO sessionDTO) { - var topicData = availableTopics.get(Long.valueOf(sessionDTO.getTopic().getId())); + var topicData = availableTopics.get(sessionDTO.getTopic().getId()); if (topicData != null) { log.debug("Enriching session with id {} with topicData {}", sessionDTO.getId(), topicData); sessionDTO.setTopic(convertToSessionTopicDTO(topicData)); diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteRoomsAndSessionAction.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteRoomsAndSessionAction.java index 0aa2df8d3..a94184e00 100644 --- a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteRoomsAndSessionAction.java +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteRoomsAndSessionAction.java @@ -20,6 +20,8 @@ @RequiredArgsConstructor abstract class DeleteRoomsAndSessionAction { + private static final String USER_SERVICE_DELETE_WORKFLOW_ERROR = + "UserService delete workflow error: "; protected final @NonNull SessionRepository sessionRepository; protected final @NonNull SessionDataRepository sessionDataRepository; protected final @NonNull RocketChatService rocketChatService; @@ -29,7 +31,7 @@ void deleteRocketChatGroup(String rcGroupId, List workflo try { this.rocketChatService.deleteGroupAsTechnicalUser(rcGroupId); } catch (RocketChatDeleteGroupException e) { - log.error("UserService delete workflow error: ", e); + log.error(USER_SERVICE_DELETE_WORKFLOW_ERROR, e); workflowErrors.add( DeletionWorkflowError.builder() .deletionSourceType(ASKER) @@ -47,7 +49,7 @@ void deleteSessionData(Session session, List workflowErro var sessionData = this.sessionDataRepository.findBySessionId(session.getId()); this.sessionDataRepository.deleteAll(sessionData); } catch (Exception e) { - log.error("UserService delete workflow error: ", e); + log.error(USER_SERVICE_DELETE_WORKFLOW_ERROR, e); workflowErrors.add( DeletionWorkflowError.builder() .deletionSourceType(ASKER) @@ -63,7 +65,7 @@ protected void deleteSession(Session session, List workfl try { this.sessionRepository.delete(session); } catch (Exception e) { - log.error("UserService delete workflow error: ", e); + log.error(USER_SERVICE_DELETE_WORKFLOW_ERROR, e); workflowErrors.add( DeletionWorkflowError.builder() .deletionSourceType(ASKER) diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomAction.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomAction.java new file mode 100644 index 000000000..c8284d8cc --- /dev/null +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomAction.java @@ -0,0 +1,59 @@ +package de.caritas.cob.userservice.api.workflow.delete.action.asker; + +import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc; +import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionSourceType.ASKER; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import de.caritas.cob.userservice.api.actions.ActionCommand; +import de.caritas.cob.userservice.api.adapters.rocketchat.RocketChatService; +import de.caritas.cob.userservice.api.exception.rocketchat.RocketChatDeleteGroupException; +import de.caritas.cob.userservice.api.model.Session; +import de.caritas.cob.userservice.api.workflow.delete.model.DeletionTargetType; +import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError; +import de.caritas.cob.userservice.api.workflow.delete.model.RocketchatRoomDeletionWorkflowDTO; +import de.caritas.cob.userservice.api.workflow.delete.model.SessionDeletionWorkflowDTO; +import java.util.List; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class DeleteSingleRoomAction implements ActionCommand { + + protected final @NonNull RocketChatService rocketChatService; + + public DeleteSingleRoomAction(@NonNull RocketChatService rocketChatService) { + this.rocketChatService = rocketChatService; + } + + void deleteRocketChatGroup(String rcGroupId, List workflowErrors) { + if (isNotBlank(rcGroupId)) { + try { + this.rocketChatService.deleteGroupAsTechnicalUser(rcGroupId); + } catch (RocketChatDeleteGroupException e) { + log.error("UserService delete workflow error: ", e); + workflowErrors.add( + DeletionWorkflowError.builder() + .deletionSourceType(ASKER) + .deletionTargetType(DeletionTargetType.ROCKET_CHAT) + .identifier(rcGroupId) + .reason("Deletion of Rocket.Chat group failed") + .timestamp(nowInUtc()) + .build()); + } + } + } + + /** + * Deletes the given {@link Session} in the database with the related Rocket.Chat room containing + * all messages and uploads. + * + * @param actionTarget the {@link SessionDeletionWorkflowDTO} with the session to delete + */ + @Override + public void execute(RocketchatRoomDeletionWorkflowDTO actionTarget) { + deleteRocketChatGroup( + actionTarget.getRocketchatRoomId(), actionTarget.getDeletionWorkflowErrors()); + } +} diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/model/RocketchatRoomDeletionWorkflowDTO.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/model/RocketchatRoomDeletionWorkflowDTO.java new file mode 100644 index 000000000..5016e9480 --- /dev/null +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/model/RocketchatRoomDeletionWorkflowDTO.java @@ -0,0 +1,13 @@ +package de.caritas.cob.userservice.api.workflow.delete.model; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class RocketchatRoomDeletionWorkflowDTO { + + private String rocketchatRoomId; + private List deletionWorkflowErrors; +} 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 e90eec53a..fe133b27e 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 @@ -116,7 +116,12 @@ private List performSessionDeletion( String rcGroupId, List userSessionList) { List workflowErrors = new ArrayList<>(); Optional session = findSessionInUserSessionList(rcGroupId, userSessionList); - session.ifPresent(s -> workflowErrors.addAll(deleteSessionService.performSessionDeletion(s))); + session.ifPresentOrElse( + s -> workflowErrors.addAll(deleteSessionService.performSessionDeletion(s)), + () -> + workflowErrors.addAll( + deleteSessionService.performRocketchatSessionDeletion(rcGroupId))); + return workflowErrors; } diff --git a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteSessionService.java b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteSessionService.java index 1a3ede1b8..11f2e2eb1 100644 --- a/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteSessionService.java +++ b/src/main/java/de/caritas/cob/userservice/api/workflow/delete/service/DeleteSessionService.java @@ -4,10 +4,13 @@ import de.caritas.cob.userservice.api.actions.registry.ActionsRegistry; import de.caritas.cob.userservice.api.model.Session; +import de.caritas.cob.userservice.api.workflow.delete.action.asker.DeleteSingleRoomAction; import de.caritas.cob.userservice.api.workflow.delete.action.asker.DeleteSingleRoomAndSessionAction; import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError; +import de.caritas.cob.userservice.api.workflow.delete.model.RocketchatRoomDeletionWorkflowDTO; import de.caritas.cob.userservice.api.workflow.delete.model.SessionDeletionWorkflowDTO; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import lombok.NonNull; @@ -42,4 +45,20 @@ public List performSessionDeletion(Session session) { return deletionWorkflowDTO.getDeletionWorkflowErrors(); } + + public Collection performRocketchatSessionDeletion( + String rcGroupId) { + if (isNull(rcGroupId)) { + return Collections.emptyList(); + } + + var deletionWorkflowDTO = new RocketchatRoomDeletionWorkflowDTO(rcGroupId, new ArrayList<>()); + + this.actionsRegistry + .buildContainerForType(RocketchatRoomDeletionWorkflowDTO.class) + .addActionToExecute(DeleteSingleRoomAction.class) + .executeActions(deletionWorkflowDTO); + + return deletionWorkflowDTO.getDeletionWorkflowErrors(); + } } From 6fd1c9a67329b8e4869eb0008f89b89945f54687 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 27 Sep 2024 11:46:59 +0200 Subject: [PATCH 2/4] fix: update upload artifact version to v4 --- .github/workflows/dockerImage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerImage.yml b/.github/workflows/dockerImage.yml index 000fe72fb..6b3f4b862 100644 --- a/.github/workflows/dockerImage.yml +++ b/.github/workflows/dockerImage.yml @@ -44,7 +44,7 @@ jobs: run: mvn -B -Pprod clean package -DskipTests=true - name: Maven Verify run: mvn -B -Pprod clean verify -DskipTests=true - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: targetfiles path: target/*.jar From 1012ef1ef6491251eaaa8203ff84745ee98f42d5 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 27 Sep 2024 11:51:16 +0200 Subject: [PATCH 3/4] fix: update download artifact version to v4 --- .github/workflows/dockerImage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerImage.yml b/.github/workflows/dockerImage.yml index 6b3f4b862..e43a274bb 100644 --- a/.github/workflows/dockerImage.yml +++ b/.github/workflows/dockerImage.yml @@ -76,7 +76,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Download buildfiles artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: targetfiles - name: Get current time From c4d5095bd19275a4e40b7aeca0c1f1591b628765 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 27 Sep 2024 12:04:57 +0200 Subject: [PATCH 4/4] chore: add unit test --- .../asker/DeleteSingleRoomActionTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/test/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomActionTest.java diff --git a/src/test/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomActionTest.java b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomActionTest.java new file mode 100644 index 000000000..6aab3d05c --- /dev/null +++ b/src/test/java/de/caritas/cob/userservice/api/workflow/delete/action/asker/DeleteSingleRoomActionTest.java @@ -0,0 +1,76 @@ +package de.caritas.cob.userservice.api.workflow.delete.action.asker; + +import static java.util.Collections.emptyList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.powermock.reflect.Whitebox.setInternalState; + +import de.caritas.cob.userservice.api.adapters.rocketchat.RocketChatService; +import de.caritas.cob.userservice.api.exception.rocketchat.RocketChatDeleteGroupException; +import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError; +import de.caritas.cob.userservice.api.workflow.delete.model.RocketchatRoomDeletionWorkflowDTO; +import java.util.ArrayList; +import java.util.List; +import org.jeasy.random.EasyRandom; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.Logger; + +@RunWith(MockitoJUnitRunner.class) +public class DeleteSingleRoomActionTest { + + @InjectMocks private DeleteSingleRoomAction deleteSingleRoomAction; + + @Mock private RocketChatService rocketChatService; + + @Mock private Logger logger; + + @Before + public void setup() { + setInternalState(DeleteSingleRoomAction.class, "log", logger); + } + + @Test + public void + execute_Should_returnEmptyListAndPerformAllDeletions_When_userSessionIsDeletedSuccessful() + throws Exception { + String rocketChatId = new EasyRandom().nextObject(String.class); + RocketchatRoomDeletionWorkflowDTO workflowDTO = + new RocketchatRoomDeletionWorkflowDTO(rocketChatId, emptyList()); + + this.deleteSingleRoomAction.execute(workflowDTO); + List workflowErrors = workflowDTO.getDeletionWorkflowErrors(); + + assertThat(workflowErrors, hasSize(0)); + verifyNoMoreInteractions(this.logger); + verify(this.rocketChatService, times(1)).deleteGroupAsTechnicalUser(any()); + } + + @Test + public void + execute_Should_returnExpectedWorkflowErrors_When_noUserSessionDeletedStepIsSuccessful() + throws Exception { + doThrow(new RocketChatDeleteGroupException(new RuntimeException())) + .when(this.rocketChatService) + .deleteGroupAsTechnicalUser(any()); + + RocketchatRoomDeletionWorkflowDTO workflowDTO = + new RocketchatRoomDeletionWorkflowDTO("rocketChatId", new ArrayList<>()); + + this.deleteSingleRoomAction.execute(workflowDTO); + List workflowErrors = workflowDTO.getDeletionWorkflowErrors(); + + assertThat(workflowErrors, hasSize(1)); + verify(logger, times(1)).error(anyString(), any(Exception.class)); + } +}