From bc92b985d8d91dc688eec92f7d2a148e692dae59 Mon Sep 17 00:00:00 2001 From: Sascha Doemer Date: Tue, 23 Apr 2024 15:59:30 +0200 Subject: [PATCH] Feature/add device positions to data model (#53) * Add DevicePosition model and integration service This commit introduces a new DevicePosition model. It is used to store the position of a device within the FIWARE system. A DevicePositionIntegrationService has also been added for persisting the DevicePosition entities. Additionally, this commit refactors the DeviceMeasurement model to leverage the FiwareEntity interface for creating a JSON representation. * Update type for 'entities' in UpdateOrCreateDeviceMeasurementRequest The type of 'entities' in UpdateOrCreateDeviceMeasurementRequest has been changed from DeviceMeasurement to FiwareEntity. This change involved adjusting related methods to match the new type. It was also necessary to adjust imports as a consequence of this type change. * Update type for 'entities' in UpdateOrCreateDeviceMeasurementRequest The type of 'entities' in UpdateOrCreateDeviceMeasurementRequest has been changed from DeviceMeasurement to FiwareEntity. This change involved adjusting related methods to match the new type. It was also necessary to adjust imports as a consequence of this type change. * Update project version in pom.xml The project version in the pom.xml file has been updated from 13.0.0 to 14.0.0. This version increment indicates the completion of new features or significant changes to the existing codebase. --- pom.xml | 2 +- .../DevicePositiontIntegrationService.java | 55 +++++++++++++++++++ .../fiware/model/DeviceMeasurement.java | 21 +------ .../fivegla/fiware/model/DevicePosition.java | 43 +++++++++++++++ .../fivegla/fiware/model/FiwareEntity.java | 31 +++++++++++ ...pdateOrCreateDeviceMeasurementRequest.java | 6 +- 6 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/app/fivegla/fiware/DevicePositiontIntegrationService.java create mode 100644 src/main/java/de/app/fivegla/fiware/model/DevicePosition.java create mode 100644 src/main/java/de/app/fivegla/fiware/model/FiwareEntity.java diff --git a/pom.xml b/pom.xml index aec057a..33b832b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.app.5gla fiware-integration-layer - 13.0.0 + 14.0.0 5gLa FIWARE integration layer https://github.com/vitrum-connect/5gla-fiware-integration-layer diff --git a/src/main/java/de/app/fivegla/fiware/DevicePositiontIntegrationService.java b/src/main/java/de/app/fivegla/fiware/DevicePositiontIntegrationService.java new file mode 100644 index 0000000..341e5af --- /dev/null +++ b/src/main/java/de/app/fivegla/fiware/DevicePositiontIntegrationService.java @@ -0,0 +1,55 @@ +package de.app.fivegla.fiware; + +import de.app.fivegla.fiware.api.CustomHeader; +import de.app.fivegla.fiware.api.FiwareIntegrationLayerException; +import de.app.fivegla.fiware.model.DevicePosition; +import de.app.fivegla.fiware.request.UpdateOrCreateDeviceMeasurementRequest; +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; + +/** + * Integration service for FIWARE to send requests to the context broker. + */ +@Slf4j +public class DevicePositiontIntegrationService extends AbstractIntegrationService { + + public DevicePositiontIntegrationService(String contextBrokerUrl, String tenant) { + super(contextBrokerUrl, tenant); + } + + /** + * Creates a new device in the context broker. + * + * @param entity the device to create + */ + public void persist(DevicePosition entity) { + var updateOrCreateEntityRequest = UpdateOrCreateDeviceMeasurementRequest.builder() + .entities(List.of(entity)) + .build(); + var httpClient = HttpClient.newHttpClient(); + var httpRequest = HttpRequest.newBuilder() + .uri(URI.create(contextBrokerUrlForCommands() + "/op/update")) + .header("Content-Type", "application/json") + .header(CustomHeader.FIWARE_SERVICE, getTenant()) + .POST(HttpRequest.BodyPublishers.ofString(updateOrCreateEntityRequest.asJson())).build(); + try { + var response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 204) { + log.error("Could not create entity. Response: " + response.body()); + log.debug("Request: " + updateOrCreateEntityRequest.asJson()); + log.debug("Response: " + response.body()); + throw new FiwareIntegrationLayerException("Could not create entity, there was an error from FIWARE."); + } else { + log.info("Device created/updated successfully."); + } + } catch (Exception e) { + throw new FiwareIntegrationLayerException("Could not create/update entity", e); + } + } + +} diff --git a/src/main/java/de/app/fivegla/fiware/model/DeviceMeasurement.java b/src/main/java/de/app/fivegla/fiware/model/DeviceMeasurement.java index 70a3bf9..8fc705b 100644 --- a/src/main/java/de/app/fivegla/fiware/model/DeviceMeasurement.java +++ b/src/main/java/de/app/fivegla/fiware/model/DeviceMeasurement.java @@ -1,6 +1,5 @@ package de.app.fivegla.fiware.model; -import de.app.fivegla.fiware.api.FiwareType; import de.app.fivegla.fiware.model.api.Validatable; import de.app.fivegla.fiware.model.internal.Attribute; import org.apache.commons.lang3.StringUtils; @@ -17,9 +16,9 @@ public record DeviceMeasurement( Attribute externalDataReference, double latitude, double longitude -) implements Validatable { - +) implements FiwareEntity, Validatable { + @Override public String asJson() { validate(); return "{" + @@ -29,24 +28,10 @@ public String asJson() { " \"controlledProperty\":" + controlledProperty.asJson() + "," + " \"externalDataReference\":" + externalDataReference.asJson() + "," + " \"dateCreated\":" + dateCreated.asJson() + "," + - " \"location\":" + locationAsJson() + + " \"location\":" + locationAsJson(latitude, longitude) + "}"; } - private String locationAsJson() { - if (latitude == 0.0 && longitude == 0.0) { - return "{}"; - } else { - return "{" + - " \"type\":\"" + FiwareType.GEO_JSON.getKey() + "\"," + - " \"value\": {" + - " \"type\":\"Point\"," + - " \"coordinates\": [" + longitude + "," + latitude + "]" + - " }" + - "}"; - } - } - @Override public void validate() { if (StringUtils.isBlank(id)) { diff --git a/src/main/java/de/app/fivegla/fiware/model/DevicePosition.java b/src/main/java/de/app/fivegla/fiware/model/DevicePosition.java new file mode 100644 index 0000000..e5fd1ad --- /dev/null +++ b/src/main/java/de/app/fivegla/fiware/model/DevicePosition.java @@ -0,0 +1,43 @@ +package de.app.fivegla.fiware.model; + +import de.app.fivegla.fiware.model.api.Validatable; +import de.app.fivegla.fiware.model.internal.Attribute; +import org.apache.commons.lang3.StringUtils; + +/** + * Device position. + */ +public record DevicePosition( + String id, + String type, + Attribute transactionId, + Attribute deviceId, + Attribute dateCreated, + double latitude, + double longitude +) implements Validatable, FiwareEntity { + + @Override + public String asJson() { + validate(); + return "{" + + " \"id\":\"" + id + "\"," + + " \"type\":\"" + type + "\"," + + " \"transactionId\":" + transactionId.asJson() + "," + + " \"deviceId\":" + deviceId.asJson() + "," + + " \"dateCreated\":" + dateCreated.asJson() + "," + + " \"location\":" + locationAsJson(latitude, longitude) + + "}"; + } + + @Override + public void validate() { + if (StringUtils.isBlank(id)) { + throw new IllegalArgumentException("The id of the device position must not be null or blank."); + } + if (StringUtils.isBlank(type)) { + throw new IllegalArgumentException("The type of the device position must not be null or blank."); + } + } + +} diff --git a/src/main/java/de/app/fivegla/fiware/model/FiwareEntity.java b/src/main/java/de/app/fivegla/fiware/model/FiwareEntity.java new file mode 100644 index 0000000..b838e1a --- /dev/null +++ b/src/main/java/de/app/fivegla/fiware/model/FiwareEntity.java @@ -0,0 +1,31 @@ +package de.app.fivegla.fiware.model; + +import de.app.fivegla.fiware.api.FiwareType; + +/** + * The FiwareEntity interface represents an entity in the Fiware system. + * Implementing classes should provide a JSON representation of the entity. + */ +public interface FiwareEntity { + + /** + * Converts the FiwareEntity object to JSON format. + * + * @return The FiwareEntity object in JSON format. + */ + String asJson(); + + default String locationAsJson(double latitude, double longitude) { + if (latitude == 0.0 && longitude == 0.0) { + return "{}"; + } else { + return "{" + + " \"type\":\"" + FiwareType.GEO_JSON.getKey() + "\"," + + " \"value\": {" + + " \"type\":\"Point\"," + + " \"coordinates\": [" + longitude + "," + latitude + "]" + + " }" + + "}"; + } + } +} diff --git a/src/main/java/de/app/fivegla/fiware/request/UpdateOrCreateDeviceMeasurementRequest.java b/src/main/java/de/app/fivegla/fiware/request/UpdateOrCreateDeviceMeasurementRequest.java index f73b89c..6280563 100644 --- a/src/main/java/de/app/fivegla/fiware/request/UpdateOrCreateDeviceMeasurementRequest.java +++ b/src/main/java/de/app/fivegla/fiware/request/UpdateOrCreateDeviceMeasurementRequest.java @@ -1,6 +1,6 @@ package de.app.fivegla.fiware.request; -import de.app.fivegla.fiware.model.DeviceMeasurement; +import de.app.fivegla.fiware.model.FiwareEntity; import de.app.fivegla.fiware.request.enums.ActionType; import lombok.Builder; import lombok.Getter; @@ -25,13 +25,13 @@ public class UpdateOrCreateDeviceMeasurementRequest { /** * The entities. */ - private List entities; + private List entities; public String asJson() { return "{\"actionType\":\"" + actionType + "\",\"entities\":[" + entitiesAsJson() + "]}"; } private String entitiesAsJson() { - return entities.stream().map(DeviceMeasurement::asJson).collect(Collectors.joining(",")); + return entities.stream().map(FiwareEntity::asJson).collect(Collectors.joining(",")); } }