You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2021/01/31 11:20:15 UTC
[plc4x] 03/45: Re-Wrote OPC UA server -> Milo Interface
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/plc4c
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 3811a17a03e5850154abde9becdef3ff26f2fba5
Author: hutcheb <be...@gmail.com>
AuthorDate: Tue Jan 19 06:54:51 2021 -0500
Re-Wrote OPC UA server -> Milo Interface
Outstanding issue with PLC4X comms failure when adding tag that isn't valid.
---
plc4j/integrations/opcua-server/pom.xml | 5 -
.../apache/plc4x/java/opcuaserver/OPCUAServer.java | 165 ++++++++++-----------
.../opcuaserver/backend/Plc4xCommunication.java | 63 ++------
.../java/opcuaserver/backend/Plc4xNamespace.java | 104 ++++---------
.../opcuaserver/configuration/Configuration.java | 7 -
.../plc4x/java/opcuaserver/OpcuaPlcDriverTest.java | 75 ++++------
.../opcua-server/src/test/resources/config.yml | 1 -
7 files changed, 148 insertions(+), 272 deletions(-)
diff --git a/plc4j/integrations/opcua-server/pom.xml b/plc4j/integrations/opcua-server/pom.xml
index ede65e2..3313a16 100644
--- a/plc4j/integrations/opcua-server/pom.xml
+++ b/plc4j/integrations/opcua-server/pom.xml
@@ -51,11 +51,6 @@
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>${guava.version}</version>
- </dependency>
<dependency>
<groupId>org.eclipse.milo</groupId>
diff --git a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/OPCUAServer.java b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/OPCUAServer.java
index 2aa6bca..1c6ddcb 100644
--- a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/OPCUAServer.java
+++ b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/OPCUAServer.java
@@ -21,11 +21,10 @@ package org.apache.plc4x.java.opcuaserver;
import java.io.File;
import java.io.FileInputStream;
+import java.net.InetAddress;
import java.security.*;
import java.security.cert.X509Certificate;
-import java.util.ArrayList;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -46,7 +45,6 @@ import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig;
import org.eclipse.milo.opcua.sdk.server.identity.CompositeValidator;
import org.eclipse.milo.opcua.sdk.server.identity.UsernameIdentityValidator;
import org.eclipse.milo.opcua.sdk.server.identity.X509IdentityValidator;
-import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;
import org.eclipse.milo.opcua.stack.core.StatusCodes;
import org.eclipse.milo.opcua.stack.core.UaRuntimeException;
import org.eclipse.milo.opcua.stack.core.security.DefaultCertificateManager;
@@ -58,15 +56,11 @@ import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode;
import org.eclipse.milo.opcua.stack.core.types.structured.BuildInfo;
import org.eclipse.milo.opcua.stack.core.util.CertificateUtil;
-import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
-import org.eclipse.milo.opcua.stack.core.util.SelfSignedHttpsCertificateBuilder;
import org.eclipse.milo.opcua.stack.server.EndpointConfiguration;
import org.eclipse.milo.opcua.stack.server.security.DefaultServerCertificateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static com.google.common.collect.Lists.newArrayList;
-import org.apache.commons.lang3.RandomStringUtils;
import static org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS;
import static org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME;
import static org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_X509;
@@ -205,10 +199,9 @@ public class OPCUAServer {
}
public static void main(String[] args) throws Exception {
- OPCUAServer server = new OPCUAServer(args);
- server.startup().get();
- final CompletableFuture<Void> future = new CompletableFuture<>();
- Runtime.getRuntime().addShutdownHook(new Thread(() -> future.complete(null)));
+ OPCUAServer serverInit = new OPCUAServer(args);
+ serverInit.getServer().startup().get();
+ CompletableFuture<Void> future = new CompletableFuture<>();
future.get();
}
@@ -220,21 +213,18 @@ public class OPCUAServer {
readCommandLineArgs(args);
-
File securityTempDir = new File(config.getDir(), "security");
if (!securityTempDir.exists() && !securityTempDir.mkdirs()) {
logger.error("Unable to create directory please confirm folder permissions on " + securityTempDir.toString());
System.exit(1);
}
- logger.info("security dir: {}", securityTempDir.getAbsolutePath());
+ logger.info("Security Directory is: {}", securityTempDir.getAbsolutePath()); //
File pkiDir = FileSystems.getDefault().getPath(config.getDir()).resolve("pki").toFile();
DefaultTrustListManager trustListManager = new DefaultTrustListManager(pkiDir);
- logger.info("pki dir: {}", pkiDir.getAbsolutePath());
-
- DefaultServerCertificateValidator certificateValidator =
- new DefaultServerCertificateValidator(trustListManager);
+ logger.info("Certificate directory is: {}, Please move certificates from the reject dir to the trusted directory to allow encrypted access", pkiDir.getAbsolutePath());
+ DefaultServerCertificateValidator certificateValidator = new DefaultServerCertificateValidator(trustListManager);
UsernameIdentityValidator identityValidator = new UsernameIdentityValidator(
true,
@@ -251,7 +241,7 @@ public class OPCUAServer {
File serverKeyStore = securityTempDir.toPath().resolve(certificateFileName).toFile();
- X509IdentityValidator x509IdentityValidator = new X509IdentityValidator(c -> true); //Fix this
+ X509IdentityValidator x509IdentityValidator = new X509IdentityValidator(c -> true);
CertificateKeyPair certificate = null;
if (!serverKeyStore.exists()) {
@@ -262,7 +252,6 @@ public class OPCUAServer {
certificate = Encryption.generateCertificate();
} else {
logger.info("Loading KeyStore at {}", serverKeyStore);
-
keyStore.load(new FileInputStream(serverKeyStore), passwordConfig.getSecurityPassword().toCharArray());
String alias = keyStore.aliases().nextElement();
KeyPair kp = new KeyPair((PublicKey) keyStore.getCertificate(alias).getPublicKey(),
@@ -276,7 +265,75 @@ public class OPCUAServer {
StatusCodes.Bad_ConfigurationError,
"certificate is missing the application URI"));
- Set<EndpointConfiguration> endpointConfigurations = createEndpointConfigurations(certificate.getCertificate());
+ Set<EndpointConfiguration> endpointConfigurations = new LinkedHashSet<>();
+
+ String hostname = InetAddress.getLocalHost().getHostName();
+
+ EndpointConfiguration.Builder builder = EndpointConfiguration.newBuilder()
+ .setBindAddress("0.0.0.0")
+ .setHostname(hostname)
+ .setPath("/plc4x")
+ .setCertificate(certificate.getCertificate())
+ .setBindPort(config.getTcpPort())
+ .setSecurityMode(MessageSecurityMode.None)
+ .addTokenPolicies(
+ USER_TOKEN_POLICY_ANONYMOUS,
+ USER_TOKEN_POLICY_USERNAME,
+ USER_TOKEN_POLICY_X509);
+
+ endpointConfigurations.add(
+ builder.copy()
+ .setSecurityPolicy(SecurityPolicy.Basic256Sha256)
+ .setSecurityMode(MessageSecurityMode.SignAndEncrypt)
+ .build()
+ );
+
+ endpointConfigurations.add(
+ builder.copy()
+ .setHostname("127.0.0.1")
+ .setSecurityPolicy(SecurityPolicy.Basic256Sha256)
+ .setSecurityMode(MessageSecurityMode.SignAndEncrypt)
+ .build()
+ );
+
+ EndpointConfiguration.Builder discoveryBuilder = builder.copy()
+ .setPath("/discovery")
+ .setSecurityPolicy(SecurityPolicy.None)
+ .setSecurityMode(MessageSecurityMode.None);
+
+ endpointConfigurations.add(discoveryBuilder.build());
+
+ EndpointConfiguration.Builder discoveryLocalBuilder = builder.copy()
+ .setPath("/discovery")
+ .setHostname("127.0.0.1")
+ .setSecurityPolicy(SecurityPolicy.None)
+ .setSecurityMode(MessageSecurityMode.None);
+
+ endpointConfigurations.add(discoveryLocalBuilder.build());
+
+ EndpointConfiguration.Builder discoveryLocalPlc4xBuilder = builder.copy()
+ .setPath("/plc4x/discovery")
+ .setHostname("127.0.0.1")
+ .setSecurityPolicy(SecurityPolicy.None)
+ .setSecurityMode(MessageSecurityMode.None);
+
+ endpointConfigurations.add(discoveryLocalPlc4xBuilder.build());
+
+ if (!config.getDisableInsecureEndpoint()) {
+ EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
+ .setSecurityPolicy(SecurityPolicy.None)
+ .setTransportProfile(TransportProfile.TCP_UASC_UABINARY);
+ endpointConfigurations.add(noSecurityBuilder.build());
+ }
+
+ //Always add an unsecured endpoint to localhost, this is a work around for Milo throwing an exception if it isn't here.
+ EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
+ .setSecurityPolicy(SecurityPolicy.None)
+ .setHostname("127.0.0.1")
+ .setTransportProfile(TransportProfile.TCP_UASC_UABINARY)
+ .setSecurityMode(MessageSecurityMode.None);
+ endpointConfigurations.add(noSecurityBuilder.build());
+
DefaultCertificateManager certificateManager = new DefaultCertificateManager(
certificate.getKeyPair(),
@@ -307,73 +364,6 @@ public class OPCUAServer {
plc4xNamespace.startup();
}
- private Set<EndpointConfiguration> createEndpointConfigurations(X509Certificate certificate) {
- Set<EndpointConfiguration> endpointConfigurations = new LinkedHashSet<>();
-
- List<String> bindAddresses = newArrayList();
- bindAddresses.add("0.0.0.0");
-
- List<String> localAddresses = new ArrayList<>(bindAddresses);
-
- Set<String> hostnames = new LinkedHashSet<>();
- hostnames.add(HostnameUtil.getHostname());
- hostnames.addAll(HostnameUtil.getHostnames("0.0.0.0"));
-
- for (String bindAddress : bindAddresses) {
- for (String hostname : hostnames) {
- EndpointConfiguration.Builder builder = EndpointConfiguration.newBuilder()
- .setBindAddress(bindAddress)
- .setHostname(hostname)
- .setPath("/plc4x")
- .setCertificate(certificate)
- .addTokenPolicies(
- USER_TOKEN_POLICY_ANONYMOUS,
- USER_TOKEN_POLICY_USERNAME,
- USER_TOKEN_POLICY_X509);
-
-
- if (!config.getDisableInsecureEndpoint()) {
- EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
- .setSecurityPolicy(SecurityPolicy.None)
- .setSecurityMode(MessageSecurityMode.None);
- endpointConfigurations.add(buildTcpEndpoint(noSecurityBuilder));
- } else {
- //Always add an unsecured endpoint to localhost, this is a work around for Milo throwing an exception if it isn't here.
- if (hostname.equals("127.0.0.1")) {
- EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
- .setSecurityPolicy(SecurityPolicy.None)
- .setSecurityMode(MessageSecurityMode.None);
- endpointConfigurations.add(buildTcpEndpoint(noSecurityBuilder));
- }
- }
-
- // TCP Basic256Sha256 / SignAndEncrypt
- endpointConfigurations.add(buildTcpEndpoint(
- builder.copy()
- .setSecurityPolicy(SecurityPolicy.Basic256Sha256)
- .setSecurityMode(MessageSecurityMode.SignAndEncrypt))
- );
-
- EndpointConfiguration.Builder discoveryBuilder = builder.copy()
- .setPath("/discovery")
- .setSecurityPolicy(SecurityPolicy.None)
- .setSecurityMode(MessageSecurityMode.None);
-
-
- endpointConfigurations.add(buildTcpEndpoint(discoveryBuilder));
- }
- }
-
- return endpointConfigurations;
- }
-
- private EndpointConfiguration buildTcpEndpoint(EndpointConfiguration.Builder base) {
- return base.copy()
- .setTransportProfile(TransportProfile.TCP_UASC_UABINARY)
- .setBindPort(config.getTcpPort())
- .build();
- }
-
public OpcUaServer getServer() {
return server;
}
@@ -384,7 +374,6 @@ public class OPCUAServer {
public CompletableFuture<OpcUaServer> shutdown() {
plc4xNamespace.shutdown();
-
return server.shutdown();
}
diff --git a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xCommunication.java b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xCommunication.java
index 9e32867..1c717c8 100644
--- a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xCommunication.java
+++ b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xCommunication.java
@@ -19,59 +19,15 @@
package org.apache.plc4x.java.opcuaserver.backend;
-
import java.lang.reflect.Array;
-import java.util.List;
import java.util.Arrays;
-import java.util.Random;
-import java.util.UUID;
-
-import org.eclipse.milo.opcua.sdk.core.AccessLevel;
-import org.eclipse.milo.opcua.sdk.core.Reference;
-import org.eclipse.milo.opcua.sdk.core.ValueRank;
-import org.eclipse.milo.opcua.sdk.core.ValueRanks;
-import org.eclipse.milo.opcua.sdk.server.Lifecycle;
-import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
import org.eclipse.milo.opcua.sdk.server.api.DataItem;
-import org.eclipse.milo.opcua.sdk.server.api.DataTypeDictionaryManager;
-import org.eclipse.milo.opcua.sdk.server.api.ManagedNamespaceWithLifecycle;
-import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.objects.BaseEventTypeNode;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.objects.ServerTypeNode;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.variables.AnalogItemTypeNode;
import org.eclipse.milo.opcua.sdk.server.nodes.filters.AttributeFilterContext;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectTypeNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.factories.NodeFactory;
-import org.eclipse.milo.opcua.sdk.server.nodes.filters.AttributeFilters;
-import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel;
-import org.eclipse.milo.opcua.stack.core.AttributeId;
-import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
-import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
-import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
-import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
-import org.eclipse.milo.opcua.stack.core.types.builtin.XmlElement;
-import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumDefinition;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumDescription;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumField;
-import org.eclipse.milo.opcua.stack.core.types.structured.Range;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureDescription;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -81,15 +37,14 @@ import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
-import org.apache.plc4x.java.api.messages.PlcWriteResponse;
+
import org.apache.plc4x.java.api.types.PlcResponseCode;
-import org.apache.plc4x.java.api.value.PlcValue;
+
import org.apache.plc4x.java.utils.connectionpool.*;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+
import org.apache.plc4x.java.api.model.PlcField;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
@@ -98,10 +53,8 @@ import java.util.HashMap;
import java.math.BigInteger;
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ubyte;
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ulong;
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ushort;
+
public class Plc4xCommunication {
@@ -118,6 +71,14 @@ public class Plc4xCommunication {
driverManager = new PooledPlcDriverManager();
}
+ public PlcDriverManager getDriverManager() {
+ return driverManager;
+ }
+
+ public void setDriverManager(PlcDriverManager driverManager) {
+ this.driverManager = driverManager;
+ }
+
public PlcField getField(String tag, String connectionString) throws PlcConnectionException {
return driverManager.getDriver(connectionString).prepareField(tag);
}
diff --git a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xNamespace.java b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xNamespace.java
index 654ac4b..12e3313 100644
--- a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xNamespace.java
+++ b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xNamespace.java
@@ -19,141 +19,86 @@
package org.apache.plc4x.java.opcuaserver.backend;
-import org.apache.plc4x.java.opcuaserver.*;
-
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
-import java.util.Random;
-import java.util.UUID;
import org.apache.plc4x.java.opcuaserver.configuration.Configuration;
import org.apache.plc4x.java.opcuaserver.configuration.DeviceConfiguration;
import org.apache.plc4x.java.opcuaserver.configuration.Tag;
+import org.apache.plc4x.java.utils.connectionpool.PooledPlcDriverManager;
import org.eclipse.milo.opcua.sdk.core.AccessLevel;
import org.eclipse.milo.opcua.sdk.core.Reference;
import org.eclipse.milo.opcua.sdk.core.ValueRank;
-import org.eclipse.milo.opcua.sdk.core.ValueRanks;
-import org.eclipse.milo.opcua.sdk.server.Lifecycle;
import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
import org.eclipse.milo.opcua.sdk.server.api.DataItem;
import org.eclipse.milo.opcua.sdk.server.api.DataTypeDictionaryManager;
import org.eclipse.milo.opcua.sdk.server.api.ManagedNamespaceWithLifecycle;
import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.objects.BaseEventTypeNode;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.objects.ServerTypeNode;
-import org.eclipse.milo.opcua.sdk.server.model.nodes.variables.AnalogItemTypeNode;
import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectTypeNode;
import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.factories.NodeFactory;
import org.eclipse.milo.opcua.sdk.server.nodes.filters.AttributeFilters;
import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel;
-import org.eclipse.milo.opcua.stack.core.AttributeId;
-import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
-import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
-import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
-import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
-import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
-import org.eclipse.milo.opcua.stack.core.types.builtin.XmlElement;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumDefinition;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumDescription;
-import org.eclipse.milo.opcua.stack.core.types.structured.EnumField;
-import org.eclipse.milo.opcua.stack.core.types.structured.Range;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureDescription;
-import org.eclipse.milo.opcua.stack.core.types.structured.StructureField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import org.apache.plc4x.java.api.model.PlcField;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ubyte;
import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ulong;
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ushort;
+
public class Plc4xNamespace extends ManagedNamespaceWithLifecycle {
- public static final String NAMESPACE_URI = "urn:eclipse:milo:plc4x:server";
+ public static final String APPLICATIONID = "urn:eclipse:milo:plc4x:server";
private Configuration config;
-
private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private volatile Thread eventThread;
- private volatile boolean keepPostingEvents = true;
-
- private final Random random = new Random();
-
private final DataTypeDictionaryManager dictionaryManager;
-
private final SubscriptionModel subscriptionModel;
-
private Plc4xCommunication plc4xServer;
public Plc4xNamespace(OpcUaServer server, Configuration c) {
- super(server, NAMESPACE_URI);
+ super(server, APPLICATIONID);
this.config = c;
subscriptionModel = new SubscriptionModel(server, this);
- dictionaryManager = new DataTypeDictionaryManager(getNodeContext(), NAMESPACE_URI);
-
+ dictionaryManager = new DataTypeDictionaryManager(getNodeContext(), APPLICATIONID);
plc4xServer = new Plc4xCommunication();
-
getLifecycleManager().addLifecycle(dictionaryManager);
getLifecycleManager().addLifecycle(subscriptionModel);
-
getLifecycleManager().addStartupTask(this::addNodes);
}
private void addNodes() {
for (DeviceConfiguration c: config.getDevices()) {
- createAndAddNodes(c);
- }
- }
+ NodeId folderNodeId = newNodeId(c.getName());
- private void createAndAddNodes(DeviceConfiguration c) {
+ UaFolderNode folderNode = new UaFolderNode(
+ getNodeContext(),
+ folderNodeId,
+ newQualifiedName(c.getName()),
+ LocalizedText.english(c.getName())
+ );
- NodeId folderNodeId = newNodeId(c.getName());
+ getNodeManager().addNode(folderNode);
- UaFolderNode folderNode = new UaFolderNode(
- getNodeContext(),
- folderNodeId,
- newQualifiedName(c.getName()),
- LocalizedText.english(c.getName())
- );
+ folderNode.addReference(new Reference(
+ folderNode.getNodeId(),
+ Identifiers.Organizes,
+ Identifiers.ObjectsFolder.expanded(),
+ false
+ ));
- getNodeManager().addNode(folderNode);
-
- // Make sure our new folder shows up under the server's Objects folder.
- folderNode.addReference(new Reference(
- folderNode.getNodeId(),
- Identifiers.Organizes,
- Identifiers.ObjectsFolder.expanded(),
- false
- ));
-
- addDynamicNodes(folderNode, c);
+ addConfiguredNodes(folderNode, c);
+ }
}
- private void addDynamicNodes(UaFolderNode rootNode, DeviceConfiguration c) {
+ private void addConfiguredNodes(UaFolderNode rootNode, DeviceConfiguration c) {
final List<Tag> tags = c.getTags();
final String connectionString = c.getConnectionString();
for (int i = 0; i < tags.size(); i++) {
@@ -238,6 +183,11 @@ public class Plc4xNamespace extends ManagedNamespaceWithLifecycle {
public void onDataItemsCreated(List<DataItem> dataItems) {
for (DataItem item : dataItems) {
plc4xServer.addField(item);
+
+ if (plc4xServer.getDriverManager() == null) {
+ plc4xServer.removeField(item);
+ plc4xServer.setDriverManager(new PooledPlcDriverManager());
+ }
}
subscriptionModel.onDataItemsCreated(dataItems);
diff --git a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/configuration/Configuration.java b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/configuration/Configuration.java
index 854e8c0..88efb2d 100644
--- a/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/configuration/Configuration.java
+++ b/plc4j/integrations/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/configuration/Configuration.java
@@ -47,9 +47,6 @@ public class Configuration {
@JsonProperty
private Integer tcpPort = 12686;
- @JsonProperty
- private Integer httpPort = 8443;
-
public Configuration() {
}
@@ -73,10 +70,6 @@ public class Configuration {
return tcpPort;
}
- public Integer getHttpPort() {
- return httpPort;
- }
-
public List<DeviceConfiguration> getDevices() {
return devices;
}
diff --git a/plc4j/integrations/opcua-server/src/test/java/org/apache/plc4x/java/opcuaserver/OpcuaPlcDriverTest.java b/plc4j/integrations/opcua-server/src/test/java/org/apache/plc4x/java/opcuaserver/OpcuaPlcDriverTest.java
index 256f35f..71f0f05 100644
--- a/plc4j/integrations/opcua-server/src/test/java/org/apache/plc4x/java/opcuaserver/OpcuaPlcDriverTest.java
+++ b/plc4j/integrations/opcua-server/src/test/java/org/apache/plc4x/java/opcuaserver/OpcuaPlcDriverTest.java
@@ -27,51 +27,46 @@ import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;
-import org.apache.plc4x.java.opcua.connection.OpcuaTcpPlcConnection;
import org.junit.jupiter.api.*;
import java.math.BigInteger;
-import java.util.HashSet;
-import java.util.Set;
+
import org.apache.commons.io.FileUtils;
import java.io.File;
-import static org.apache.plc4x.java.opcua.OpcuaPlcDriver.INET_ADDRESS_PATTERN;
-import static org.apache.plc4x.java.opcua.OpcuaPlcDriver.OPCUA_URI_PATTERN;
-import static org.apache.plc4x.java.opcuaserver.UtilsTest.assertMatching;
import static org.assertj.core.api.Assertions.fail;
/**
*/
public class OpcuaPlcDriverTest {
// Read only variables of milo example server of version 3.6
- private static final String BOOL_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_BOOL";
- private static final String BYTE_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_BYTE";
- private static final String DOUBLE_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_LREAL";
- private static final String FLOAT_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_REAL";
- private static final String INT16_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_INT";
- private static final String INT32_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_DINT";
- private static final String INT64_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_LINT";
- private static final String INTEGER_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_DINT";
- private static final String SBYTE_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_USINT";
- private static final String STRING_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_STRING";
- private static final String UINT16_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_UINT";
- private static final String UINT32_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_UDINT";
- private static final String UINT64_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_ULINT";
- private static final String UINTEGER_IDENTIFIER_READ_WRITE = "ns=2;s=Simulated_OPC_UDINT";
- private static final String DOES_NOT_EXIST_IDENTIFIER_READ_WRITE = "ns=2;i=12512623";
+ private static final String BOOL_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_BOOL";
+ private static final String BYTE_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_BYTE";
+ private static final String DOUBLE_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_LREAL";
+ private static final String FLOAT_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_REAL";
+ private static final String INT16_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_INT";
+ private static final String INT32_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_DINT";
+ private static final String INT64_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_LINT";
+ private static final String INTEGER_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_DINT";
+ private static final String SBYTE_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_USINT";
+ private static final String STRING_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_STRING";
+ private static final String UINT16_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_UINT";
+ private static final String UINT32_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_UDINT";
+ private static final String UINT64_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_ULINT";
+ private static final String UINTEGER_IDENTIFIER_READ_WRITE = "ns=1;s=Simulated_UDINT";
+ private static final String DOES_NOT_EXIST_IDENTIFIER_READ_WRITE = "ns=1;i=12512623";
// At the moment not used in PLC4X or in the OPC UA driver
- private static final String BYTE_STRING_IDENTIFIER_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/ByteString";
- private static final String DATE_TIME_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/DateTime";
- private static final String DURATION_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/Duration";
- private static final String GUID_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/Guid";
- private static final String LOCALISED_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/LocalizedText";
- private static final String NODE_ID_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/NodeId";
- private static final String QUALIFIED_NAM_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/QualifiedName";
- private static final String UTC_TIME_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/UtcTime";
- private static final String VARIANT_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/Variant";
- private static final String XML_ELEMENT_READ_WRITE = "ns=2;s=HelloWorld/ScalarTypes/XmlElement";
+ private static final String BYTE_STRING_IDENTIFIER_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/ByteString";
+ private static final String DATE_TIME_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/DateTime";
+ private static final String DURATION_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/Duration";
+ private static final String GUID_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/Guid";
+ private static final String LOCALISED_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/LocalizedText";
+ private static final String NODE_ID_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/NodeId";
+ private static final String QUALIFIED_NAM_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/QualifiedName";
+ private static final String UTC_TIME_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/UtcTime";
+ private static final String VARIANT_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/Variant";
+ private static final String XML_ELEMENT_READ_WRITE = "ns=1;s=HelloWorld/ScalarTypes/XmlElement";
// Address of local milo server
private String miloLocalAddress = "127.0.0.1:12673/plc4x";
//Tcp pattern of OPC UA
@@ -113,7 +108,6 @@ public class OpcuaPlcDriverTest {
@Test
public void connectionNoParams(){
-
connectionStringValidSet.forEach(connectionAddress -> {
String connectionString = connectionAddress;
try {
@@ -153,8 +147,8 @@ public class OpcuaPlcDriverTest {
}
@Test
- public void readVariables() {
- try {
+ public void readVariables() throws Exception{
+
PlcConnection opcuaConnection = new PlcDriverManager().getConnection(tcpConnectionAddress);
assert opcuaConnection.isConnected();
@@ -198,14 +192,12 @@ public class OpcuaPlcDriverTest {
opcuaConnection.close();
assert !opcuaConnection.isConnected();
- } catch (Exception e) {
- fail("Exception during readVariables Test EXCEPTION: " + e.getMessage());
- }
+
}
@Test
- public void writeVariables() {
- try {
+ public void writeVariables() throws Exception {
+
PlcConnection opcuaConnection = new PlcDriverManager().getConnection(tcpConnectionAddress);
assert opcuaConnection.isConnected();
@@ -218,7 +210,7 @@ public class OpcuaPlcDriverTest {
builder.addItem("Int32", INT32_IDENTIFIER_READ_WRITE, 42);
builder.addItem("Int64", INT64_IDENTIFIER_READ_WRITE, 42L);
builder.addItem("Integer", INTEGER_IDENTIFIER_READ_WRITE, 42);
- builder.addItem("SByte", SBYTE_IDENTIFIER_READ_WRITE + ":SINT", -100);
+ builder.addItem("SByte", SBYTE_IDENTIFIER_READ_WRITE + ":USINT", 100);
builder.addItem("String", STRING_IDENTIFIER_READ_WRITE, "Helllo Toddy!");
builder.addItem("UInt16", UINT16_IDENTIFIER_READ_WRITE + ":UINT", 65535);
builder.addItem("UInt32", UINT32_IDENTIFIER_READ_WRITE + ":UDINT", 100);
@@ -248,9 +240,6 @@ public class OpcuaPlcDriverTest {
opcuaConnection.close();
assert !opcuaConnection.isConnected();
- } catch (Exception e) {
- fail("Exception during writeVariables Test EXCEPTION: " + e.getMessage());
- }
}
}
diff --git a/plc4j/integrations/opcua-server/src/test/resources/config.yml b/plc4j/integrations/opcua-server/src/test/resources/config.yml
index d0b0cd9..c60002e 100644
--- a/plc4j/integrations/opcua-server/src/test/resources/config.yml
+++ b/plc4j/integrations/opcua-server/src/test/resources/config.yml
@@ -21,7 +21,6 @@ dir: "target/test-tmp/"
name: Plc4x.OPC.UA.Server
disableInsecureEndpoint: true
tcpPort: 12673
-httpPort: 8445
devices:
- name: "Simulated Device"
connectionString: "simulated://127.0.0.1"