This is an automated email from the ASF dual-hosted git repository. hutcheb pushed a commit to branch feature/native_opua_client in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit d8e54a013a4959d4a4b9e60e8bc976bc925abd48 Author: hutcheb <[email protected]> AuthorDate: Sat Jan 23 07:06:37 2021 -0500 Cleaned up parameter parsing and key store generator. --- .../apache/plc4x/java/opcua/OpcuaPlcDriver.java | 36 ++++++++++++++++------ .../java/opcua/config/OpcuaConfiguration.java | 24 ++++++--------- plc4j/integrations/opcua-server/pom.xml | 5 +-- .../spi/connection/DefaultNettyPlcConnection.java | 14 --------- protocols/knxnetip/src/main/xslt/knx-types.xsl | 26 ++++------------ 5 files changed, 43 insertions(+), 62 deletions(-) diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java index 1a391f5..8ee6981 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java @@ -33,9 +33,9 @@ import org.apache.plc4x.java.spi.values.IEC61131ValueHandler; import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.spi.configuration.Configuration; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; -import org.apache.plc4x.java.spi.optimizer.SingleFieldOptimizer; import io.netty.buffer.ByteBuf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ServiceLoader; import java.util.regex.Matcher; @@ -45,14 +45,9 @@ import java.util.function.ToIntFunction; import static org.apache.plc4x.java.spi.configuration.ConfigurationFactory.configure; -/** - * Implementation of the OPC UA protocol, based on: - * - Eclipse Milo (https://github.com/eclipse/milo) - * - * Created by Matthias Milan Strljic on 10.05.2019 - */ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { + private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaPlcDriver.class); public static final Pattern OPCUA_URI_PARAM_PATTERN = Pattern.compile("(?<param>[(\\?|\\&)([^=]+)\\=([^&]+)]+)?"); //later used for regex filtering of the params @@ -65,7 +60,7 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { public static final Pattern URI_PATTERN = Pattern.compile("^(?<protocolCode>opcua)" + INET_ADDRESS_PATTERN + "(?<transportEndpoint>[\\w/=]*)[\\?]?" + - "(?<paramString>[\\&\\w=]+\\=[\\w&]+)*" + "(?<paramString>([^\\=]+\\=[^\\=&]+[&]?)*)" ); @@ -125,6 +120,10 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { return new IEC61131ValueHandler(); } + protected boolean awaitDisconnectComplete() { + return true; + } + @Override protected ProtocolStackConfigurer<OpcuaAPU> getStackConfigurer() { return SingleProtocolStackConfigurer.builder(OpcuaAPU.class, OpcuaAPUIO.class) @@ -190,6 +189,7 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { configure(configuration, transport); // Create an instance of the communication channel which the driver should use. + System.out.println(transportHost + ":" + transportPort); ChannelFactory channelFactory = transport.createChannelFactory(transportHost + ":" + transportPort); if(channelFactory == null) { throw new PlcConnectionException("Unable to get channel factory from url " + transportHost + ":" + transportPort); @@ -205,6 +205,23 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { awaitSetupComplete = Boolean.parseBoolean(System.getProperty(PROPERTY_PLC4X_FORCE_AWAIT_SETUP_COMPLETE)); } + // Make the "await disconnect complete" overridable via system property. + boolean awaitDisconnectComplete = awaitDisconnectComplete(); + if(System.getProperty(PROPERTY_PLC4X_FORCE_AWAIT_DISCONNECT_COMPLETE) != null) { + awaitDisconnectComplete = Boolean.parseBoolean(System.getProperty(PROPERTY_PLC4X_FORCE_AWAIT_DISCONNECT_COMPLETE)); + } + + if (!(configuration.getSecurityPolicy().equals("None"))) { + try { + LOGGER.info(configuration.getKeyStoreFile()); + LOGGER.info(configuration.getCertDirectory()); + LOGGER.info(configuration.getKeyStorePassword()); + configuration.openKeyStore(); + } catch (Exception e) { + throw new PlcConnectionException("Unable to open keystore, please confirm you have the correct permissions"); + } + } + return new DefaultNettyPlcConnection( canRead(), canWrite(), canSubscribe(), getFieldHandler(), @@ -212,6 +229,7 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> { configuration, channelFactory, awaitSetupComplete, + awaitDisconnectComplete, getStackConfigurer(), getOptimizer()); } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java index c9ff79f..0b6b86d 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java @@ -29,6 +29,7 @@ import org.apache.plc4x.java.spi.configuration.annotations.defaults.BooleanDefau import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue; import org.apache.plc4x.java.spi.configuration.annotations.defaults.StringDefaultValue; import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +45,11 @@ import java.security.cert.X509Certificate; public class OpcuaConfiguration implements Configuration, TcpTransportConfiguration { + static { + // Required for SecurityPolicy.Aes256_Sha256_RsaPss + Security.addProvider(new BouncyCastleProvider()); + } + private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaConfiguration.class); private String code; @@ -52,18 +58,6 @@ public class OpcuaConfiguration implements Configuration, TcpTransportConfigurat private String endpoint; private String params; - public OpcuaConfiguration() { - if (!(securityPolicy == "None")) { - try { - if (!(keyStoreFile == null) & !(certDirectory == null) & !(keyStorePassword == null)) { - openKeyStore(); - } - } catch (Exception e) { - LOGGER.info("Unable to open keystore, please confirm you have the correct permissions"); - } - } - } - @ConfigurationParameter("discovery") @BooleanDefaultValue(true) private boolean discovery; @@ -133,8 +127,8 @@ public class OpcuaConfiguration implements Configuration, TcpTransportConfigurat this.password = password; } - public void setCertFile(String certFile) { - this.certDirectory = certFile; + public void setCertDirectory(String certDirectory) { + this.certDirectory = certDirectory; } public void setSecurityPolicy(String securityPolicy) { @@ -181,7 +175,7 @@ public class OpcuaConfiguration implements Configuration, TcpTransportConfigurat this.endpoint = endpoint; } - private void openKeyStore() throws KeyStoreException, PlcConnectionException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException { + public void openKeyStore() throws KeyStoreException, PlcConnectionException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException { File securityTempDir = new File(certDirectory, "security"); if (!securityTempDir.exists() && !securityTempDir.mkdirs()) { throw new PlcConnectionException("Unable to create directory please confirm folder permissions on " + certDirectory); diff --git a/plc4j/integrations/opcua-server/pom.xml b/plc4j/integrations/opcua-server/pom.xml index 21fcc24..aa3b66a 100644 --- a/plc4j/integrations/opcua-server/pom.xml +++ b/plc4j/integrations/opcua-server/pom.xml @@ -203,10 +203,7 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </dependency> -<<<<<<< HEAD - -======= <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> @@ -216,7 +213,7 @@ <groupId>io.vavr</groupId> <artifactId>vavr</artifactId> </dependency> ->>>>>>> develop + <dependency> <groupId>org.apache.commons</groupId> diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java index 2343d11..177ef71 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java @@ -50,11 +50,7 @@ public class DefaultNettyPlcConnection extends AbstractPlcConnection implements protected final boolean awaitSessionSetupComplete; protected final boolean awaitSessionDisconnectComplete; protected final ProtocolStackConfigurer stackConfigurer; -<<<<<<< HEAD - private final CompletableFuture<Void> sessionDisconnectCompleteFuture = new CompletableFuture<>(); -======= protected final CompletableFuture<Void> sessionDisconnectCompleteFuture = new CompletableFuture<>(); ->>>>>>> develop protected Channel channel; protected boolean connected; @@ -122,15 +118,6 @@ public class DefaultNettyPlcConnection extends AbstractPlcConnection implements */ @Override public void close() throws PlcConnectionException { -<<<<<<< HEAD - // TODO call protocols close method - - channel.pipeline().fireUserEventTriggered(new DisconnectEvent()); - try { - sessionDisconnectCompleteFuture.get(10000L, TimeUnit.MILLISECONDS); - } catch (Exception e) { - //Do Nothing -======= logger.debug("Closing connection to PLC, await for disconnect = {}", awaitSessionDisconnectComplete); @@ -141,7 +128,6 @@ public class DefaultNettyPlcConnection extends AbstractPlcConnection implements } } catch (Exception e) { logger.error("Timeout while trying to close connection"); ->>>>>>> develop } channel.pipeline().fireUserEventTriggered(new CloseConnectionEvent()); diff --git a/protocols/knxnetip/src/main/xslt/knx-types.xsl b/protocols/knxnetip/src/main/xslt/knx-types.xsl index 6590625..4e3a6de 100644 --- a/protocols/knxnetip/src/main/xslt/knx-types.xsl +++ b/protocols/knxnetip/src/main/xslt/knx-types.xsl @@ -47,45 +47,35 @@ // specific language governing permissions and limitations // under the License. // -[enum uint 16 'KnxDatapointType' [uint 16 'number', uint 8 'sizeInBits', string 'name'] +[enum uint 16 'KnxDatapointType' [uint 16 'number', uint 8 'sizeInBits', string '-1' 'name'] ['0' DPT_UNKNOWN ['0', '0', '"Unknown Datapoint Type"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:DatapointTypes/knx:DatapointType"/> ] -[enum uint 32 'KnxDatapointSubtype' [uint 16 'number', KnxDatapointType 'datapointType', string 'name'] +[enum uint 32 'KnxDatapointSubtype' [uint 16 'number', KnxDatapointType 'datapointType', string '-1' 'name'] ['0' DPST_UNKNOWN ['0', 'KnxDatapointType.DPT_UNKNOWN', '"Unknown Datapoint Subtype"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:DatapointTypes/knx:DatapointType/knx:DatapointSubtypes/knx:DatapointSubtype"/> ] -[enum uint 16 'KnxInterfaceObjectType' [string 'code', string 'name'] +[enum uint 16 'KnxInterfaceObjectType' [string '-1' 'code', string '-1' 'name'] ['0' OT_UNKNOWN ['U', '"Unknown Interface Object Type"']] ['1' OT_GENERAL ['G', '"General Interface Object Type"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:InterfaceObjectTypes/knx:InterfaceObjectType"/> ] -<<<<<<< HEAD -[enum uint 8 'KnxObjectType' [string '-1' 'text']<xsl:apply-templates select="knx:KNX/knx:MasterData/knx:InterfaceObjectTypes/knx:InterfaceObjectType"/> -] - -[enum uint 8 'KnxObjectProperties' [string '-1' 'name', string '-1' 'dataTypeId', string '-1' 'text']<xsl:apply-templates select="knx:KNX/knx:MasterData/knx:InterfaceObjectProperties/knx:InterfaceObjectProperty"/> -] - -[enum uint 16 'KnxManufacturers' [string '-1' 'text']<xsl:apply-templates select="knx:KNX/knx:MasterData/knx:Manufacturers/knx:Manufacturer"/> -======= -[enum uint 32 'KnxInterfaceObjectProperty' [uint 8 'propertyId', KnxInterfaceObjectType 'objectType', KnxPropertyDataType 'propertyDataType', string 'name'] +[enum uint 32 'KnxInterfaceObjectProperty' [uint 8 'propertyId', KnxInterfaceObjectType 'objectType', KnxPropertyDataType 'propertyDataType', string '-1' 'name'] ['0' PID_UNKNOWN ['0', 'KnxInterfaceObjectType.OT_UNKNOWN', 'KnxPropertyDataType.PDT_UNKNOWN', '"Unknown Interface Object Property"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:InterfaceObjectProperties/knx:InterfaceObjectProperty"/> ] -[enum uint 8 'KnxPropertyDataType' [uint 8 'number', uint 8 'sizeInBytes', string 'name'] +[enum uint 8 'KnxPropertyDataType' [uint 8 'number', uint 8 'sizeInBytes', string '-1' 'name'] ['0' PDT_UNKNOWN ['0', '0', '"Unknown Property Data Type"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:PropertyDataTypes/knx:PropertyDataType"/> ] -[enum uint 16 'KnxManufacturer' [uint 16 'number', string 'name'] +[enum uint 16 'KnxManufacturer' [uint 16 'number', string '-1' 'name'] ['0' M_UNKNOWN ['0', '"Unknown Manufacturer"']] <xsl:apply-templates select="knx:KNX/knx:MasterData/knx:Manufacturers/knx:Manufacturer"/> ->>>>>>> develop ] </xsl:template> @@ -188,9 +178,6 @@ </xsl:choose> </xsl:template> -<<<<<<< HEAD -</xsl:stylesheet> -======= <xsl:template name="getIdFromText"> <xsl:param name="text"/> <xsl:variable name="cleanedText" select="fn:replace(fn:replace(fn:replace(fn:replace(fn:upper-case($text), '/', ''), '\(', ''), '\)', ''), '–', '_')"/> @@ -199,4 +186,3 @@ </xsl:template> </xsl:stylesheet> ->>>>>>> develop
