Skip to content

Commit

Permalink
S7 working with new sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
codepitbull committed Dec 13, 2024
1 parent 31cfa9d commit 14d9f2e
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 125 deletions.
8 changes: 3 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
apache-commonsIO = "2.17.0"
apache-commonsIO = "2.18.0"
apache-commonsCompress = "1.27.1"
apache-commonsLang = "3.17.0"
apache-plc4x = "0.11.0"
Expand All @@ -8,7 +8,7 @@ awaitility = "4.2.2"
bouncycastle = "1.70"
byteBuddy = "1.15.5"
concurrentUnit = "0.4.6"
dagger = "2.52"
dagger = "2.53.1"
dropwizard-metrics = "4.2.28"
equalsVerifier = "3.17.1"
future-converter = "1.2.0"
Expand All @@ -30,7 +30,6 @@ jctools = "4.0.5"
jersey = "2.45"
jose4j = "0.9.6"
jsonSchemaValidator = "1.5.2"
jsonSchemaInferrer = "0.2.1"
junit-jupiter = "5.11.2"
junit = "4.13.2"
logback = "1.5.11"
Expand All @@ -45,7 +44,7 @@ slf4j = "2.0.16"
spotBugs = "4.8.5"
stefanBirkner-systemRules = "1.19.0"
swagger-annotations = "2.2.25"
victools-jsonschema = "4.36.0"
victools-jsonschema = "4.37.0"
wiremock = "3.0.1"
zeroAllocationHashing = "0.16"

