TSK-1947: processing of LDAP-data after refresh

This commit is contained in:
ryzheboka 2022-08-23 20:10:46 +02:00 committed by Elena Mokeeva
parent e1db9f0843
commit e1d205d4ef
7 changed files with 140 additions and 5 deletions

View File

@ -0,0 +1,18 @@
package pro.taskana.spi.user.api;
import pro.taskana.user.api.models.User;
/**
* The RefreshUserPostprocessor allows to implement custom behaviour after a {@linkplain User} has
* been updated.
*/
public interface RefreshUserPostprocessor {
/**
* Processes a {@linkplain User} after its refresh.
*
* @param userToProcess {@linkplain User} the User to preprocess
* @return the {@linkplain User} after it has been processed
*/
User processUserAfterRefresh(User userToProcess);
}

View File

@ -0,0 +1,43 @@
package pro.taskana.spi.user.internal;
import static pro.taskana.common.internal.util.CheckedConsumer.wrap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.common.internal.util.SpiLoader;
import pro.taskana.spi.user.api.RefreshUserPostprocessor;
import pro.taskana.user.api.models.User;
public class RefreshUserPostprocessorManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(RefreshUserPostprocessorManager.class);
private final List<RefreshUserPostprocessor> refreshUserPostprocessors;
public RefreshUserPostprocessorManager() {
refreshUserPostprocessors = SpiLoader.load(RefreshUserPostprocessor.class);
for (RefreshUserPostprocessor postprocessor : refreshUserPostprocessors) {
LOGGER.info(
"Registered RefreshUserPostprocessor provider: {}", postprocessor.getClass().getName());
}
if (refreshUserPostprocessors.isEmpty()) {
LOGGER.info("No RefreshUserPostprocessor found. Running without RefreshUserPostprocessor.");
}
}
public User processUserAfterRefresh(User userToProcess) {
LOGGER.debug("Sending user to RefreshUserPostprocessor providers: {}", userToProcess);
refreshUserPostprocessors.forEach(
wrap(
refreshUserPostprocessor ->
refreshUserPostprocessor.processUserAfterRefresh(userToProcess)));
return userToProcess;
}
public boolean isEnabled() {
return !refreshUserPostprocessors.isEmpty();
}
}

View File

