Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
Feature/support multiple notification urls (#24)
Browse files Browse the repository at this point in the history
* Added tenant support to Fiware integration services

Implemented tenant support in Fiware integration services to organize resources and provide resource isolation. Integrated this implementation into the existing test suites. Made necessary amendments to the corresponding test resources and instantiated services with the tenant parameter. Removed StatusServiceIT test file as the functionality is covered in DeviceIntegrationServiceBasedOnTenantIT.

* Update version in pom.xml file

Bumped up the version from 5.4.0 to 6.0.0 in pom.xml. This Version change reflects the recent updates made to the project, including the implementation of tenant support in Fiware integration services for resource organization and isolation. As part of these updates, also made necessary changes to the corresponding test resources and services.

* Add CustomHeader for tenant identification in Fiware API calls

Introduced a 'CustomHeader' interface which standardizes the use of the 'fiware-service' HTTP header across the application. It improves code consistency, reduces potential human error and enhances code readability. This header carries the identity of the tenant(service) and eases resource coordination in multi-tenancy environments. Changes are made in the AbstractEntityIntegrationService and SubscriptionService classes, where the header is being added to the HTTP requests.

* Update tests for the usage of contextBrokerUrl and tenant

Refactored some integration tests so that instead of hard-coding the strings for the contextBrokerUrl and tenant, they're now using values from a superclass (AbstractIT). This helps to avoid redundancy, reduces the risk of inconsistencies across tests and increases code maintainability.

* Format.

* Remove duplicate header in SubscriptionService

A header for FIWARE_SERVICE was duplicated in the SubscriptionService class. This duplication added no functional value and could potentially cause confusion or issues in future development. The unnecessary line has been removed for cleaner, more efficient code.
  • Loading branch information
saschadoemer authored Oct 20, 2023
1 parent 34235d4 commit 9b932b9
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 58 deletions.
78 changes: 43 additions & 35 deletions src/main/java/de/app/fivegla/fiware/SubscriptionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;


Expand All @@ -21,11 +22,11 @@
*/
@Slf4j
public class SubscriptionService extends AbstractIntegrationService<Subscription> {
private final String notificationUrl;
private final List<String> notificationUrls;

public SubscriptionService(String contextBrokerUrl, String tenant, String notificationUrl) {
public SubscriptionService(String contextBrokerUrl, String tenant, List<String> notificationUrls) {
super(contextBrokerUrl, tenant);
this.notificationUrl = notificationUrl;
this.notificationUrls = notificationUrls;
}

public void subscribeAndReset(Type type) {
Expand All @@ -35,24 +36,26 @@ public void subscribeAndReset(Type type) {

public void subscribe(Type type) {
var httpClient = HttpClient.newHttpClient();
var subscription = createSubscriptionForType(type);
var httpRequest = HttpRequest.newBuilder()
.uri(URI.create(contextBrokerUrlForCommands() + "/subscriptions"))
.header("Content-Type", "application/json")
.header(CustomHeader.FIWARE_SERVICE, getTenant())
.POST(HttpRequest.BodyPublishers.ofString(toJson(subscription))).build();
try {
var response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 201) {
log.error("Could not create subscription. Response: " + response.body());
log.debug("Request: " + toJson(subscription));
log.debug("Response: " + response.body());
throw new FiwareIntegrationLayerException("Could not create subscription, there was an error from FIWARE.");
} else {
log.info("Subscription created/updated successfully.");
var subscriptions = createSubscriptionForType(type);
for (var subscription : subscriptions) {
var httpRequest = HttpRequest.newBuilder()
.uri(URI.create(contextBrokerUrlForCommands() + "/subscriptions"))
.header("Content-Type", "application/json")
.header(CustomHeader.FIWARE_SERVICE, getTenant())
.POST(HttpRequest.BodyPublishers.ofString(toJson(subscription))).build();
try {
var response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 201) {
log.error("Could not create subscription. Response: " + response.body());
log.debug("Request: " + toJson(subscription));
log.debug("Response: " + response.body());
throw new FiwareIntegrationLayerException("Could not create subscription, there was an error from FIWARE.");
} else {
log.info("Subscription created/updated successfully.");
}
} catch (Exception e) {
throw new FiwareIntegrationLayerException("Could not create/update subscription", e);
}
} catch (Exception e) {
throw new FiwareIntegrationLayerException("Could not create/update subscription", e);
}
}

Expand Down Expand Up @@ -103,20 +106,25 @@ public List<Subscription> findAll(Type type) {
}
}

private Subscription createSubscriptionForType(Type type) {
return Subscription.builder()
.description("Subscription for " + type.getKey() + " type")
.subject(Subject.builder()
.entities(List.of(Entity.builder()
.idPattern(".*")
.type(type.getKey())
.build()))
.build())
.notification(Notification.builder()
.http(Http.builder()
.url(notificationUrl)
.build())
.build())
.build();
private List<Subscription> createSubscriptionForType(Type type) {
var subscriptions = new ArrayList<Subscription>();
for (var notificationUrl : notificationUrls) {
var subscription = Subscription.builder()
.description("Subscription for " + type.getKey() + " type")
.subject(Subject.builder()
.entities(List.of(Entity.builder()
.idPattern(".*")
.type(type.getKey())
.build()))
.build())
.notification(Notification.builder()
.http(Http.builder()
.url(notificationUrl)
.build())
.build())
.build();
subscriptions.add(subscription);
}
return subscriptions;
}
}
14 changes: 14 additions & 0 deletions src/test/java/de/app/fivegla/fiware/AbstractIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package de.app.fivegla.fiware;

import java.util.List;

/**
* This class is an abstract base class for IT (Integration Testing) classes.
* It provides common properties and methods that can be used by concrete IT classes.
*/
public class AbstractIT {
protected String contextBrokerUrl = "http://localhost:1026";
protected String tenant = "default";
protected List<String> notificationUrls = List.of("http://192.168.56.1:5055/notify");

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import java.util.List;
import java.util.UUID;

class DeviceIntegrationServiceBasedOnTenantIT {
class DeviceIntegrationServiceBasedOnTenantIT extends AbstractIT {

@Test
void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnTheCurrentVersion() {
var fiwareIntegrationServiceForFoo = new DeviceIntegrationService("http://localhost:1026", "foo");
var fiwareIntegrationServiceForBar = new DeviceIntegrationService("http://localhost:1026", "bar");
var fiwareIntegrationServiceForFoo = new DeviceIntegrationService(contextBrokerUrl, "foo");
var fiwareIntegrationServiceForBar = new DeviceIntegrationService(contextBrokerUrl, "bar");

var deviceForFoo = Device.builder().id("integration-test:" + UUID.randomUUID()).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var deviceForBar = Device.builder().id("integration-test:" + UUID.randomUUID()).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.Farm21Sensor.getKey())).build()).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
import java.util.List;
import java.util.UUID;

class DeviceIntegrationServiceIT {
class DeviceIntegrationServiceIT extends AbstractIT {

@Test
void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnTheCurrentVersion() {
var fiwareIntegrationService = new DeviceIntegrationService("http://localhost:1026", "default");
var fiwareIntegrationService = new DeviceIntegrationService(contextBrokerUrl, tenant);
var device = Device.builder().id("integration-test:" + UUID.randomUUID()).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
fiwareIntegrationService.persist(device);
Assertions.assertTrue(fiwareIntegrationService.exists(device.getId()));
}

@Test
void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnException() {
var fiwareIntegrationService = new DeviceIntegrationService("http://localhost:1026", "default");
var fiwareIntegrationService = new DeviceIntegrationService(contextBrokerUrl, tenant);
var id = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(id).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
fiwareIntegrationService.persist(device);
Expand All @@ -32,7 +32,7 @@ void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnE

@Test
void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheValuesForTheDevice() {
var fiwareIntegrationService = new DeviceIntegrationService("http://localhost:1026", "default");
var fiwareIntegrationService = new DeviceIntegrationService(contextBrokerUrl, tenant);
var id = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(id).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
fiwareIntegrationService.persist(device);
Expand All @@ -51,7 +51,7 @@ void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheVal

@Test
void givenExistingDeviceWhenCheckingIfTheDeviceDoesExistTheServiceShouldReturnTrue() {
var fiwareIntegrationService = new DeviceIntegrationService("http://localhost:1026", "default");
var fiwareIntegrationService = new DeviceIntegrationService(contextBrokerUrl, tenant);
var id = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(id).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
fiwareIntegrationService.persist(device);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import java.util.List;
import java.util.UUID;

class DeviceMeasurementIntegrationServiceIT {
class DeviceMeasurementIntegrationServiceIT extends AbstractIT {

@Test
void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnTheCurrentVersion() {
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
var device = Device.builder().id("integration-test:" + UUID.randomUUID()).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
var deviceMeasurement = DeviceMeasurement.builder().id("integration-test:" + UUID.randomUUID()).refDevice(device.getId()).numValue(2.4).location(location).build();
Expand All @@ -25,7 +25,7 @@ void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnT

@Test
void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnException() {
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
String deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand All @@ -39,7 +39,7 @@ void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnE

@Test
void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheValuesForTheDevice() {
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
String deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand All @@ -63,7 +63,7 @@ void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheVal

@Test
void givenExistingDeviceWhenCheckingIfTheDeviceDoesExistTheServiceShouldReturnTrue() {
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
String deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import java.util.List;
import java.util.UUID;

class DroneDeviceMeasurementIntegrationServiceIT {
class DroneDeviceMeasurementIntegrationServiceIT extends AbstractIT {

@Test
void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnTheCurrentVersion() {
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
var device = Device.builder().id("integration-test:" + UUID.randomUUID()).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
var deviceMeasurement = DeviceMeasurement.builder().id("integration-test:" + UUID.randomUUID()).refDevice(device.getId()).numValue(2.4).location(location).build();
Expand All @@ -23,7 +23,7 @@ void givenExistingPackagePropertiesWhenFetchingTheVersionTheServiceShouldReturnT

@Test
void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnException() {
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
var deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand All @@ -39,7 +39,7 @@ void givenAlreadyExistingDeviceWhenCreatingNewDevicesTheServiceShouldNotThrowAnE

@Test
void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheValuesForTheDevice() {
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
var deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand All @@ -61,7 +61,7 @@ void givenAlreadyExistingDeviceWhenUpdatingTheDeviceTheServiceShouldUpdateTheVal

@Test
void givenExistingDeviceWhenCheckingIfTheDeviceDoesExistTheServiceShouldReturnTrue() {
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService("http://localhost:1026", "tenant");
var deviceMeasurementIntegrationService = new DroneDeviceMeasurementIntegrationService(contextBrokerUrl, tenant);
String deviceId = "integration-test:" + UUID.randomUUID();
var device = Device.builder().id(deviceId).deviceCategory(DeviceCategory.builder().value(List.of(DeviceCategoryValues.SoilScoutSensor.getKey())).build()).build();
var location = Location.builder().coordinates(List.of(1.0, 2.0)).build();
Expand Down
10 changes: 5 additions & 5 deletions src/test/java/de/app/fivegla/fiware/SubscriptionServiceIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class SubscriptionServiceIT {
class SubscriptionServiceIT extends AbstractIT {

@AfterEach
void tearDown() {
var fiwareIntegrationService = new SubscriptionService("http://localhost:1026", "default", "http://192.168.56.1:5055/notify");
var fiwareIntegrationService = new SubscriptionService(contextBrokerUrl, tenant, notificationUrls);
fiwareIntegrationService.removeAll(Type.Device);
}

@Test
void givenValidSubscriptionWhenSendingSubscriptionToFiwareThereShouldBeNoError() {
var fiwareIntegrationService = new SubscriptionService("http://localhost:1026", "default", "http://192.168.56.1:5055/notify");
var fiwareIntegrationService = new SubscriptionService(contextBrokerUrl, tenant, notificationUrls);
fiwareIntegrationService.subscribe(Type.Device);
var subscriptions = fiwareIntegrationService.findAll(Type.Device);
Assertions.assertNotNull(subscriptions);
}

@Test
void givenExistingSubscriptionWhenRemovingAllSubscriptionsTheNumberOfExistingSubscriptionsShouldBeNull() {
var fiwareIntegrationService = new SubscriptionService("http://localhost:1026", "default", "http://192.168.56.1:5055/notify");
var fiwareIntegrationService = new SubscriptionService(contextBrokerUrl, tenant, notificationUrls);
fiwareIntegrationService.subscribe(Type.Device);
var subscriptions = fiwareIntegrationService.findAll(Type.Device);
Assertions.assertNotNull(subscriptions);
Expand All @@ -36,7 +36,7 @@ void givenExistingSubscriptionWhenRemovingAllSubscriptionsTheNumberOfExistingSub

@Test
void givenExistingSubscriptionWhenSubscribingAndResettingTheNumberOfExistingSubscriptionsShouldStayTheSame() {
var fiwareIntegrationService = new SubscriptionService("http://localhost:1026", "default", "http://192.168.56.1:5055/notify");
var fiwareIntegrationService = new SubscriptionService(contextBrokerUrl, tenant, notificationUrls);
fiwareIntegrationService.subscribe(Type.Device);
var subscriptions = fiwareIntegrationService.findAll(Type.Device);
Assertions.assertNotNull(subscriptions);
Expand Down

0 comments on commit 9b932b9

Please sign in to comment.