diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java index 54d5292..29a448a 100644 --- a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java +++ b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java @@ -3,15 +3,18 @@ import in.projecteka.gateway.common.DbOperationError; import in.projecteka.gateway.registry.model.Bridge; import in.projecteka.gateway.registry.model.BridgeRegistryRequest; +import in.projecteka.gateway.registry.model.BridgeService; import in.projecteka.gateway.registry.model.BridgeServiceRequest; import in.projecteka.gateway.registry.model.CMEntry; import in.projecteka.gateway.registry.model.CMServiceRequest; import io.vertx.pgclient.PgPool; import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowSet; import io.vertx.sqlclient.Tuple; import lombok.AllArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -45,6 +48,8 @@ public class RegistryRepository { "active = $2, name = $3, date_modified = timezone('utc'::text, now()) FROM bridge " + "WHERE bridge_service.bridge_id = bridge.bridge_id AND bridge.active = $4 AND " + "bridge_service.service_id = $5 AND bridge_service.type = $6"; + private static final String SELECT_BRIDGE_SERVICES = "select service_id, type FROM bridge_service " + + "WHERE bridge_id = $1 AND active = $2"; private final PgPool readWriteClient; @@ -213,4 +218,26 @@ private Mono select(String query, Tuple params, String errorMessage) { monoSink.success(true); })); } + + public Flux fetchBridgeServicesIfPresent(String bridgeId) { + return Flux.create(fluxSink -> this.readOnlyClient.preparedQuery(SELECT_BRIDGE_SERVICES) + .execute(Tuple.of(bridgeId, true), + handler -> { + if (handler.failed()) { + logger.error(handler.cause().getMessage(), handler.cause()); + fluxSink.error(new DbOperationError("Failed to fetch bridge services")); + return; + } + RowSet results = handler.result(); + if (results.iterator().hasNext()) { + results.forEach(row -> { + fluxSink.next(BridgeService.builder() + .id(row.getString("service_id")) + .type(ServiceType.valueOf(row.getString("type"))) + .build()); + }); + } + fluxSink.complete(); + })); + } } diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryService.java b/src/main/java/in/projecteka/gateway/registry/RegistryService.java index 548a265..d6fa3c3 100644 --- a/src/main/java/in/projecteka/gateway/registry/RegistryService.java +++ b/src/main/java/in/projecteka/gateway/registry/RegistryService.java @@ -101,6 +101,10 @@ public Mono populateBridgeEntry(BridgeRegistryRequest bridgeRegi .flatMap(bridge -> bridge.getId() != null ? bridgeRequest(bridge, bridgeRegistryRequest) .flatMap(req -> registryRepository.updateBridgeEntry(req) + .then(registryRepository.fetchBridgeServicesIfPresent(req.getId()).collectList() + .flatMap(services -> Flux.fromIterable(services) + .flatMap(service -> bridgeMappings.invalidate(Pair.of(service.getId(), + service.getType()))).then())) .then(req.getActive() ? createClient(bridgeRegistryRequest.getId()) : adminServiceClient.deleteClientIfExists(bridgeRegistryRequest.getId()) diff --git a/src/main/java/in/projecteka/gateway/registry/model/BridgeService.java b/src/main/java/in/projecteka/gateway/registry/model/BridgeService.java new file mode 100644 index 0000000..baec2c1 --- /dev/null +++ b/src/main/java/in/projecteka/gateway/registry/model/BridgeService.java @@ -0,0 +1,13 @@ +package in.projecteka.gateway.registry.model; + + +import in.projecteka.gateway.registry.ServiceType; +import lombok.Builder; +import lombok.Value; + +@Value +@Builder +public class BridgeService { + String id; + ServiceType type; +} diff --git a/src/test/java/in/projecteka/gateway/registry/RegistryServiceTest.java b/src/test/java/in/projecteka/gateway/registry/RegistryServiceTest.java index c32be13..90c4158 100644 --- a/src/test/java/in/projecteka/gateway/registry/RegistryServiceTest.java +++ b/src/test/java/in/projecteka/gateway/registry/RegistryServiceTest.java @@ -12,6 +12,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.util.Pair; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.publisher.MonoSink; import reactor.test.StepVerifier; @@ -25,6 +26,7 @@ import static in.projecteka.gateway.registry.ServiceType.HIP; import static in.projecteka.gateway.registry.TestBuilders.bridge; import static in.projecteka.gateway.registry.TestBuilders.bridgeRegistryRequest; +import static in.projecteka.gateway.registry.TestBuilders.bridgeService; import static in.projecteka.gateway.registry.TestBuilders.bridgeServiceRequest; import static in.projecteka.gateway.registry.TestBuilders.cmServiceRequest; import static in.projecteka.gateway.registry.TestBuilders.realmRole; @@ -245,8 +247,11 @@ void shouldUpdateBridgeEntryAndDeleteClientInKeyCloakWhenBridgeSetToInactive() { var request = bridgeRegistryRequest().active(false).build(); var bridgeId = request.getId(); var bridge = bridge().build(); + var bridgeService = bridgeService().build(); when(registryRepository.ifPresent(bridgeId)).thenReturn(just(bridge)); when(registryRepository.updateBridgeEntry(request)).thenReturn(empty()); + when(registryRepository.fetchBridgeServicesIfPresent(bridgeId)).thenReturn(Flux.just(bridgeService)); + when(bridgeMappings.invalidate(Pair.of(bridgeService.getId(), bridgeService.getType()))).thenReturn(empty()); when(adminServiceClient.deleteClientIfExists(bridgeId)).thenReturn(empty()); var producer = registryService.populateBridgeEntry(request); @@ -269,6 +274,7 @@ void shouldUpdateBridgeEntryAndCreateClientInKeyCloakWhenBridgeSetToActive() { var clientResponse = ClientResponse.builder().id(bridgeId).secret(clientSecret.getValue()).build(); when(registryRepository.ifPresent(bridgeId)).thenReturn(just(bridge)); when(registryRepository.updateBridgeEntry(request)).thenReturn(empty()); + when(registryRepository.fetchBridgeServicesIfPresent(bridgeId)).thenReturn(Flux.empty()); when(adminServiceClient.createClientIfNotExists(bridgeId)).thenReturn(empty()); when(adminServiceClient.getServiceAccount(bridgeId)).thenReturn(just(serviceAccount)); when(adminServiceClient.getAvailableRealmRoles(serviceAccount.getId())).thenReturn(just(realmRoles)); diff --git a/src/test/java/in/projecteka/gateway/registry/TestBuilders.java b/src/test/java/in/projecteka/gateway/registry/TestBuilders.java index 89c50b9..03b5a4b 100644 --- a/src/test/java/in/projecteka/gateway/registry/TestBuilders.java +++ b/src/test/java/in/projecteka/gateway/registry/TestBuilders.java @@ -4,6 +4,7 @@ import in.projecteka.gateway.clients.model.ServiceAccount; import in.projecteka.gateway.registry.model.Bridge; import in.projecteka.gateway.registry.model.BridgeRegistryRequest; +import in.projecteka.gateway.registry.model.BridgeService; import in.projecteka.gateway.registry.model.BridgeServiceRequest; import in.projecteka.gateway.registry.model.CMServiceRequest; import org.jeasy.random.EasyRandom; @@ -38,4 +39,8 @@ public static CMServiceRequest.CMServiceRequestBuilder cmServiceRequest() { public static Bridge.BridgeBuilder bridge() { return easyRandom.nextObject(Bridge.BridgeBuilder.class); } + + public static BridgeService.BridgeServiceBuilder bridgeService() { + return easyRandom.nextObject(BridgeService.BridgeServiceBuilder.class); + } }