From f05ce66242a8a1b24288936668d47a6812fec096 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 12:50:41 +0100 Subject: [PATCH 1/6] fix payload format --- .../ProtocolAdapterPublisherJsonPayload.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java index f60a9da4ea..5c59010b6d 100644 --- a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java +++ b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java @@ -16,6 +16,7 @@ package com.hivemq.edge.modules.adapters.data; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; import com.hivemq.extension.sdk.api.annotations.NotNull; import com.hivemq.extension.sdk.api.annotations.Nullable; @@ -25,14 +26,36 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class ProtocolAdapterPublisherJsonPayload extends AbstractProtocolAdapterJsonPayload { - private @NotNull TagSample sample; + @JsonProperty("value") + private @NotNull Value value; + + @JsonProperty("tagName") + private @Nullable String tagName; public ProtocolAdapterPublisherJsonPayload(final @Nullable Long timestamp, final @NotNull TagSample sample) { super(timestamp); - this.sample = sample; + this.value = new Value(sample.getTagValue()); + this.tagName = sample.getTagName(); + } + + @NotNull + public Object getValue() { + return value; } - public TagSample getSample() { - return sample; + @Nullable + public String getTagName() { + return tagName; + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + private static class Value{ + + @JsonProperty("data") + private @NotNull Object data; + + public Value(final @NotNull Object data) { + this.data = data; + } } } From 3d6375251714eb71b12fb134476fad4e1f7e4b9b Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 13:20:00 +0100 Subject: [PATCH 2/6] fix payload format --- .../data/ProtocolAdapterPublisherJsonPayload.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java index 5c59010b6d..e53d5fe3f2 100644 --- a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java +++ b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/data/ProtocolAdapterPublisherJsonPayload.java @@ -27,14 +27,14 @@ public class ProtocolAdapterPublisherJsonPayload extends AbstractProtocolAdapterJsonPayload { @JsonProperty("value") - private @NotNull Value value; + private @NotNull Object value; @JsonProperty("tagName") private @Nullable String tagName; public ProtocolAdapterPublisherJsonPayload(final @Nullable Long timestamp, final @NotNull TagSample sample) { super(timestamp); - this.value = new Value(sample.getTagValue()); + this.value = sample.getTagValue(); this.tagName = sample.getTagName(); } @@ -48,14 +48,5 @@ public String getTagName() { return tagName; } - @JsonInclude(JsonInclude.Include.NON_NULL) - private static class Value{ - @JsonProperty("data") - private @NotNull Object data; - - public Value(final @NotNull Object data) { - this.data = data; - } - } } From 59b21eefd4e5e65cd40ceb1999a2441a37d66d2b Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 14:34:49 +0100 Subject: [PATCH 3/6] add test for payload format for http --- .../impl/AbstractPollingProtocolAdapter.java | 4 +- .../hivemq-edge-module-http/build.gradle.kts | 1 + .../edge/adapters/http/HttpAdapterConfig.java | 52 +++++++------ .../adapters/http/HttpProtocolAdapter.java | 2 +- .../http/HttpProtocolAdapterTest.java | 74 +++++++++++++++++++ 5 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java diff --git a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractPollingProtocolAdapter.java b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractPollingProtocolAdapter.java index 4eebd5657c..79dd68a1d8 100644 --- a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractPollingProtocolAdapter.java +++ b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractPollingProtocolAdapter.java @@ -16,6 +16,7 @@ package com.hivemq.edge.modules.adapters.impl; import com.codahale.metrics.MetricRegistry; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.hivemq.edge.modules.adapters.data.AbstractProtocolAdapterJsonPayload; @@ -55,7 +56,8 @@ public AbstractPollingProtocolAdapter( super(adapterInformation, adapterConfig, metricRegistry); } - protected void bindServices(final @NotNull ModuleServices moduleServices){ + @VisibleForTesting + public void bindServices(final @NotNull ModuleServices moduleServices){ Preconditions.checkNotNull(moduleServices); super.bindServices(moduleServices); if(protocolAdapterPollingService == null){ diff --git a/modules/hivemq-edge-module-http/build.gradle.kts b/modules/hivemq-edge-module-http/build.gradle.kts index 9bde653db2..cc627d9361 100644 --- a/modules/hivemq-edge-module-http/build.gradle.kts +++ b/modules/hivemq-edge-module-http/build.gradle.kts @@ -57,6 +57,7 @@ dependencies { compileOnly("com.hivemq:hivemq-extension-sdk") testImplementation("org.apache.commons:commons-lang3:${property("commons-lang.version")}") testImplementation("commons-io:commons-io:${property("commons-io.version")}") + testImplementation("com.google.guava:guava:${property("guava.version")}") testImplementation("org.mockito:mockito-core:${property("mockito.version")}") testImplementation("org.junit.jupiter:junit-jupiter-api:${property("junit.jupiter.version")}") testImplementation("org.junit.jupiter:junit-jupiter-params:${property("junit.jupiter.version")}") diff --git a/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpAdapterConfig.java b/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpAdapterConfig.java index 90616799fa..2d06f68fbf 100644 --- a/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpAdapterConfig.java +++ b/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpAdapterConfig.java @@ -26,19 +26,22 @@ import java.util.ArrayList; import java.util.List; -@JsonPropertyOrder({"url", - "destination", - "qos", - "httpRequestMethod", - "httpConnectTimeout", - "httpRequestBodyContentType", - "httpRequestBody", - "httpPublishSuccessStatusCodeOnly", - "httpHeaders"}) +@JsonPropertyOrder({ + "url", + "destination", + "qos", + "httpRequestMethod", + "httpConnectTimeout", + "httpRequestBodyContentType", + "httpRequestBody", + "httpPublishSuccessStatusCodeOnly", + "httpHeaders"}) public class HttpAdapterConfig extends AbstractPollingProtocolAdapterConfig { public enum HttpMethod { - GET, POST, PUT + GET, + POST, + PUT } public enum HttpContentType { @@ -48,7 +51,7 @@ public enum HttpContentType { XML("application/xml"), YAML("application/yaml"); - HttpContentType(String contentType){ + HttpContentType(String contentType) { this.contentType = contentType; } @@ -60,11 +63,9 @@ public String getContentType() { } @JsonProperty("url") - @ModuleConfigField(title = "URL", - description = "The url of the http request you would like to make", + @ModuleConfigField(title = "URL", description = "The url of the http request you would like to make", // stringPattern = HttpConstants.HTTP_URL_REGEX, - format = ModuleConfigField.FieldType.URI, - required = true) + format = ModuleConfigField.FieldType.URI, required = true) private @NotNull String url; @JsonProperty(value = "destination", required = true) @@ -96,18 +97,18 @@ public String getContentType() { private @NotNull HttpAdapterConfig.HttpContentType httpRequestBodyContentType = HttpContentType.JSON; @JsonProperty("httpRequestBody") - @ModuleConfigField(title = "Http Request Body", - description = "The body to include in the HTTP request") + @ModuleConfigField(title = "Http Request Body", description = "The body to include in the HTTP request") private @NotNull String httpRequestBody; @JsonProperty("httpConnectTimeout") @ModuleConfigField(title = "Http Connection Timeout", - description = "Timeout (in second) to wait for the HTTP Request to complete", required = true, defaultValue = HttpAdapterConstants.DEFAULT_TIMEOUT_SECONDS + "") + description = "Timeout (in second) to wait for the HTTP Request to complete", + required = true, + defaultValue = HttpAdapterConstants.DEFAULT_TIMEOUT_SECONDS + "") private @NotNull Integer httpConnectTimeout = HttpAdapterConstants.DEFAULT_TIMEOUT_SECONDS; @JsonProperty("httpHeaders") - @ModuleConfigField(title = "HTTP Headers", - description = "HTTP headers to be added to your requests") + @ModuleConfigField(title = "HTTP Headers", description = "HTTP headers to be added to your requests") private @NotNull List httpHeaders = new ArrayList<>(); @JsonProperty("httpPublishSuccessStatusCodeOnly") @@ -125,9 +126,14 @@ public String getContentType() { public HttpAdapterConfig() { } + public HttpAdapterConfig(final @NotNull String adapterId) { + this.id = adapterId; + } + public boolean isHttpPublishSuccessStatusCodeOnly() { return httpPublishSuccessStatusCodeOnly; } + public @NotNull HttpMethod getHttpRequestMethod() { return httpRequestMethod; } @@ -167,13 +173,11 @@ public boolean isAllowUntrustedCertificates() { public static class HttpHeader { @JsonProperty("name") - @ModuleConfigField(title = "Http Header Name", - description = "The name of the HTTP header") + @ModuleConfigField(title = "Http Header Name", description = "The name of the HTTP header") private String name; @JsonProperty("value") - @ModuleConfigField(title = "Http Header Value", - description = "The value of the HTTP header") + @ModuleConfigField(title = "Http Header Value", description = "The value of the HTTP header") private String value; public HttpHeader() { diff --git a/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpProtocolAdapter.java b/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpProtocolAdapter.java index 197de6fbc8..1ff1e56ddf 100644 --- a/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpProtocolAdapter.java +++ b/modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpProtocolAdapter.java @@ -52,7 +52,7 @@ */ public class HttpProtocolAdapter extends AbstractPollingProtocolAdapter { - private static final String RESPONSE_DATA = "httpResponseData"; + static final String RESPONSE_DATA = "httpResponseData"; private static final Logger log = LoggerFactory.getLogger(HttpProtocolAdapter.class); private HttpClient httpClient = null; diff --git a/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java b/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java new file mode 100644 index 0000000000..ab03c197ec --- /dev/null +++ b/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java @@ -0,0 +1,74 @@ +package com.hivemq.edge.adapters.http; + +import com.codahale.metrics.MetricRegistry; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableMap; +import com.hivemq.edge.adapters.http.model.HttpData; +import com.hivemq.edge.modules.adapters.impl.ProtocolAdapterPublishBuilderImpl; +import com.hivemq.edge.modules.api.adapters.ModuleServices; +import com.hivemq.edge.modules.api.adapters.ProtocolAdapterPublishService; +import com.hivemq.edge.modules.api.events.EventService; +import com.hivemq.edge.modules.config.impl.AbstractProtocolAdapterConfig; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.mqtt.handler.publish.PublishReturnCode; +import com.hivemq.mqtt.message.publish.PUBLISH; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static com.hivemq.edge.adapters.http.HttpProtocolAdapter.RESPONSE_DATA; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class HttpProtocolAdapterTest { + + private final @NotNull MetricRegistry metricRegistry = new MetricRegistry(); + private final @NotNull HttpAdapterConfig httpAdapterConfig = new HttpAdapterConfig("adapterId"); + private final @NotNull HttpProtocolAdapter httpProtocolAdapter = + new HttpProtocolAdapter(HttpProtocolAdapterInformation.INSTANCE, httpAdapterConfig, metricRegistry); + private final @NotNull ProtocolAdapterPublishService publishService = mock(ProtocolAdapterPublishService.class); + private final @NotNull ModuleServices moduleServices = mock(ModuleServices.class); + private final @NotNull ProtocolAdapterPublishBuilderImpl.SendCallback sendCallback = + mock(ProtocolAdapterPublishBuilderImpl.SendCallback.class); + private final @NotNull ArgumentCaptor publishArgumentCaptor = ArgumentCaptor.forClass(PUBLISH.class); + + @BeforeEach + void setUp() { + when(moduleServices.adapterPublishService()).thenReturn(publishService); + when(moduleServices.eventService()).thenReturn(mock(EventService.class)); + httpProtocolAdapter.bindServices(moduleServices); + //noinspection unchecked + when(sendCallback.onPublishSend(publishArgumentCaptor.capture(), any(), any(ImmutableMap.class))).thenReturn( + CompletableFuture.completedFuture(PublishReturnCode.DELIVERED)); + final ProtocolAdapterPublishBuilderImpl protocolAdapterPublishBuilder = + new ProtocolAdapterPublishBuilderImpl("hivemq", sendCallback); + protocolAdapterPublishBuilder.withAdapter(httpProtocolAdapter); + when(publishService.publish()).thenReturn(protocolAdapterPublishBuilder); + } + + @Test + void test_captureDataSample_expectedPayloadPresent() throws ExecutionException, InterruptedException, JsonProcessingException { + final AbstractProtocolAdapterConfig.Subscription subscription = + new AbstractProtocolAdapterConfig.Subscription("topic", 2); + final HttpData httpData = new HttpData(subscription, "http://localhost:8080", 200, "text/plain"); + httpData.addDataPoint(RESPONSE_DATA, "hello world"); + + httpProtocolAdapter.captureDataSample(httpData).get(); + + final String payloadAsString = new String(publishArgumentCaptor.getValue().getPayload()); + System.out.println(payloadAsString); + ObjectMapper objectMapper = new ObjectMapper(); + final JsonNode tree = objectMapper.readTree(payloadAsString); + assertTrue(tree.get("timestamp").isIntegralNumber()); + assertEquals(tree.get("value").asText(), "hello world"); + } + +} From 64fbf54b8ec4b5dba899d461773c7b34d6d73019 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 14:51:43 +0100 Subject: [PATCH 4/6] add payload test for ModbusProtocolAdapter --- .../impl/AbstractProtocolAdapter.java | 4 +- .../build.gradle.kts | 4 + .../adapters/modbus/ModbusAdapterConfig.java | 4 + .../modbus/ModbusProtocolAdapterTest.java | 74 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java diff --git a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java index 651aa32101..ba9b643403 100644 --- a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java +++ b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java @@ -19,6 +19,7 @@ import com.codahale.metrics.MetricRegistry; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.hivemq.edge.model.TypeIdentifier; import com.hivemq.edge.modules.adapters.ProtocolAdapterException; @@ -156,7 +157,8 @@ public byte[] convertToJson(final @NotNull AbstractProtocolAdapterJsonPayload da } } - protected void bindServices(final @NotNull ModuleServices moduleServices){ + @VisibleForTesting + public void bindServices(final @NotNull ModuleServices moduleServices){ Preconditions.checkNotNull(moduleServices); if(adapterPublishService == null){ adapterPublishService = moduleServices.adapterPublishService(); diff --git a/modules/hivemq-edge-module-modbus/build.gradle.kts b/modules/hivemq-edge-module-modbus/build.gradle.kts index de904dbf5a..6f1b7313ae 100644 --- a/modules/hivemq-edge-module-modbus/build.gradle.kts +++ b/modules/hivemq-edge-module-modbus/build.gradle.kts @@ -54,6 +54,10 @@ configurations { } dependencies { + testImplementation("com.hivemq:hivemq-edge") + compileOnly("com.hivemq:hivemq-extension-sdk") + testImplementation("com.google.guava:guava:${property("guava.version")}") + testImplementation("org.mockito:mockito-core:${property("mockito.version")}") testImplementation("org.junit.jupiter:junit-jupiter-api:${property("junit.jupiter.version")}") testImplementation("org.junit.jupiter:junit-jupiter-params:${property("junit.jupiter.version")}") testImplementation("org.junit.platform:junit-platform-launcher:${property("junit.jupiter.platform.version")}") diff --git a/modules/hivemq-edge-module-modbus/src/main/java/com/hivemq/edge/adapters/modbus/ModbusAdapterConfig.java b/modules/hivemq-edge-module-modbus/src/main/java/com/hivemq/edge/adapters/modbus/ModbusAdapterConfig.java index 0c39ff6357..8a7cee0389 100644 --- a/modules/hivemq-edge-module-modbus/src/main/java/com/hivemq/edge/adapters/modbus/ModbusAdapterConfig.java +++ b/modules/hivemq-edge-module-modbus/src/main/java/com/hivemq/edge/adapters/modbus/ModbusAdapterConfig.java @@ -69,6 +69,10 @@ public class ModbusAdapterConfig extends AbstractPollingProtocolAdapterConfig { public ModbusAdapterConfig() { } + public ModbusAdapterConfig(final @NotNull String adapterId) { + this.id = adapterId; + } + public boolean getPublishChangedDataOnly() { return publishChangedDataOnly; } diff --git a/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java b/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java new file mode 100644 index 0000000000..cf8e69ccf5 --- /dev/null +++ b/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java @@ -0,0 +1,74 @@ +package com.hivemq.edge.adapters.modbus; + +import com.codahale.metrics.MetricRegistry; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableMap; +import com.hivemq.edge.adapters.modbus.model.ModBusData; +import com.hivemq.edge.modules.adapters.impl.ProtocolAdapterPublishBuilderImpl; +import com.hivemq.edge.modules.api.adapters.ModuleServices; +import com.hivemq.edge.modules.api.adapters.ProtocolAdapterPublishService; +import com.hivemq.edge.modules.api.events.EventService; +import com.hivemq.edge.modules.config.impl.AbstractProtocolAdapterConfig; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.mqtt.handler.publish.PublishReturnCode; +import com.hivemq.mqtt.message.publish.PUBLISH; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ModbusProtocolAdapterTest { + + private final @NotNull MetricRegistry metricRegistry = new MetricRegistry(); + private final @NotNull ModbusAdapterConfig adapterConfig = new ModbusAdapterConfig("adapterId"); + private final @NotNull ModbusProtocolAdapter adapter = + new ModbusProtocolAdapter(ModbusProtocolAdapterInformation.INSTANCE, adapterConfig, metricRegistry); + private final @NotNull ProtocolAdapterPublishService publishService = mock(ProtocolAdapterPublishService.class); + private final @NotNull ModuleServices moduleServices = mock(ModuleServices.class); + private final @NotNull ProtocolAdapterPublishBuilderImpl.SendCallback sendCallback = + mock(ProtocolAdapterPublishBuilderImpl.SendCallback.class); + private final @NotNull ArgumentCaptor publishArgumentCaptor = ArgumentCaptor.forClass(PUBLISH.class); + + @BeforeEach + void setUp() { + when(moduleServices.adapterPublishService()).thenReturn(publishService); + when(moduleServices.eventService()).thenReturn(mock(EventService.class)); + adapter.bindServices(moduleServices); + //noinspection unchecked + when(sendCallback.onPublishSend(publishArgumentCaptor.capture(), any(), any(ImmutableMap.class))).thenReturn( + CompletableFuture.completedFuture(PublishReturnCode.DELIVERED)); + final ProtocolAdapterPublishBuilderImpl protocolAdapterPublishBuilder = + new ProtocolAdapterPublishBuilderImpl("hivemq", sendCallback); + protocolAdapterPublishBuilder.withAdapter(adapter); + when(publishService.publish()).thenReturn(protocolAdapterPublishBuilder); + } + + @Test + void test_captureDataSample_expectedPayloadPresent() + throws ExecutionException, InterruptedException, JsonProcessingException { + final AbstractProtocolAdapterConfig.Subscription subscription = + new AbstractProtocolAdapterConfig.Subscription("topic", 2); + final ModBusData data = new ModBusData(subscription, ModBusData.TYPE.INPUT_REGISTERS); + data.addDataPoint("register", "hello world"); + + adapter.captureDataSample(data).get(); + + final String payloadAsString = new String(publishArgumentCaptor.getValue().getPayload()); + System.out.println(payloadAsString); + ObjectMapper objectMapper = new ObjectMapper(); + final JsonNode tree = objectMapper.readTree(payloadAsString); + assertTrue(tree.get("timestamp").isIntegralNumber()); + assertEquals(tree.get("value").asText(), "hello world"); + } + +} From 545223a10e06df26fbe8fe30133ab8ef5f6ded64 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 15:22:49 +0100 Subject: [PATCH 5/6] add JsonAssertions and use them in unit test --- .../adapters/impl/AbstractProtocolAdapter.java | 3 ++- modules/hivemq-edge-module-http/build.gradle.kts | 1 + .../hivemq-edge-module-http/gradle.properties | 1 + .../adapters/http/HttpProtocolAdapterTest.java | 16 +++++----------- .../hivemq-edge-module-modbus/build.gradle.kts | 1 + .../hivemq-edge-module-modbus/gradle.properties | 1 + .../modbus/ModbusProtocolAdapterTest.java | 12 +++--------- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java index ba9b643403..8ac935ff2b 100644 --- a/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java +++ b/hivemq-edge/src/main/java/com/hivemq/edge/modules/adapters/impl/AbstractProtocolAdapter.java @@ -42,6 +42,7 @@ import com.hivemq.edge.modules.api.events.EventUtils; import com.hivemq.edge.modules.api.events.model.Event; import com.hivemq.edge.modules.config.impl.AbstractProtocolAdapterConfig; +import com.hivemq.edge.modules.config.impl.AbstractProtocolAdapterConfig.Subscription.MessageHandlingOptions; import com.hivemq.extension.sdk.api.annotations.NotNull; import com.hivemq.extension.sdk.api.annotations.Nullable; import org.slf4j.Logger; @@ -118,7 +119,7 @@ public List convertAdapterSampleToPublishes( Long timestamp = data.getSubscription().getIncludeTimestamp() ? data.getTimestamp() : null; if(data.getDataPoints().size() > 1 && data.getSubscription().getMessageHandlingOptions() == - AbstractProtocolAdapterConfig.Subscription.MessageHandlingOptions.MQTTMessagePerSubscription){ + MessageHandlingOptions.MQTTMessagePerSubscription){ //-- Put all derived samples into a single MQTT message list.add(createMultiPublishPayload(timestamp, data.getDataPoints(), data.getSubscription().getIncludeTagNames())); } else { diff --git a/modules/hivemq-edge-module-http/build.gradle.kts b/modules/hivemq-edge-module-http/build.gradle.kts index cc627d9361..e67570931c 100644 --- a/modules/hivemq-edge-module-http/build.gradle.kts +++ b/modules/hivemq-edge-module-http/build.gradle.kts @@ -65,6 +65,7 @@ dependencies { testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${property("junit.jupiter.version")}") testImplementation("org.mockito:mockito-core:${property("mockito.version")}") testImplementation("org.mockito:mockito-junit-jupiter:${property("mockito.version")}") + testImplementation("net.javacrumbs.json-unit:json-unit-assertj:${property("jsonUnit")}") } tasks.test { diff --git a/modules/hivemq-edge-module-http/gradle.properties b/modules/hivemq-edge-module-http/gradle.properties index eab0425207..64630e413d 100644 --- a/modules/hivemq-edge-module-http/gradle.properties +++ b/modules/hivemq-edge-module-http/gradle.properties @@ -14,6 +14,7 @@ junit.jupiter.platform.version=1.7.1 mockito.version=4.7.0 commons-lang.version=3.11 commons-io.version=2.8.0 +jsonUnit = 3.2.2 # logging slf4j.version=1.7.30 diff --git a/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java b/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java index ab03c197ec..925921aba8 100644 --- a/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java +++ b/modules/hivemq-edge-module-http/src/test/java/com/hivemq/edge/adapters/http/HttpProtocolAdapterTest.java @@ -2,8 +2,6 @@ import com.codahale.metrics.MetricRegistry; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.hivemq.edge.adapters.http.model.HttpData; import com.hivemq.edge.modules.adapters.impl.ProtocolAdapterPublishBuilderImpl; @@ -22,8 +20,7 @@ import java.util.concurrent.ExecutionException; import static com.hivemq.edge.adapters.http.HttpProtocolAdapter.RESPONSE_DATA; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -55,7 +52,8 @@ void setUp() { } @Test - void test_captureDataSample_expectedPayloadPresent() throws ExecutionException, InterruptedException, JsonProcessingException { + void test_captureDataSample_expectedPayloadPresent() + throws ExecutionException, InterruptedException, JsonProcessingException { final AbstractProtocolAdapterConfig.Subscription subscription = new AbstractProtocolAdapterConfig.Subscription("topic", 2); final HttpData httpData = new HttpData(subscription, "http://localhost:8080", 200, "text/plain"); @@ -64,11 +62,7 @@ void test_captureDataSample_expectedPayloadPresent() throws ExecutionException, httpProtocolAdapter.captureDataSample(httpData).get(); final String payloadAsString = new String(publishArgumentCaptor.getValue().getPayload()); - System.out.println(payloadAsString); - ObjectMapper objectMapper = new ObjectMapper(); - final JsonNode tree = objectMapper.readTree(payloadAsString); - assertTrue(tree.get("timestamp").isIntegralNumber()); - assertEquals(tree.get("value").asText(), "hello world"); + assertThatJson(payloadAsString).node("timestamp").isIntegralNumber(); + assertThatJson(payloadAsString).node("value").isString().isEqualTo("hello world"); } - } diff --git a/modules/hivemq-edge-module-modbus/build.gradle.kts b/modules/hivemq-edge-module-modbus/build.gradle.kts index 6f1b7313ae..e5ad2e6667 100644 --- a/modules/hivemq-edge-module-modbus/build.gradle.kts +++ b/modules/hivemq-edge-module-modbus/build.gradle.kts @@ -64,6 +64,7 @@ dependencies { testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${property("junit.jupiter.version")}") testImplementation("org.mockito:mockito-core:${property("mockito.version")}") testImplementation("org.mockito:mockito-junit-jupiter:${property("mockito.version")}") + testImplementation("net.javacrumbs.json-unit:json-unit-assertj:${property("jsonUnit")}") } tasks.test { diff --git a/modules/hivemq-edge-module-modbus/gradle.properties b/modules/hivemq-edge-module-modbus/gradle.properties index ffaf7b9d71..12a6ef0629 100644 --- a/modules/hivemq-edge-module-modbus/gradle.properties +++ b/modules/hivemq-edge-module-modbus/gradle.properties @@ -12,6 +12,7 @@ guava.version=32.0.1-jre junit.jupiter.version=5.7.1 junit.jupiter.platform.version=1.7.1 mockito.version=4.7.0 +jsonUnit = 3.2.2 # logging slf4j.version=1.7.30 logback.version=1.2.3 diff --git a/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java b/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java index cf8e69ccf5..87fc7edece 100644 --- a/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java +++ b/modules/hivemq-edge-module-modbus/src/test/java/com/hivemq/edge/adapters/modbus/ModbusProtocolAdapterTest.java @@ -2,8 +2,6 @@ import com.codahale.metrics.MetricRegistry; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.hivemq.edge.adapters.modbus.model.ModBusData; import com.hivemq.edge.modules.adapters.impl.ProtocolAdapterPublishBuilderImpl; @@ -21,8 +19,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -64,11 +61,8 @@ void test_captureDataSample_expectedPayloadPresent() adapter.captureDataSample(data).get(); final String payloadAsString = new String(publishArgumentCaptor.getValue().getPayload()); - System.out.println(payloadAsString); - ObjectMapper objectMapper = new ObjectMapper(); - final JsonNode tree = objectMapper.readTree(payloadAsString); - assertTrue(tree.get("timestamp").isIntegralNumber()); - assertEquals(tree.get("value").asText(), "hello world"); + assertThatJson(payloadAsString).node("timestamp").isIntegralNumber(); + assertThatJson(payloadAsString).node("value").isString().isEqualTo("hello world"); } } From abe962154a92b695fb003205ff9d591d1ae65178 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 17 Nov 2023 15:31:42 +0100 Subject: [PATCH 6/6] reduce jsonUnit version --- modules/hivemq-edge-module-http/gradle.properties | 2 +- modules/hivemq-edge-module-modbus/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/hivemq-edge-module-http/gradle.properties b/modules/hivemq-edge-module-http/gradle.properties index 64630e413d..516a9df70e 100644 --- a/modules/hivemq-edge-module-http/gradle.properties +++ b/modules/hivemq-edge-module-http/gradle.properties @@ -14,7 +14,7 @@ junit.jupiter.platform.version=1.7.1 mockito.version=4.7.0 commons-lang.version=3.11 commons-io.version=2.8.0 -jsonUnit = 3.2.2 +jsonUnit = 2.38.0 # logging slf4j.version=1.7.30 diff --git a/modules/hivemq-edge-module-modbus/gradle.properties b/modules/hivemq-edge-module-modbus/gradle.properties index 12a6ef0629..9099a5d005 100644 --- a/modules/hivemq-edge-module-modbus/gradle.properties +++ b/modules/hivemq-edge-module-modbus/gradle.properties @@ -12,7 +12,7 @@ guava.version=32.0.1-jre junit.jupiter.version=5.7.1 junit.jupiter.platform.version=1.7.1 mockito.version=4.7.0 -jsonUnit = 3.2.2 +jsonUnit = 2.38.0 # logging slf4j.version=1.7.30 logback.version=1.2.3