diff --git a/src/main/java/no/fintlabs/Application.java b/src/main/java/no/fintlabs/Application.java index e06e442..21afd77 100644 --- a/src/main/java/no/fintlabs/Application.java +++ b/src/main/java/no/fintlabs/Application.java @@ -10,9 +10,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; @ConfigurationPropertiesScan @SpringBootApplication +@EnableScheduling public class Application { public static void main(String[] args) { diff --git a/src/main/java/no/fintlabs/user/ResponseFactory.java b/src/main/java/no/fintlabs/user/ResponseFactory.java index d817353..3390add 100644 --- a/src/main/java/no/fintlabs/user/ResponseFactory.java +++ b/src/main/java/no/fintlabs/user/ResponseFactory.java @@ -50,6 +50,13 @@ public ResponseEntity> toResponseEntity(Page use ); } + public ResponseEntity> toResponseEntity(String message) { + return new ResponseEntity<>( + Map.of("message", message), + HttpStatus.OK + ); + } + private Page toPage(List list, Pageable paging) { int start = (int) paging.getOffset(); int end = Math.min((start + paging.getPageSize()), list.size()); @@ -58,6 +65,4 @@ private Page toPage(List list, Pageable paging) { ? new PageImpl<>(new ArrayList<>(), paging, list.size()) : new PageImpl<>(list.subList(start, end), paging, list.size()); } - - } diff --git a/src/main/java/no/fintlabs/user/UserController.java b/src/main/java/no/fintlabs/user/UserController.java index 9205aed..e956e7c 100644 --- a/src/main/java/no/fintlabs/user/UserController.java +++ b/src/main/java/no/fintlabs/user/UserController.java @@ -75,21 +75,21 @@ public ResponseEntity getLoggedOnUser(@AuthenticationPrincipal Jwt } @PostMapping("/republish") - public ResponseEntity republishKontrollUsers() { //@AuthenticationPrincipal Jwt jwt) { + public ResponseEntity> republishKontrollUsers(@AuthenticationPrincipal Jwt jwt) { //TODO: implement when agreed on security solution /*if (!validateIsAdmin(jwt)) { throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User does not have access to republish all kontrollusers"); }*/ + String triggerType = "admin (" + FintJwtEndUserPrincipal.from(jwt).getMail() + ") request"; List allUsers = userService.getAllUsers(); - log.info("Republishing all {} kontrollusers", allUsers.size()); - allUsers.stream() - .filter(user -> user.getIdentityProviderUserObjectId() != null) - .forEach(userEntityProducerService::publish); - - log.info("Republishing all {} kontrollusers done", allUsers.size()); + if (allUsers.isEmpty()) { + log.info("No users found to publish"); + return responseFactory.toResponseEntity("No users found to publish"); + } + int noOfPublishedUsers = userEntityProducerService.publishAllKontrollUsers(triggerType, allUsers); - return new ResponseEntity<>(HttpStatus.OK); + return responseFactory.toResponseEntity("Republished " + noOfPublishedUsers + " users"); } } diff --git a/src/main/java/no/fintlabs/user/UserEntityProducerService.java b/src/main/java/no/fintlabs/user/UserEntityProducerService.java index 1f4eb08..ccb3d31 100644 --- a/src/main/java/no/fintlabs/user/UserEntityProducerService.java +++ b/src/main/java/no/fintlabs/user/UserEntityProducerService.java @@ -8,14 +8,18 @@ import no.fintlabs.kafka.entity.topic.EntityTopicService; import org.springframework.stereotype.Service; +import java.util.List; + @Service @Slf4j public class UserEntityProducerService { private final EntityProducer entityProducer; private final EntityTopicNameParameters entityTopicNameParameters; - public UserEntityProducerService(EntityProducerFactory entityProducerFactory, - EntityTopicService entityTopicService) { + public UserEntityProducerService( + EntityProducerFactory entityProducerFactory, + EntityTopicService entityTopicService + ) { entityProducer = entityProducerFactory.createProducer(User.class); entityTopicNameParameters = EntityTopicNameParameters .builder() @@ -34,4 +38,12 @@ public void publish(User user){ .build() ); } + + public int publishAllKontrollUsers(String triggerType, List allUsers){ + log.info("Republishing all {} kontrollusers triggered by {}", allUsers.size(), triggerType); + + allUsers.forEach(this::publish); + log.info("Republishing all {} kontrollusers triggered by {} done", allUsers.size(), triggerType); + return allUsers.size(); + } } diff --git a/src/main/java/no/fintlabs/user/UserPublishingComponent.java b/src/main/java/no/fintlabs/user/UserPublishingComponent.java new file mode 100644 index 0000000..307d973 --- /dev/null +++ b/src/main/java/no/fintlabs/user/UserPublishingComponent.java @@ -0,0 +1,35 @@ +package no.fintlabs.user; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +public class UserPublishingComponent { + private final UserEntityProducerService userEntityProducerService; + private final UserService userService; + + public UserPublishingComponent(UserEntityProducerService userEntityProducerService, UserService userService) { + this.userEntityProducerService = userEntityProducerService; + this.userService = userService; + } + @Scheduled( + initialDelayString = "${fint.kontroll.user-catalog.publishing.initial-delay}", + fixedDelayString = "${fint.kontroll.user-catalog.publishing.fixed-delay}", + timeUnit = TimeUnit.HOURS + ) + public void publishUsers() { + String triggerType = "scheduled job"; + List allUsers = userService.getAllUsers(); + + if (allUsers.isEmpty()) { + log.info("No users to publish"); + return; + } + userEntityProducerService.publishAllKontrollUsers(triggerType, allUsers); + } +} diff --git a/src/main/java/no/fintlabs/user/UserService.java b/src/main/java/no/fintlabs/user/UserService.java index c0132d7..b96af65 100644 --- a/src/main/java/no/fintlabs/user/UserService.java +++ b/src/main/java/no/fintlabs/user/UserService.java @@ -28,7 +28,10 @@ public UserService(UserRepository userRepository, UserEntityProducerService user } public List getAllUsers() { - return userRepository.findAll(); + return userRepository.findAll() + .stream() + .filter(user -> user.getIdentityProviderUserObjectId() != null) + .toList(); } public void save(User user) { @@ -40,8 +43,8 @@ public void save(User user) { private Runnable onSaveNewUser(User user) { return () -> { User newUser = userRepository.save(user); - log.info("Create new user: " + user.getId()); - log.info("created kontrollUser: " + newUser.getIdentityProviderUserObjectId()); + log.info("Create new user: {}", user.getId()); + log.info("Created kontrollUser: {}", newUser.getIdentityProviderUserObjectId()); userEntityProducerService.publish(newUser); }; } @@ -49,9 +52,9 @@ private Runnable onSaveNewUser(User user) { private Consumer onSaveExistingUser(User user) { return existingUser -> { user.setId(existingUser.getId()); - log.debug("Update user: " + user.getId()); + log.debug("Update user: {}", user.getId()); User savedUser = userRepository.save(user); - log.debug("update kontrollUser: " + savedUser.getIdentityProviderUserObjectId()); + log.debug("update kontrollUser: {}", savedUser.getIdentityProviderUserObjectId()); userEntityProducerService.publish(savedUser); }; } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index d2851dd..8a555b0 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -9,6 +9,9 @@ fint: kontroll: user-catalog: pagesize: 50 + publishing: + initial-delay: 0 + fixed-delay: 48 opa: url: http://fint-kontroll-opa:8181/v1/data/accessmanagement authorization: diff --git a/src/test/java/no/fintlabs/user/UserServiceTest.java b/src/test/java/no/fintlabs/user/UserServiceTest.java index e64a09b..8bbeb4b 100644 --- a/src/test/java/no/fintlabs/user/UserServiceTest.java +++ b/src/test/java/no/fintlabs/user/UserServiceTest.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Optional; +import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @@ -103,8 +104,21 @@ void testGetDetailedUserById_shouldPermitAccess(){ DetailedUser foundDetailedUser = userService.getDetailedUserById(fintJwtEndUserPrincipal,1L); assertEquals(requestedDetailedUser.getId(), foundDetailedUser.getId()); + } + @Test + void testGetAllUsers_shouldReturnOnlyUsersWithNotNullIdpObjectId() { + User user1 = User.builder() + .id(1L) + .identityProviderUserObjectId(UUID.fromString("3f2b9b63-47e9-43c2-9d61-dd078d621479")) + .build(); + User user2 = User.builder() + .id(2L) + .build(); + when(userRepository.findAll()).thenReturn(List.of(user1,user2)); + assertEquals(1, userService.getAllUsers().size()); + assertEquals(user1, userService.getAllUsers().get(0)); } }