Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/fix breaking changes in payload #202

Merged
merged 6 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -25,14 +26,27 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProtocolAdapterPublisherJsonPayload extends AbstractProtocolAdapterJsonPayload {

private @NotNull TagSample sample;
@JsonProperty("value")
private @NotNull Object value;

@JsonProperty("tagName")
private @Nullable String tagName;

public ProtocolAdapterPublisherJsonPayload(final @Nullable Long timestamp, final @NotNull TagSample sample) {
super(timestamp);
this.sample = sample;
this.value = sample.getTagValue();
this.tagName = sample.getTagName();
}

@NotNull
public Object getValue() {
return value;
}

public TagSample getSample() {
return sample;
@Nullable
public String getTagName() {
return tagName;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -41,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;
Expand Down Expand Up @@ -117,7 +119,7 @@ public List<AbstractProtocolAdapterJsonPayload> 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 {
Expand Down Expand Up @@ -156,7 +158,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();
Expand Down
2 changes: 2 additions & 0 deletions modules/hivemq-edge-module-http/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ 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")}")
testImplementation("org.junit.platform:junit-platform-launcher:${property("junit.jupiter.platform.version")}")
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 {
Expand Down
1 change: 1 addition & 0 deletions modules/hivemq-edge-module-http/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 2.38.0

# logging
slf4j.version=1.7.30
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -48,7 +51,7 @@ public enum HttpContentType {
XML("application/xml"),
YAML("application/yaml");

HttpContentType(String contentType){
HttpContentType(String contentType) {
this.contentType = contentType;
}

Expand All @@ -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)
Expand Down Expand Up @@ -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<HttpHeader> httpHeaders = new ArrayList<>();

@JsonProperty("httpPublishSuccessStatusCodeOnly")
Expand All @@ -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;
}
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
*/
public class HttpProtocolAdapter extends AbstractPollingProtocolAdapter<HttpAdapterConfig, HttpData> {

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;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.hivemq.edge.adapters.http;

import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.core.JsonProcessingException;
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 net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
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<PUBLISH> 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());
assertThatJson(payloadAsString).node("timestamp").isIntegralNumber();
assertThatJson(payloadAsString).node("value").isString().isEqualTo("hello world");
}
}
5 changes: 5 additions & 0 deletions modules/hivemq-edge-module-modbus/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@ 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")}")
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 {
Expand Down
1 change: 1 addition & 0 deletions modules/hivemq-edge-module-modbus/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 2.38.0
# logging
slf4j.version=1.7.30
logback.version=1.2.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading
Loading