From 44c283d4fe03bfcb636f3290b4210587a85a3c0f Mon Sep 17 00:00:00 2001 From: Sascha Doemer Date: Tue, 18 Jun 2024 08:37:41 +0200 Subject: [PATCH] Bugfix/remove duplicates from postgis due to multiple subscriptions (#213) --- .../fivegla/business/SubscriptionService.java | 26 ++++++++ .../fivegla/controller/api/BaseMappings.java | 1 + .../tenant/SubscriptionController.java | 62 +++++++++++++++++++ .../SubscriptionIntegrationService.java | 22 +++++-- 4 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 src/main/java/de/app/fivegla/business/SubscriptionService.java create mode 100644 src/main/java/de/app/fivegla/controller/tenant/SubscriptionController.java diff --git a/src/main/java/de/app/fivegla/business/SubscriptionService.java b/src/main/java/de/app/fivegla/business/SubscriptionService.java new file mode 100644 index 00000000..e7081571 --- /dev/null +++ b/src/main/java/de/app/fivegla/business/SubscriptionService.java @@ -0,0 +1,26 @@ +package de.app.fivegla.business; + +import de.app.fivegla.integration.fiware.SubscriptionIntegrationService; +import de.app.fivegla.persistence.entity.Tenant; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SubscriptionService { + + private final SubscriptionIntegrationService subscriptionIntegrationService; + + /** + * Delete all existing subscriptions. + * + * @param tenant the tenant + */ + public void deleteAllSubscriptions(Tenant tenant) { + log.info("Deleting all subscriptions"); + subscriptionIntegrationService.removeAll(tenant); + } + +} diff --git a/src/main/java/de/app/fivegla/controller/api/BaseMappings.java b/src/main/java/de/app/fivegla/controller/api/BaseMappings.java index e10229a8..09a44c94 100644 --- a/src/main/java/de/app/fivegla/controller/api/BaseMappings.java +++ b/src/main/java/de/app/fivegla/controller/api/BaseMappings.java @@ -31,4 +31,5 @@ public class BaseMappings { public static final String THIRD_PARTY_API_CONFIGURATION = SECURED_BY_TENANT + "/3rd-party-api-configuration"; public static final String DEVICE_POSITION = SECURED_BY_TENANT + "/device-position"; public static final String GROUPS = SECURED_BY_TENANT + "/groups"; + public static final String SUBSCRIPTION = SECURED_BY_TENANT + "/subscription"; } diff --git a/src/main/java/de/app/fivegla/controller/tenant/SubscriptionController.java b/src/main/java/de/app/fivegla/controller/tenant/SubscriptionController.java new file mode 100644 index 00000000..51e10115 --- /dev/null +++ b/src/main/java/de/app/fivegla/controller/tenant/SubscriptionController.java @@ -0,0 +1,62 @@ +package de.app.fivegla.controller.tenant; + +import de.app.fivegla.api.Response; +import de.app.fivegla.business.SubscriptionService; +import de.app.fivegla.business.TenantService; +import de.app.fivegla.config.security.marker.TenantCredentialApiAccess; +import de.app.fivegla.controller.api.BaseMappings; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.security.Principal; + +/** + * The SubscriptionController class handles subscription-related operations. + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(BaseMappings.SUBSCRIPTION) +public class SubscriptionController implements TenantCredentialApiAccess { + + private final TenantService tenantService; + private final SubscriptionService subscriptionService; + + @Operation( + operationId = "delete.all.subscriptions", + description = "Delete all subscriptions.", + tags = BaseMappings.SUBSCRIPTION + ) + @ApiResponse( + responseCode = "200", + description = "All subscriptions have been deleted.", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Response.class) + ) + ) + @ApiResponse( + responseCode = "400", + description = "The request is invalid.", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Response.class) + ) + ) + @DeleteMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity deleteAllSubscriptions(Principal principal) { + var tenant = validateTenant(tenantService, principal); + subscriptionService.deleteAllSubscriptions(tenant); + return ResponseEntity.ok().body(new Response()); + } + +} diff --git a/src/main/java/de/app/fivegla/integration/fiware/SubscriptionIntegrationService.java b/src/main/java/de/app/fivegla/integration/fiware/SubscriptionIntegrationService.java index ee4838b2..06ed2246 100644 --- a/src/main/java/de/app/fivegla/integration/fiware/SubscriptionIntegrationService.java +++ b/src/main/java/de/app/fivegla/integration/fiware/SubscriptionIntegrationService.java @@ -47,6 +47,7 @@ public SubscriptionIntegrationService(String contextBrokerUrl, List noti * each representing a different type. */ public void subscribe(Tenant tenant, EntityType... entityTypes) { + removeAll(tenant); // FIXME adjust and update subscriptions instead of removing all var httpClient = HttpClient.newHttpClient(); var subscriptions = createSubscriptions(entityTypes); for (var subscription : subscriptions) { @@ -115,10 +116,9 @@ private List createSubscriptionEntities(EntityType... entityTypes) { * Removes all subscriptions of the specified type. * * @param tenant the tenant to remove subscriptions for - * @param type the type of subscriptions to be removed */ - public void removeAll(Tenant tenant, EntityType type) { - findAll(tenant, type).forEach(subscription -> removeSubscription(tenant, subscription)); + public void removeAll(Tenant tenant) { + findAll(tenant).forEach(subscription -> removeSubscription(tenant, subscription)); } private void removeSubscription(Tenant tenant, Subscription subscription) { @@ -156,6 +156,18 @@ private void removeSubscription(Tenant tenant, Subscription subscription) { * @return A list of Subscription objects matching the given entityType. */ public List findAll(Tenant tenant, EntityType entityType) { + return findAll(tenant).stream().filter(subscription -> subscription.getSubject().getEntities() + .stream() + .anyMatch(entity -> entity.getType().equals(entityType.getKey()))).toList(); + } + + /** + * Finds all subscriptions of a given entityType. + * + * @param tenant The tenant to find subscriptions for. + * @return A list of Subscription objects matching the given entityType. + */ + public List findAll(Tenant tenant) { var httpClient = HttpClient.newHttpClient(); var httpRequest = HttpRequest.newBuilder() .header(CustomHeader.FIWARE_SERVICE, tenant.getTenantId()) @@ -172,9 +184,7 @@ public List findAll(Tenant tenant, EntityType entityType) { .build()); } else { log.info("Subscription found successfully."); - return toListOfObjects(response.body()).stream().filter(subscription -> subscription.getSubject().getEntities() - .stream() - .anyMatch(entity -> entity.getType().equals(entityType.getKey()))).toList(); + return toListOfObjects(response.body()); } } catch (Exception e) { log.error("Could not find subscriptions.", e);