Expand Down Expand Up @@ -90,7 +89,6 @@ javax-annotation-api = { module = "javax.annotation:javax.annotation-api", versi
jaxb-impl = { module = "com.sun.xml.bind:jaxb-impl", version.ref = "jaxb" }
jctools = { module = "org.jctools:jctools-core", version.ref = "jctools" }
jose4j = { module = "org.bitbucket.b_c:jose4j", version.ref = "jose4j" }
jsonSchemaInferrer = { module = "com.github.saasquatch:json-schema-inferrer", version.ref = "jsonSchemaInferrer" }
jsonSchemaValidator = { module = "com.networknt:json-schema-validator", version.ref = "jsonSchemaValidator" }
julToSlf4j = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" }
junit = { module = "junit:junit", version.ref = "junit" }
Expand Down
1 change: 0 additions & 1 deletion hivemq-edge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ repositories {
}
filter {
includeGroup("com.github.simon622.mqtt-sn")
includeGroup("com.github.saasquatch")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.hivemq.adapter.sdk.api.ProtocolAdapterCategory;
import com.hivemq.adapter.sdk.api.ProtocolAdapterInformation;
import com.hivemq.adapter.sdk.api.ProtocolAdapterTag;
import com.hivemq.adapter.sdk.api.config.ProtocolAdapterConfig;
import com.hivemq.adapter.sdk.api.config.ProtocolSpecificAdapterConfig;
import com.hivemq.adapter.sdk.api.tag.Tag;
import com.hivemq.edge.adapters.s7.config.S7AdapterConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class S7AdapterConfig implements ProtocolSpecificAdapterConfig {
public static final String PROPERTY_REMOTE_RACK = "remoteRack";
public static final String PROPERTY_REMOTE_SLOT = "remoteSlot";
public static final String PROPERTY_PDU_LENGTH = "pduLength";
public static final String PROPERTY_S_7_TO_MQTT_MAPPINGS = "s7ToMqttMappings";
public static final String PROPERTY_S_7_TO_MQTT = "s7ToMqtt";

public enum ControllerType {
S7_200,
Expand Down Expand Up @@ -89,7 +89,7 @@ public enum ControllerType {
description = "")
private final Integer pduLength;

@JsonProperty(value = PROPERTY_S_7_TO_MQTT_MAPPINGS, required = true)
@JsonProperty(value = PROPERTY_S_7_TO_MQTT, required = true)
@ModuleConfigField(title = "S7 To MQTT Config",
description = "The configuration for a data stream from S7 to MQTT",
required = true)
Expand All @@ -104,7 +104,7 @@ public S7AdapterConfig(
@JsonProperty(value = PROPERTY_REMOTE_RACK) final @Nullable Integer remoteRack,
@JsonProperty(value = PROPERTY_REMOTE_SLOT) final @Nullable Integer remoteSlot,
@JsonProperty(value = PROPERTY_PDU_LENGTH) final @Nullable Integer pduLength,
@JsonProperty(value = PROPERTY_S_7_TO_MQTT_MAPPINGS, required = true) final @NotNull S7ToMqttConfig s7ToMqttConfig) {
@JsonProperty(value = PROPERTY_S_7_TO_MQTT, required = true) final @NotNull S7ToMqttConfig s7ToMqttConfig) {
this.host = host;
this.controllerType = controllerType;
this.port = port;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
package com.hivemq.edge.adapters.s7.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hivemq.adapter.sdk.api.config.MqttUserProperty;
import com.hivemq.adapter.sdk.api.factories.ProtocolAdapterFactoryInput;
import com.hivemq.adapter.sdk.api.tag.Tag;
import com.hivemq.configuration.entity.HiveMQConfigEntity;
import com.hivemq.configuration.entity.adapter.ProtocolAdapterEntity;
import com.hivemq.configuration.reader.ConfigFileReaderWriter;
import com.hivemq.configuration.reader.ConfigurationFile;
import com.hivemq.edge.adapters.s7.S7ProtocolAdapterFactory;
import com.hivemq.protocols.AdapterConfigAndTags;
import com.hivemq.protocols.ProtocolAdapterConfig;
import com.hivemq.protocols.ProtocolAdapterConfigConverter;
import com.hivemq.protocols.ProtocolAdapterFactoryManager;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.hivemq.adapter.sdk.api.config.MessageHandlingOptions.MQTTMessagePerSubscription;
import static com.hivemq.adapter.sdk.api.config.MessageHandlingOptions.MQTTMessagePerTag;
import static com.hivemq.edge.adapters.s7.S7ProtocolAdapterInformation.PROTOCOL_ID;
import static com.hivemq.protocols.ProtocolAdapterUtils.createProtocolAdapterMapper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
Expand All @@ -34,51 +34,21 @@ class S7AdapterConfigTest {
@Test
public void convertConfigObject_fullConfig_valid() throws Exception {
final URL resource = getClass().getResource("/s7-adapter-full-config.xml");
final File path = Path.of(resource.toURI()).toFile();

final HiveMQConfigEntity configEntity = loadConfig(path);
final ProtocolAdapterEntity adapter = configEntity.getProtocolAdapterConfig().get(0);

final ProtocolAdapterFactoryInput mockInput = mock(ProtocolAdapterFactoryInput.class);
when(mockInput.isWritingEnabled()).thenReturn(false);
final S7ProtocolAdapterFactory s7ProtocolAdapterFactory = new S7ProtocolAdapterFactory(mockInput);

final AdapterConfigAndTags adapterConfigAndTags =
AdapterConfigAndTags.fromAdapterConfigMap((Map<String, Object>) adapters.get(PROTOCOL_ID),
false,
mapper,
s7ProtocolAdapterFactory);
final ProtocolAdapterConfig protocolAdapterConfig = getProtocolAdapterConfig(resource);

final S7AdapterConfig config = (S7AdapterConfig) adapterConfigAndTags.getAdapterConfig();
final S7AdapterConfig config = (S7AdapterConfig) protocolAdapterConfig.getAdapterConfig();
assertThat(protocolAdapterConfig.missingTags())
.isEmpty();

assertThat(config.getId()).isEqualTo("my-s7-protocol-adapter");
assertThat(config.getPort()).isEqualTo(1234);
assertThat(config.getHost()).isEqualTo("my.s7-server.com");
assertThat(config.getControllerType()).isEqualTo(S7AdapterConfig.ControllerType.S7_400);
assertThat(config.getPollingIntervalMillis()).isEqualTo(10);
assertThat(config.getMaxPollingErrorsBeforeRemoval()).isEqualTo(9);
assertThat(config.getPublishChangedDataOnly()).isFalse();
assertThat(config.getS7ToMqttMappings()).satisfiesExactly(mapping -> {
assertThat(mapping.getMqttTopic()).isEqualTo("my/topic");
assertThat(mapping.getMqttQos()).isEqualTo(1);
assertThat(mapping.getMessageHandlingOptions()).isEqualTo(MQTTMessagePerSubscription);
assertThat(mapping.getIncludeTimestamp()).isTrue();
assertThat(mapping.getIncludeTagNames()).isTrue();
assertThat(mapping.getTagName()).isEqualTo("tag-name");

}, mapping -> {
assertThat(mapping.getMqttTopic()).isEqualTo("my/topic/2");
assertThat(mapping.getMqttQos()).isEqualTo(1);
assertThat(mapping.getMessageHandlingOptions()).isEqualTo(MQTTMessagePerSubscription);
assertThat(mapping.getIncludeTimestamp()).isTrue();
assertThat(mapping.getIncludeTagNames()).isTrue();
assertThat(mapping.getTagName()).isEqualTo("tag-name");
});
assertThat(config.getS7ToMqttConfig().getPollingIntervalMillis()).isEqualTo(10);
assertThat(config.getS7ToMqttConfig().getMaxPollingErrorsBeforeRemoval()).isEqualTo(9);
assertThat(config.getS7ToMqttConfig().getPublishChangedDataOnly()).isFalse();


assertThat(adapterConfigAndTags.missingTags()).isEmpty();

assertThat(adapterConfigAndTags.getTags())
assertThat(protocolAdapterConfig.getTags())
.allSatisfy(t -> {
assertThat(t)
.isInstanceOf(S7Tag.class)
Expand All @@ -90,44 +60,21 @@ public void convertConfigObject_fullConfig_valid() throws Exception {
@Test
public void convertConfigObject_defaults_valid() throws Exception {
final URL resource = getClass().getResource("/s7-adapter-minimal-config.xml");
final File path = Path.of(resource.toURI()).toFile();

final HiveMQConfigEntity configEntity = loadConfig(path);
final Map<String, Object> adapters = configEntity.getProtocolAdapterConfig();

final ProtocolAdapterFactoryInput mockInput = mock(ProtocolAdapterFactoryInput.class);
when(mockInput.isWritingEnabled()).thenReturn(false);
final S7ProtocolAdapterFactory s7ProtocolAdapterFactory = new S7ProtocolAdapterFactory(mockInput);

final AdapterConfigAndTags adapterConfigAndTags =
AdapterConfigAndTags.fromAdapterConfigMap((Map<String, Object>) adapters.get(PROTOCOL_ID),
false,
mapper,
s7ProtocolAdapterFactory);
final ProtocolAdapterConfig protocolAdapterConfig = getProtocolAdapterConfig(resource);

final S7AdapterConfig config = (S7AdapterConfig) adapterConfigAndTags.getAdapterConfig();
final S7AdapterConfig config = (S7AdapterConfig) protocolAdapterConfig.getAdapterConfig();
assertThat(protocolAdapterConfig.missingTags())
.isEmpty();

assertThat(config).isNotNull();
assertThat(config.getId()).isEqualTo("my-s7-protocol-adapter");
assertThat(config.getPort()).isEqualTo(1234);
assertThat(config.getHost()).isEqualTo("my.s7-server.com");
assertThat(config.getControllerType()).isEqualTo(S7AdapterConfig.ControllerType.S7_400);
assertThat(config.getPollingIntervalMillis()).isEqualTo(1000);
assertThat(config.getMaxPollingErrorsBeforeRemoval()).isEqualTo(10);
assertThat(config.getPublishChangedDataOnly()).isTrue();
assertThat(config.getS7ToMqttMappings()).satisfiesExactly(mapping -> {
assertThat(mapping.getMqttTopic()).isEqualTo("my/topic");
assertThat(mapping.getMqttQos()).isEqualTo(0);
assertThat(mapping.getMessageHandlingOptions()).isEqualTo(MQTTMessagePerTag);
assertThat(mapping.getIncludeTimestamp()).isTrue();
assertThat(mapping.getIncludeTagNames()).isFalse();
assertThat(mapping.getTagName()).isEqualTo("tag-name");
});

assertThat(config.getS7ToMqttConfig().getPollingIntervalMillis()).isEqualTo(1000);
assertThat(config.getS7ToMqttConfig().getMaxPollingErrorsBeforeRemoval()).isEqualTo(10);
assertThat(config.getS7ToMqttConfig().getPublishChangedDataOnly()).isTrue();

assertThat(adapterConfigAndTags.missingTags()).isEmpty();

assertThat(adapterConfigAndTags.getTags())
assertThat(protocolAdapterConfig.getTags())
.allSatisfy(t -> {
assertThat(t)
.isInstanceOf(S7Tag.class)
Expand All @@ -138,26 +85,21 @@ public void convertConfigObject_defaults_valid() throws Exception {

@Test
public void unconvertConfigObject_full_valid() {
final S7ToMqttConfig pollingContext = new S7ToMqttConfig("my/destination",
final S7ToMqttConfig pollingContext = new S7ToMqttConfig(
3000,
1,
MQTTMessagePerSubscription,
false,
true,
"tag-name",
List.of(new MqttUserProperty("my-name", "my-value"))
false
);

final S7AdapterConfig s7AdapterConfig = new S7AdapterConfig("my-s7-adapter",
final S7AdapterConfig s7AdapterConfig = new S7AdapterConfig(
"my-s7-adapter",
14,
"my.host.com",
S7AdapterConfig.ControllerType.S7_1500,
1,
2,
3,
4,
5,
false,
List.of(pollingContext));
pollingContext);

final ProtocolAdapterFactoryInput mockInput = mock(ProtocolAdapterFactoryInput.class);
when(mockInput.isWritingEnabled()).thenReturn(false);
Expand Down Expand Up @@ -191,6 +133,29 @@ public void unconvertConfigObject_full_valid() {
});
}

private @NotNull ProtocolAdapterConfig getProtocolAdapterConfig(final @NotNull URL resource) throws
URISyntaxException {
final File path = Path.of(resource.toURI()).toFile();

final HiveMQConfigEntity configEntity = loadConfig(path);
final ProtocolAdapterEntity adapterEntity = configEntity.getProtocolAdapterConfig().get(0);

final ProtocolAdapterConfigConverter converter = createConverter();

return converter.fromEntity(adapterEntity);
}

private @NotNull ProtocolAdapterConfigConverter createConverter() {
final ProtocolAdapterFactoryInput mockInput = mock(ProtocolAdapterFactoryInput.class);
when(mockInput.isWritingEnabled()).thenReturn(true);

S7ProtocolAdapterFactory protocolAdapterFactory = new S7ProtocolAdapterFactory(mockInput);
ProtocolAdapterFactoryManager manager = mock(ProtocolAdapterFactoryManager.class);
when(manager.get("s7-new")).thenReturn(Optional.of(protocolAdapterFactory));
ProtocolAdapterConfigConverter converter = new ProtocolAdapterConfigConverter(manager, mapper);
return converter;
}

private @NotNull HiveMQConfigEntity loadConfig(final @NotNull File configFile) {
final ConfigFileReaderWriter readerWriter = new ConfigFileReaderWriter(new ConfigurationFile(configFile),
mock(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,23 @@
-->
<hivemq>
<protocol-adapters>
<s7-new>
<protocol-adapter>
<protocolId>s7-new</protocolId>
<adapterId>my-s7-protocol-adapter</adapterId>
<config>
<id>my-s7-protocol-adapter</id>
<host>my.s7-server.com</host>
<port>1234</port>
<controllerType>S7_400</controllerType>
<remoteRack>1</remoteRack>
<remoteSlot>3</remoteSlot>2>
<pollingIntervalMillis>10</pollingIntervalMillis>
<maxPollingErrorsBeforeRemoval>9</maxPollingErrorsBeforeRemoval>
<publishChangedDataOnly>false</publishChangedDataOnly>
<s7ToMqttMappings>
<s7ToMqttMapping>
<mqttTopic>my/topic</mqttTopic>
<mqttQos>1</mqttQos>
<controllerType>S7_400</controllerType>
<remoteRack>1</remoteRack>
<remoteSlot>3</remoteSlot>
<s7ToMqtt>
<pollingIntervalMillis>10</pollingIntervalMillis>
<maxPollingErrorsBeforeRemoval>9</maxPollingErrorsBeforeRemoval>
<publishChangedDataOnly>false</publishChangedDataOnly>
</s7ToMqtt>
</config>
<northboundMappings>
<northboundMapping>
<topic>my/topic</topic>
<maxQos>1</maxQos>
<includeTagNames>true</includeTagNames>
<includeTimestamp>true</includeTimestamp>
<messageHandlingOptions>MQTTMessagePerSubscription</messageHandlingOptions>
Expand All @@ -46,10 +48,10 @@
<value>value2</value>
</mqttUserProperty>
</mqttUserProperties>
</s7ToMqttMapping>
<s7ToMqttMapping>
<mqttTopic>my/topic/2</mqttTopic>
<mqttQos>1</mqttQos>
</northboundMapping>
<northboundMapping>
<topic>my/topic/2</topic>
<maxQos>1</maxQos>
<includeTagNames>true</includeTagNames>
<includeTimestamp>true</includeTimestamp>
<messageHandlingOptions>MQTTMessagePerSubscription</messageHandlingOptions>
Expand All @@ -64,19 +66,16 @@
<value>value2</value>
</mqttUserProperty>
</mqttUserProperties>
</s7ToMqttMapping>
</s7ToMqttMappings>
</config>
</northboundMapping>
</northboundMappings>
<tags>
<tag>
<name>tag-name</name>
<description>description</description>
<definition>
<address>%IB1</address>
<dataType>INT32</dataType>
</definition>
</tag>
<name>tag-name</name>
<description>description</description>
<definition>
<address>%IB1</address>
<dataType>INT32</dataType>
</definition>
</tags>
</s7-new>
</protocol-adapter>
</protocol-adapters>
</hivemq>
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
</s7ToMqttMapping>
</s7ToMqttMappings>
</config>
<northboundMappings>
<northboundMapping>
<topic>my/topic</topic>
<tagName>tag-name</tagName>
</northboundMapping>
</northboundMappings>
<tags>
<tag>
<name>tag-name</name>
Expand Down

0 comments on commit 14d9f2e

Please sign in to comment.