@ -2,6 +2,7 @@ package pro.taskana.user.jobs;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,6 +16,7 @@ import pro.taskana.common.internal.jobs.AbstractTaskanaJob;
import pro.taskana.common.internal.transaction.TaskanaTransactionProvider;
import pro.taskana.common.rest.ldap.LdapClient;
import pro.taskana.common.rest.util.ApplicationContextProvider;
import pro.taskana.spi.user.internal.RefreshUserPostprocessorManager;
import pro.taskana.task.internal.jobs.helper.SqlConnectionRunner;
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
import pro.taskana.user.api.exceptions.UserNotFoundException;
@ -25,6 +27,7 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
private static final Logger LOGGER = LoggerFactory.getLogger(UserInfoRefreshJob.class);
private final SqlConnectionRunner sqlConnectionRunner;
private RefreshUserPostprocessorManager refreshUserPostprocessorManager;
public UserInfoRefreshJob(TaskanaEngine taskanaEngine) {
this(taskanaEngine, null, null);
@ -38,6 +41,7 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
runEvery = taskanaEngine.getConfiguration().getUserRefreshJobRunEvery();
firstRun = taskanaEngine.getConfiguration().getUserRefreshJobFirstRun();
sqlConnectionRunner = new SqlConnectionRunner(taskanaEngine);
refreshUserPostprocessorManager = new RefreshUserPostprocessorManager();
}
/**
@ -68,9 +72,13 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
try {
List<User> users = ldapClient.searchUsersInUserRole();
addExistingConfigurationDataToUsers(users);
List<User> usersAfterProcessing =
users.stream()
.map(user -> refreshUserPostprocessorManager.processUserAfterRefresh(user))
.collect(Collectors.toList());
addExistingConfigurationDataToUsers(usersAfterProcessing);
clearExistingUsers();
insertNewUsers(users);
insertNewUsers(usersAfterProcessing);
LOGGER.info("Job to refresh all user info has finished.");

View File

@ -7,12 +7,16 @@ import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.rest.ldap.LdapClient;
import pro.taskana.common.test.rest.RestHelper;
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.common.test.security.WithAccessId;
@ -22,22 +26,29 @@ import pro.taskana.user.internal.models.UserImpl;
@TaskanaSpringBootTest
@ExtendWith(JaasExtension.class)
@TestMethodOrder(OrderAnnotation.class)
class UserInfoRefreshJobIntTest {
TaskanaEngine taskanaEngine;
UserService userService;
LdapClient ldapClient;
private final RestHelper restHelper;
@Autowired
public UserInfoRefreshJobIntTest(
TaskanaEngine taskanaEngine, UserService userService, LdapClient ldapClient) {
TaskanaEngine taskanaEngine,
UserService userService,
LdapClient ldapClient,
RestHelper restHelper) {
this.taskanaEngine = taskanaEngine;
this.userService = userService;
this.ldapClient = ldapClient;
this.restHelper = restHelper;
}
@Test
@WithAccessId(user = "businessadmin")
@Order(1)
void should_RefreshUserInfo_When_UserInfoRefreshJobIsExecuted() throws Exception {
try (Connection connection = taskanaEngine.getConfiguration().getDatasource().getConnection()) {
@ -50,13 +61,38 @@ class UserInfoRefreshJobIntTest {
users = getUsers(connection);
List<User> ldapusers = ldapClient.searchUsersInUserRole();
assertThat(users).hasSize(6).hasSameSizeAs(ldapusers);
assertThat(users)
.usingRecursiveFieldByFieldElementComparatorIgnoringFields("longName", "data")
.hasSize(6)
.hasSameSizeAs(ldapusers)
.usingRecursiveFieldByFieldElementComparatorIgnoringFields(
"longName", "data", "orgLevel1")
.containsExactlyElementsOf(ldapusers);
}
}
@Test
@WithAccessId(user = "businessadmin")
@Order(2)
void should_PostprocessUser_When_RefrehUserPostprocessorIsActive() throws Exception {
try (Connection connection = taskanaEngine.getConfiguration().getDatasource().getConnection()) {
UserInfoRefreshJob userInfoRefreshJob = new UserInfoRefreshJob(taskanaEngine);
userInfoRefreshJob.execute();
Statement statement = connection.createStatement();
ResultSet rs =
statement.executeQuery(
"SELECT * FROM "
+ connection.getSchema()
+ ".USER_INFO "
+ "WHERE USER_ID='user-2-2'");
rs.next();
String updatedOrgLevel = rs.getString("ORG_LEVEL_1");
assertThat(updatedOrgLevel).isEqualTo("FirstSecond");
}
}
private List<User> getUsers(Connection connection) throws Exception {
List<User> users = new ArrayList<>();

View File

@ -0,0 +1,14 @@
package pro.taskana.user.rest;
import pro.taskana.spi.user.api.RefreshUserPostprocessor;
import pro.taskana.user.api.models.User;
public class FirstRefreshUserPostprocessor implements RefreshUserPostprocessor {
@Override
public User processUserAfterRefresh(User userToProcess) {
if (userToProcess.getId().equals("user-2-2")) {
userToProcess.setOrgLevel1("First");
}
return userToProcess;
}
}

View File

@ -0,0 +1,14 @@
package pro.taskana.user.rest;
import pro.taskana.spi.user.api.RefreshUserPostprocessor;
import pro.taskana.user.api.models.User;
public class SecondRefreshUserPostprocessor implements RefreshUserPostprocessor {
@Override
public User processUserAfterRefresh(User userToProcess) {
if (userToProcess.getId().equals("user-2-2")) {
userToProcess.setOrgLevel1(userToProcess.getOrgLevel1() + "Second");
}
return userToProcess;
}
}

View File

@ -0,0 +1,2 @@
pro.taskana.user.rest.FirstRefreshUserPostprocessor
pro.taskana.user.rest.SecondRefreshUserPostprocessor