From 80add3d5bc5c2c5127863039ebf60134ad13911b Mon Sep 17 00:00:00 2001 From: Matthias Milan Strljic Date: Mon, 13 May 2019 19:17:11 +0200 Subject: [PATCH 1/8] Add initial OPC UA project. This is a raw version of the project without any tests or refactoring in a first fully functional state. --- plc4j/drivers/opcua/pom.xml | 83 +++ .../plc4x/java/opcua/OPCUAPlcDriver.java | 99 ++++ .../connection/BaseOPCUAPlcConnection.java | 89 ++++ .../connection/OPCUAConnectionFactory.java | 36 ++ .../connection/OPCUATcpPlcConnection.java | 474 ++++++++++++++++++ .../plc4x/java/opcua/protocol/OpcuaField.java | 115 +++++ .../opcua/protocol/model/OpcuaDataTypes.java | 43 ++ .../protocol/model/OpcuaIdentifierType.java | 26 + .../protocol/model/OpcuaPlcFieldHandler.java | 146 ++++++ .../model/OpcuaSubsriptionHandle.java | 76 +++ .../org.apache.plc4x.java.spi.PlcDriver | 19 + .../opcua/connection/ManualPLC4XOPCUA.java | 125 +++++ plc4j/drivers/pom.xml | 1 + 13 files changed, 1332 insertions(+) create mode 100644 plc4j/drivers/opcua/pom.xml create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OPCUAPlcDriver.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java create mode 100644 plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java create mode 100644 plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml new file mode 100644 index 00000000000..69a36cd4e88 --- /dev/null +++ b/plc4j/drivers/opcua/pom.xml @@ -0,0 +1,83 @@ + + + + + 4.0.0 + + + org.apache.plc4x + plc4j-drivers + 0.4.0-SNAPSHOT + + + plc4j-driver-opcua + PLC4J: Driver: OPC UA + Implementation of a PLC4X driver able to speak with devices using the OPC UA protocol. + + + + org.apache.plc4x + plc4j-api + 0.4.0-SNAPSHOT + + + + org.apache.plc4x + plc4j-protocol-driver-base + 0.4.0-SNAPSHOT + + + + org.eclipse.milo + sdk-client + 0.3.0-M1 + + + org.eclipse.milo + stack-core + 0.3.0-M1 + + + org.eclipse.milo + stack-client + 0.3.0-M1 + + + + org.apache.commons + commons-lang3 + + + + \ No newline at end of file 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 new file mode 100644 index 00000000000..68f3886f5ef --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OPCUAPlcDriver.java @@ -0,0 +1,99 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua; + +import org.apache.commons.lang3.StringUtils; +import org.apache.plc4x.java.PlcDriverManager; +import org.apache.plc4x.java.api.PlcConnection; +import org.apache.plc4x.java.api.authentication.PlcAuthentication; +import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +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.model.PlcField; +import org.apache.plc4x.java.opcua.connection.OPCUAConnectionFactory; +import org.apache.plc4x.java.opcua.connection.OPCUATcpPlcConnection; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; +import org.apache.plc4x.java.spi.PlcDriver; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Implementation of the OPC UA protocol, based on: + * - Eclipse Milo (https://github.com/eclipse/milo) + */ +public class OPCUAPlcDriver implements PlcDriver { + + + + public static final Pattern INET_ADDRESS_PATTERN = Pattern.compile("tcp://(?[\\w.-]+)(:(?\\d*))?"); + public static final Pattern OPCUA_URI_PATTERN = Pattern.compile("^opcua:(" + INET_ADDRESS_PATTERN + ")?" + "(?/[\\w/]+)?"); + + private OPCUAConnectionFactory opcuaConnectionFactory; + + public OPCUAPlcDriver() { + this.opcuaConnectionFactory = new OPCUAConnectionFactory(); + } + + public OPCUAPlcDriver(OPCUAConnectionFactory opcuaConnectionFactory) { + this.opcuaConnectionFactory = opcuaConnectionFactory; + } + + @Override + public String getProtocolCode() { + return "opcua"; + } + + @Override + public String getProtocolName() { + return "OPC UA (TCP)"; + } + + @Override + public PlcConnection connect(String url) throws PlcConnectionException { + Matcher matcher = OPCUA_URI_PATTERN.matcher(url); + + if (!matcher.matches()) { + throw new PlcConnectionException( + "Connection url doesn't match the format 'opcua:{type}//{port|host}'"); + } + + String host = matcher.group("host"); + String portString = matcher.group("port"); + Integer port = StringUtils.isNotBlank(portString) ? Integer.parseInt(portString) : null; + String params = matcher.group("params") != null ? matcher.group("params").substring(1) : null; + + try { + return opcuaConnectionFactory.opcuaTcpPlcConnectionOf(InetAddress.getByName(host), port, params); + } catch (UnknownHostException e) { + throw new PlcConnectionException(e); + } + } + + @Override + public PlcConnection connect(String url, PlcAuthentication authentication) throws PlcConnectionException { + throw new PlcConnectionException("opcua does not support Auth at this state"); + } + +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java new file mode 100644 index 00000000000..b7221e238b3 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java @@ -0,0 +1,89 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.connection; + +import org.apache.commons.lang3.StringUtils; +import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.base.connection.AbstractPlcConnection; +import org.apache.plc4x.java.base.messages.*; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public abstract class BaseOPCUAPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcSubscriber { + + private static final Logger logger = LoggerFactory.getLogger(BaseOPCUAPlcConnection.class); + + BaseOPCUAPlcConnection(String params) { + + if (!StringUtils.isEmpty(params)) { + for (String param : params.split("&")) { + String[] paramElements = param.split("="); + String paramName = paramElements[0]; + if (paramElements.length == 2) { + String paramValue = paramElements[1]; + switch (paramName) { + default: + logger.debug("Unknown parameter {} with value {}", paramName, paramValue); + } + } else { + logger.debug("Unknown no-value parameter {}", paramName); + } + } + } + } + + @Override + public boolean canRead() { + return true; + } + + @Override + public boolean canWrite() { + return true; + } + + @Override + public PlcReadRequest.Builder readRequestBuilder() { + return new DefaultPlcReadRequest.Builder(this, new OpcuaPlcFieldHandler()); + } + + @Override + public PlcWriteRequest.Builder writeRequestBuilder() { + return new DefaultPlcWriteRequest.Builder(this, new OpcuaPlcFieldHandler()); + } + + @Override + public boolean canSubscribe() { + return true; + } + + @Override + public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() { + return new DefaultPlcSubscriptionRequest.Builder(this, new OpcuaPlcFieldHandler()); + } + + @Override + public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() { + return new DefaultPlcUnsubscriptionRequest.Builder(this); + } + + +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java new file mode 100644 index 00000000000..1bf0e60f0a8 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java @@ -0,0 +1,36 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.connection; + +import java.net.InetAddress; +import java.util.Objects; + +public class OPCUAConnectionFactory { + + public OPCUATcpPlcConnection opcuaTcpPlcConnectionOf(InetAddress address, Integer port, String params) { + Objects.requireNonNull(address); + + if (port == null) { + return OPCUATcpPlcConnection.of(address, params); + } else { + return OPCUATcpPlcConnection.of(address, port, params); + } + } + +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java new file mode 100644 index 00000000000..72352267791 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java @@ -0,0 +1,474 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.connection; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.api.model.PlcConsumerRegistration; +import org.apache.plc4x.java.api.model.PlcField; +import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; + +import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.base.messages.*; +import org.apache.plc4x.java.base.messages.items.*; +import org.apache.plc4x.java.base.model.SubscriptionPlcField; +import org.apache.plc4x.java.opcua.protocol.OpcuaField; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaSubsriptionHandle; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; +import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider; +import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider; +import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem; +import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription; +import org.eclipse.milo.opcua.stack.client.DiscoveryClient; +import org.eclipse.milo.opcua.stack.core.AttributeId; +import org.eclipse.milo.opcua.stack.core.Identifiers; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy; +import org.eclipse.milo.opcua.stack.core.types.builtin.*; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort; +import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode; +import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; +import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest; +import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; + +public class OPCUATcpPlcConnection extends BaseOPCUAPlcConnection { + + private static final int OPCUA_DEFAULT_TCP_PORT = 4840; + + private static final Logger logger = LoggerFactory.getLogger(OPCUATcpPlcConnection.class); + private InetAddress address; + private int port; + private String params; + private OpcUaClient client; + private boolean isConnected = false; + private final AtomicLong clientHandles = new AtomicLong(1L); + private OPCUATcpPlcConnection(InetAddress address, String params) { + this( address, OPCUA_DEFAULT_TCP_PORT, params); + logger.info("Configured OPCUATcpPlcConnection with: host-name {}", address.getHostAddress()); + } + + public OPCUATcpPlcConnection(InetAddress address, int port, String params) { + this(params); + logger.info("Configured OPCUATcpPlcConnection with: host-name {}", address.getHostAddress()); + this.address = address; + this.port = port; + this.params = params; + } + + public OPCUATcpPlcConnection(String params) { + super(params); + } + + public static OPCUATcpPlcConnection of(InetAddress address, String params) { + return new OPCUATcpPlcConnection(address, params); + } + + public static OPCUATcpPlcConnection of(InetAddress address, int port, String params) { + return new OPCUATcpPlcConnection(address, port, params); + } + + + + public InetAddress getRemoteAddress() { + return null; + } + + @Override + public void connect() throws PlcConnectionException { + List endpoints = null; + + try { + endpoints = DiscoveryClient.getEndpoints(getEndpointUrl(address, port, params)).get(); + } catch (Throwable ex) { + // try the explicit discovery endpoint as well + String discoveryUrl = getEndpointUrl(address, port, params); + + if (!discoveryUrl.endsWith("/")) { + discoveryUrl += "/"; + } + discoveryUrl += "discovery"; + + logger.info("Trying explicit discovery URL: {}", discoveryUrl); + try { + endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + + EndpointDescription endpoint = null; + try { + endpoint = endpoints.stream() + .filter(e -> e.getSecurityPolicyUri().equals(getSecurityPolicy().getUri())) + .filter(endpointFilter()) + .findFirst() + .orElseThrow(() -> new Exception("no desired endpoints returned")); + } catch (Exception e) { + e.printStackTrace(); + } + + OpcUaClientConfig config = OpcUaClientConfig.builder() + .setApplicationName(LocalizedText.english("eclipse milo opc-ua client")) + .setApplicationUri("urn:eclipse:milo:examples:client") + .setEndpoint(endpoint) + .setIdentityProvider(getIdentityProvider()) + .setRequestTimeout(UInteger.valueOf(5000)) + .build(); + + try { + this.client = OpcUaClient.create(config); + this.client.connect().get(); + isConnected = true; + } catch (UaException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + isConnected = false; + } catch (ExecutionException e) { + isConnected = false; + } + } + + @Override + public boolean isConnected() { + return client != null && isConnected; + } + + @Override + public void close() throws Exception { + if(client != null){ + client.disconnect().get(); + isConnected = false; + } + } + + @Override + public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { + InternalPlcSubscriptionRequest internalPlcSubscriptionRequest = checkInternal(subscriptionRequest, InternalPlcSubscriptionRequest.class); + CompletableFuture future = CompletableFuture.supplyAsync(() ->{ + Map> responseItems = internalPlcSubscriptionRequest.getSubscriptionPlcFieldMap().entrySet().stream() + .map(subscriptionPlcFieldEntry -> { + final String plcFieldName = subscriptionPlcFieldEntry.getKey(); + final SubscriptionPlcField subscriptionPlcField = subscriptionPlcFieldEntry.getValue(); + final OpcuaField field = (OpcuaField)Objects.requireNonNull(subscriptionPlcField.getPlcField()); + long cycleTime = subscriptionPlcField.getDuration().orElse(Duration.ofSeconds(1)).toMillis(); + NodeId idNode = generateNodeId(field); + ReadValueId readValueId = new ReadValueId( + idNode, + AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE); + UInteger clientHandle = uint(clientHandles.getAndIncrement()); + + MonitoringParameters parameters = new MonitoringParameters( + clientHandle, + (double) cycleTime, // sampling interval + null, // filter, null means use default + uint(1), // queue size + true // discard oldest + ); + MonitoringMode monitoringMode; + switch (subscriptionPlcField.getPlcSubscriptionType()) { + case CYCLIC: + monitoringMode = MonitoringMode.Sampling; + break; + case CHANGE_OF_STATE: + monitoringMode = MonitoringMode.Reporting; + break; + case EVENT: + monitoringMode = MonitoringMode.Reporting; + break; + default: monitoringMode = MonitoringMode.Reporting; + } + + PlcSubscriptionHandle subHandle = null; + PlcResponseCode responseCode = PlcResponseCode.ACCESS_DENIED; + try { + UaSubscription subscription = client.getSubscriptionManager().createSubscription(1000.0).get(); + + MonitoredItemCreateRequest request = new MonitoredItemCreateRequest( + readValueId, monitoringMode, parameters); + List requestList = new LinkedList<>(); + requestList.add(request); + OpcuaSubsriptionHandle subsriptionHandle = new OpcuaSubsriptionHandle(plcFieldName, clientHandle); + BiConsumer onItemCreated = + (item, id) -> item.setValueConsumer(subsriptionHandle::onSubscriptionValue); + + List items = subscription.createMonitoredItems( + TimestampsToReturn.Both, + requestList, + onItemCreated + ).get(); + + subHandle = subsriptionHandle; + responseCode = PlcResponseCode.OK; + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + + return Pair.of(plcFieldName, Pair.of(responseCode, subHandle)); + }) + .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); + PlcSubscriptionResponse result = new DefaultPlcSubscriptionResponse(internalPlcSubscriptionRequest, responseItems); + return result; + }); + + return future; + } + + @Override + public CompletableFuture unsubscribe(PlcUnsubscriptionRequest unsubscriptionRequest) { + InternalPlcUnsubscriptionRequest internalPlcUnsubscriptionRequest = checkInternal(unsubscriptionRequest, InternalPlcUnsubscriptionRequest.class); + internalPlcUnsubscriptionRequest.getInternalPlcSubscriptionHandles().forEach(o -> { + OpcuaSubsriptionHandle opcSubHandle = (OpcuaSubsriptionHandle) o; + try { + client.getSubscriptionManager().deleteSubscription(opcSubHandle.getClientHandle()).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + }); + + return null; + } + + @Override + public PlcConsumerRegistration register(Consumer consumer, Collection handles) { + List unregisters = new LinkedList<>(); + handles.forEach(plcSubscriptionHandle -> unregisters.add(plcSubscriptionHandle.register(consumer))); + + return () -> unregisters.forEach(PlcConsumerRegistration::unregister); + } + + @Override + public void unregister(PlcConsumerRegistration registration) { + registration.unregister(); + } + + @Override + public CompletableFuture read(PlcReadRequest readRequest) { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + readRequest.getFields(); + Map> fields = new HashMap<>(); + List readValueIds = new LinkedList<>(); + List readPLCValues = readRequest.getFields(); + for (PlcField field: readPLCValues) { + NodeId idNode = generateNodeId((OpcuaField) field); + readValueIds.add(idNode); + } + + CompletableFuture> dataValueCompletableFuture = client.readValues(0.0, TimestampsToReturn.Both, readValueIds); + List readValues = null; + try { + readValues = dataValueCompletableFuture.get(); + } catch (InterruptedException e) { + e.printStackTrace(); + readValues = new LinkedList<>(); + } catch (ExecutionException e) { + e.printStackTrace(); + readValues = new LinkedList<>(); + } + for(int counter = 0; counter < readValues.size(); counter++){ + PlcResponseCode resultCode = PlcResponseCode.OK; + BaseDefaultFieldItem stringItem = null; + if(readValues.get(counter).getStatusCode() != StatusCode.GOOD){ + resultCode = PlcResponseCode.NOT_FOUND; + }else{ + stringItem = encodeFieldItem(readValues.get(counter)); + + } + Pair newPair = new ImmutablePair<>(resultCode, stringItem); + fields.put((String) readRequest.getFieldNames().toArray()[counter], newPair); + + + } + InternalPlcReadRequest internalPlcReadRequest = checkInternal(readRequest, InternalPlcReadRequest.class); + PlcReadResponse response = new DefaultPlcReadResponse(internalPlcReadRequest, fields ); + return response; + }); + + + return future; + } + + private NodeId generateNodeId(OpcuaField uaField){ + NodeId idNode = null; + switch (uaField.getIdentifierType()) { + case s: + idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); + break; + case i: + idNode = new NodeId(uaField.getNamespace(), UInteger.valueOf(uaField.getIdentifier())); + break; + case g: + idNode = new NodeId(uaField.getNamespace(), UUID.fromString(uaField.getIdentifier())); + break; + case b: + idNode = new NodeId(uaField.getNamespace(), new ByteString(uaField.getIdentifier().getBytes())); + break; + + default: idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); + } + + return idNode; + } + + public static BaseDefaultFieldItem encodeFieldItem(DataValue value){ + NodeId typeNode = value.getValue().getDataType().get(); + Object objValue = value.getValue().getValue(); + + if(typeNode.equals(Identifiers.Boolean)){ + return new DefaultBooleanFieldItem((Boolean)objValue); + }else if (typeNode.equals(Identifiers.ByteString)){ + byte[] array = ((ByteString)objValue).bytes(); + Byte[] byteArry = new Byte[array.length]; + int counter = 0; + for (byte bytie: array + ) { + byteArry[counter] = bytie; + counter++; + } + return new DefaultByteArrayFieldItem(byteArry); + }else if (typeNode.equals(Identifiers.Integer)){ + return new DefaultIntegerFieldItem((Integer)objValue); + }else if (typeNode.equals(Identifiers.Int16)){ + return new DefaultShortFieldItem((Short)objValue); + }else if (typeNode.equals(Identifiers.Int32)){ + return new DefaultIntegerFieldItem((Integer)objValue); + }else if (typeNode.equals(Identifiers.Int64)){ + return new DefaultLongFieldItem((Long)objValue); + }else if (typeNode.equals(Identifiers.UInteger)){ + return new DefaultLongFieldItem((Long)objValue); + }else if (typeNode.equals(Identifiers.UInt16)){ + return new DefaultIntegerFieldItem(((UShort)objValue).intValue()); + }else if (typeNode.equals(Identifiers.UInt32)){ + return new DefaultLongFieldItem(((UInteger)objValue).longValue()); + }else if (typeNode.equals(Identifiers.UInt64)){ + return new DefaultBigIntegerFieldItem(new BigInteger(objValue.toString())); + }else if (typeNode.equals(Identifiers.Byte)){ + return new DefaultShortFieldItem(Short.valueOf(objValue.toString())); + }else if (typeNode.equals(Identifiers.Float)){ + return new DefaultFloatFieldItem((Float)objValue); + }else if (typeNode.equals(Identifiers.Double)){ + return new DefaultDoubleFieldItem((Double)objValue); + }else if (typeNode.equals(Identifiers.SByte)){ + return new DefaultByteFieldItem((Byte)objValue); + }else { + return new DefaultStringFieldItem(objValue.toString()); + } + + } + + @Override + public CompletableFuture write(PlcWriteRequest writeRequest) { + CompletableFuture future; + future = CompletableFuture.supplyAsync(() -> { + + InternalPlcWriteRequest internalPlcWriteRequest = (InternalPlcWriteRequest) writeRequest; + + List writePLCValues = writeRequest.getFields(); + LinkedList values = new LinkedList<>(); + LinkedList ids = new LinkedList<>(); + LinkedList names = new LinkedList<>(); + Map fieldResponse = new HashMap<>(); + for (String fieldName: writeRequest.getFieldNames()) { + OpcuaField uaField = (OpcuaField) writeRequest.getField(fieldName); + NodeId idNode = generateNodeId(uaField); + Variant var = new Variant(internalPlcWriteRequest.getFieldItem(fieldName).getObject(0)); + DataValue value = new DataValue(var, null, null); + ids.add(idNode); + names.add(fieldName); + values.add(value); + } + CompletableFuture> opcRequest = + client.writeValues(ids, values); + List statusCodes = null; + try { + statusCodes = opcRequest.get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + for(int counter = 0; counter < names.size(); counter++){ + PlcResponseCode resultCode = PlcResponseCode.OK; + BaseDefaultFieldItem stringItem = null; + if(statusCodes != null && statusCodes.size() > counter){ + if(statusCodes.get(counter).isGood()){ + resultCode = PlcResponseCode.OK; + }else if(statusCodes.get(counter).isUncertain()){ + resultCode = PlcResponseCode.NOT_FOUND; + }else { + resultCode = PlcResponseCode.ACCESS_DENIED; + } + }else{ + resultCode = PlcResponseCode.ACCESS_DENIED; + } + fieldResponse.put(names.get(counter), resultCode); + } + InternalPlcWriteRequest internalPlcReadRequest = checkInternal(writeRequest, InternalPlcWriteRequest.class); + PlcWriteResponse response = new DefaultPlcWriteResponse(internalPlcReadRequest, fieldResponse); + return response; + }); + + + return future; + } + + + private String getEndpointUrl(InetAddress address, Integer port, String params) { + return "opc.tcp://" + address.getHostAddress() +":" + port + "/" + params; + } + + private Predicate endpointFilter() { + return e -> true; + } + + private SecurityPolicy getSecurityPolicy() { + return SecurityPolicy.None; + } + + private IdentityProvider getIdentityProvider() { + return new AnonymousProvider(); + } +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java new file mode 100644 index 00000000000..317d6ade33e --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java @@ -0,0 +1,115 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.plc4x.java.opcua.protocol; + +import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; +import org.apache.plc4x.java.api.model.PlcField; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaDataTypes; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaIdentifierType; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class OpcuaField implements PlcField { + + private static final Pattern ADDRESS_PATTERN = Pattern.compile("^ns=(?\\d+);(?[isgb])=((?\\w+))?"); + + private final OpcuaIdentifierType identifierType; + + private final int namespace; + + private final String identifier; + + protected OpcuaField(int namespace, OpcuaIdentifierType identifierType, String identifier) { + this.namespace = namespace; + this.identifier = identifier; + this.identifierType = identifierType; + if (this.identifier == null || this.namespace < 0) { + throw new IllegalArgumentException("Identifier can not be null or Namespace can not be lower then 0."); + } + } + + private OpcuaField(Integer namespace, String identifier, OpcuaIdentifierType identifierType) { + this.identifier = Objects.requireNonNull(identifier); + this.identifierType = Objects.requireNonNull(identifierType); + this.namespace = namespace != null ? namespace : 0; + if (this.namespace < 0) { + throw new IllegalArgumentException("namespace must be greater then zero. Was " + this.namespace); + } + } + + public static OpcuaField of(String address) { + Matcher matcher = ADDRESS_PATTERN.matcher(address); + if (!matcher.matches()) { + throw new PlcInvalidFieldException(address, ADDRESS_PATTERN, "{address}"); + } + String identifier = matcher.group("identifier"); + + String identifierTypeString = matcher.group("identifierType"); + OpcuaIdentifierType identifierType = OpcuaIdentifierType.valueOf(identifierTypeString); + + String namespaceString = matcher.group("namespace"); + Integer namespace = namespaceString != null ? Integer.valueOf(namespaceString) : 0; + + return new OpcuaField(namespace, identifier, identifierType); + } + + + public static boolean matches(String address) { + return ADDRESS_PATTERN.matcher(address).matches(); + } + + public int getNamespace() { + return namespace; + } + + public String getIdentifier() { + return identifier; + } + + public OpcuaIdentifierType getIdentifierType() { + return identifierType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof OpcuaField)) { + return false; + } + OpcuaField that = (OpcuaField) o; + return namespace == that.namespace && identifier.equals(that.identifier); + } + + @Override + public int hashCode() { + return Objects.hash(namespace); + } + + @Override + public String toString() { + return "OpcuaField{" + + "namespace=" + namespace + + "identifier=" + identifier + + '}'; + } +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java new file mode 100644 index 00000000000..e3f056ecfd7 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java @@ -0,0 +1,43 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.protocol.model; + +public enum OpcuaDataTypes { + BOOL, + SByte, + Byte, + Int16, + UInt16, + Int32, + UInt32, + Int64, + Uint64, + Float, + Double, + StatusCode, + String, + DateTime, + Guid, + ByteString, + XMLElement, + NodeId, + ExpandedNodeId, + QualifiedName + +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java new file mode 100644 index 00000000000..afcef2a8e67 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java @@ -0,0 +1,26 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.protocol.model; + +public enum OpcuaIdentifierType { + s, + i, + g, + b +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java new file mode 100644 index 00000000000..81fe4f260e5 --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java @@ -0,0 +1,146 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.protocol.model; + + + +import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; +import org.apache.plc4x.java.api.model.PlcField; +import org.apache.plc4x.java.base.connection.DefaultPlcFieldHandler; +import org.apache.plc4x.java.base.messages.items.*; +import org.apache.plc4x.java.opcua.protocol.OpcuaField; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class OpcuaPlcFieldHandler extends DefaultPlcFieldHandler { + + @Override + public PlcField createField(String fieldQuery) throws PlcInvalidFieldException { + if (OpcuaField.matches(fieldQuery)) { + return OpcuaField.of(fieldQuery); + } + throw new PlcInvalidFieldException(fieldQuery); + } + + @Override + public BaseDefaultFieldItem encodeString(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add(item.toString()); + } + return new DefaultStringFieldItem(resultSet.toArray(new String[0])); + } + + @Override + public BaseDefaultFieldItem encodeBoolean(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Boolean) item); + } + return new DefaultBooleanFieldItem(resultSet.toArray(new Boolean[0])); + } + + @Override + public BaseDefaultFieldItem encodeByte(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Byte) item); + } + return new DefaultByteFieldItem(resultSet.toArray(new Byte[0])); + } + + @Override + public BaseDefaultFieldItem encodeShort(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Short) item); + } + return new DefaultShortFieldItem(resultSet.toArray(new Short[0])); + } + + @Override + public BaseDefaultFieldItem encodeInteger(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Integer) item); + } + return new DefaultIntegerFieldItem(resultSet.toArray(new Integer[0])); + } + + @Override + public BaseDefaultFieldItem encodeBigInteger(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((BigInteger) item); + } + return new DefaultBigIntegerFieldItem(resultSet.toArray(new BigInteger[0])); + } + + @Override + public BaseDefaultFieldItem encodeLong(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Long) item); + } + return new DefaultLongFieldItem(resultSet.toArray(new Long[0])); + } + + @Override + public BaseDefaultFieldItem encodeFloat(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Float) item); + } + return new DefaultFloatFieldItem(resultSet.toArray(new Float[0])); + } + + + + @Override + public BaseDefaultFieldItem encodeDouble(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Double) item); + } + return new DefaultDoubleFieldItem(resultSet.toArray(new Double[0])); + } + + + @Override + public BaseDefaultFieldItem encodeByteArray(PlcField field, Object[] values) { + OpcuaField adsField = (OpcuaField) field; + ArrayList resultSet = new ArrayList<>(); + for(Object item : values){ + resultSet.add((Byte[]) item); + } + return new DefaultByteArrayFieldItem(resultSet.toArray(new Byte[0][0])); + } +} diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java new file mode 100644 index 00000000000..4a033457c4e --- /dev/null +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java @@ -0,0 +1,76 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.protocol.model; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; +import org.apache.plc4x.java.api.model.PlcConsumerRegistration; +import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; +import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionEvent; +import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem; +import org.apache.plc4x.java.opcua.connection.OPCUATcpPlcConnection; +import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; + +import java.awt.*; +import java.time.Instant; +import java.util.*; +import java.util.function.Consumer; + +public class OpcuaSubsriptionHandle implements PlcSubscriptionHandle { + Set< Consumer> consumers = new HashSet<>(); + String fieldName; + public UInteger getClientHandle() { + return clientHandle; + } + + UInteger clientHandle; + + public OpcuaSubsriptionHandle(String fieldName, UInteger clientHandle){ + this.clientHandle = clientHandle; + } + @Override + public PlcConsumerRegistration register(Consumer consumer) { + consumers.add(consumer); + return () -> {consumers.remove(consumer);}; + } + + public void onSubscriptionValue(UaMonitoredItem item, DataValue value) { + consumers.forEach(plcSubscriptionEventConsumer -> { + PlcResponseCode resultCode = PlcResponseCode.OK; + BaseDefaultFieldItem stringItem = null; + if(value.getStatusCode() != StatusCode.GOOD){ + resultCode = PlcResponseCode.NOT_FOUND; + }else{ + stringItem = OPCUATcpPlcConnection.encodeFieldItem(value); + + } + Map> fields = new HashMap<>(); + Pair newPair = new ImmutablePair<>(resultCode, stringItem); + fields.put(fieldName, newPair); + PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), fields); + plcSubscriptionEventConsumer.accept(event); + }); + } + +} diff --git a/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver b/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver new file mode 100644 index 00000000000..860acdcd5af --- /dev/null +++ b/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.plc4x.java.opcua.OPCUAPlcDriver diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java new file mode 100644 index 00000000000..eb29494d484 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java @@ -0,0 +1,125 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +package org.apache.plc4x.java.opcua.connection; + +import org.apache.plc4x.java.PlcDriverManager; +import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.api.model.PlcConsumerRegistration; +import org.apache.plc4x.java.api.model.PlcField; +import org.apache.plc4x.java.api.types.PlcSubscriptionType; +import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionRequest; +import org.apache.plc4x.java.base.model.SubscriptionPlcField; +import org.apache.plc4x.java.opcua.protocol.OpcuaField; +import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; + +import java.math.BigInteger; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +public class ManualPLC4XOPCUA { + public static void main(String args[]){ + + + + + OPCUATcpPlcConnection adsConnection = null; + OpcuaPlcFieldHandler fieldH = new OpcuaPlcFieldHandler(); + PlcField field = fieldH.createField("ns=2;i=10855"); + try { + adsConnection = (OPCUATcpPlcConnection) + new PlcDriverManager().getConnection("opcua:tcp://opcua.demo-this.com:51210/UA/SampleServer"); + + } catch (PlcConnectionException e) { + e.printStackTrace(); + } + try { + PlcReadRequest.Builder builder = adsConnection.readRequestBuilder(); + //builder.addItem("String", "ns=2;i=10855"); + builder.addItem("Bool", "ns=2;i=10844"); + builder.addItem("ByteString", "ns=2;i=10858"); + builder.addItem("Byte", "ns=2;i=10846"); + builder.addItem("Double", "ns=2;i=10854"); + builder.addItem("Float", "ns=2;i=10853"); + builder.addItem("Int16", "ns=2;i=10847"); + builder.addItem("Int32", "ns=2;i=10849"); + builder.addItem("Int64", "ns=2;i=10851"); + builder.addItem("Integer", "ns=2;i=10869"); + builder.addItem("SByte", "ns=2;i=10845"); + builder.addItem("String", "ns=2;i=10855"); + builder.addItem("UInt16", "ns=2;i=10848"); + builder.addItem("UInt32", "ns=2;i=10850"); + builder.addItem("UInt64", "ns=2;i=10852"); + builder.addItem("UInteger", "ns=2;i=10870"); + + builder.addItem("DoesNotExists", "ns=2;i=12512623"); + + PlcReadRequest request = builder.build(); + PlcReadResponse response = adsConnection.read(request).get(); + Collection coll = response.getAllStrings("String"); + + PlcWriteRequest.Builder wBuilder = adsConnection.writeRequestBuilder(); + //wBuilder.addItem("w-Bool", "ns=2;i=10844", "TEST"); + //wBuilder.addItem("w-Bool", "ns=2;i=11012", true); + //--->> wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); + wBuilder.addItem("w-String", "ns=2;i=10855", "TEST"); + + /* + wBuilder.addItem("w-Byte", "ns=2;i=10846", (byte)1); + wBuilder.addItem("w-Double", "ns=2;i=10854", (double)0.25); + wBuilder.addItem("w-Float", "ns=2;i=10853", (float)0.25); + wBuilder.addItem("w-Int16", "ns=2;i=10847", (short)12); + wBuilder.addItem("w-Int32", "ns=2;i=10849", (int)314); + wBuilder.addItem("w-Int64", "ns=2;i=10851", (long)123125); + wBuilder.addItem("w-Integer", "ns=2;i=10869", (int)314); + wBuilder.addItem("w-SByte", "ns=2;i=10845", (short)23); + wBuilder.addItem("w-String", "ns=2;i=10855", "TEST"); + wBuilder.addItem("w-UInt16", "ns=2;i=10848", (int)222); + wBuilder.addItem("w-UInt32", "ns=2;i=10850", (long)21412); + wBuilder.addItem("w-UInt64", "ns=2;i=10852", new BigInteger("1245152")); + wBuilder.addItem("w-UInteger", "ns=2;i=10870", new BigInteger("1245152")); + + */ + PlcWriteRequest writeRequest = wBuilder.build(); + PlcWriteResponse wResponse = adsConnection.write(writeRequest).get(); + + PlcSubscriptionResponse subResp = adsConnection.subscribe(new DefaultPlcSubscriptionRequest( + adsConnection, + new LinkedHashMap<>( + Collections.singletonMap("field1", + new SubscriptionPlcField(PlcSubscriptionType.CHANGE_OF_STATE, OpcuaField.of("ns=2;i=10855"), Duration.of(1, ChronoUnit.SECONDS))) + ) + )).get(); + + Consumer consumer = plcSubscriptionEvent -> System.out.println(plcSubscriptionEvent.toString()); + PlcConsumerRegistration registration = adsConnection.register(consumer, subResp.getSubscriptionHandles()); + Thread.sleep(7000); + registration.unregister(); + Thread.sleep(200000); + adsConnection.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/plc4j/drivers/pom.xml b/plc4j/drivers/pom.xml index 34f60a25c27..cf47c0761ca 100644 --- a/plc4j/drivers/pom.xml +++ b/plc4j/drivers/pom.xml @@ -39,6 +39,7 @@ modbus s7 simulated + opcua From dd5a9e0c86419e2ec913603012e1725805841ffe Mon Sep 17 00:00:00 2001 From: Matthias Milan Strljic Date: Mon, 13 May 2019 19:24:28 +0200 Subject: [PATCH 2/8] Added NOTICE entry for the use of Milo --- NOTICE | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NOTICE b/NOTICE index 97048d6e923..6ff3737bfe3 100644 --- a/NOTICE +++ b/NOTICE @@ -8,3 +8,6 @@ The Apache Software Foundation (http://www.apache.org/). This product includes software developed at The Netty project (https://netty.io/). + +This product includes software developed at +The Milo project (https://github.com/eclipse/milo). From 2840896d00c7883b1c130731027f1389f9582018 Mon Sep 17 00:00:00 2001 From: Mathi Date: Mon, 13 May 2019 19:45:03 +0200 Subject: [PATCH 3/8] Added Author field --- .../plc4x/java/opcua/OPCUAPlcDriver.java | 12 +++------- .../connection/BaseOPCUAPlcConnection.java | 7 +++++- .../connection/OPCUAConnectionFactory.java | 2 ++ .../connection/OPCUATcpPlcConnection.java | 3 ++- .../plc4x/java/opcua/protocol/OpcuaField.java | 5 ++-- .../opcua/protocol/model/OpcuaDataTypes.java | 2 ++ .../protocol/model/OpcuaIdentifierType.java | 2 ++ .../protocol/model/OpcuaPlcFieldHandler.java | 5 ++-- .../model/OpcuaSubsriptionHandle.java | 8 +++++-- .../opcua/connection/ManualPLC4XOPCUA.java | 24 +++++++++---------- 10 files changed, 40 insertions(+), 30 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 68f3886f5ef..4e20b8ccefb 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 @@ -15,27 +15,21 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua; import org.apache.commons.lang3.StringUtils; -import org.apache.plc4x.java.PlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.authentication.PlcAuthentication; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; -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.model.PlcField; import org.apache.plc4x.java.opcua.connection.OPCUAConnectionFactory; -import org.apache.plc4x.java.opcua.connection.OPCUATcpPlcConnection; -import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; import org.apache.plc4x.java.spi.PlcDriver; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java index b7221e238b3..26cbb0939f7 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java @@ -15,11 +15,16 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.connection; import org.apache.commons.lang3.StringUtils; -import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.api.messages.PlcReadRequest; +import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest; +import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest; +import org.apache.plc4x.java.api.messages.PlcWriteRequest; import org.apache.plc4x.java.base.connection.AbstractPlcConnection; import org.apache.plc4x.java.base.messages.*; import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java index 1bf0e60f0a8..b82b696cac4 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.connection; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java index 72352267791..4929bf8d44c 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.connection; @@ -25,7 +27,6 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcField; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; - import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.base.messages.*; import org.apache.plc4x.java.base.messages.items.*; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java index 317d6ade33e..0ac3c9f121b 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java @@ -15,12 +15,13 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ package org.apache.plc4x.java.opcua.protocol; import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; import org.apache.plc4x.java.api.model.PlcField; -import org.apache.plc4x.java.opcua.protocol.model.OpcuaDataTypes; import org.apache.plc4x.java.opcua.protocol.model.OpcuaIdentifierType; import java.util.Objects; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java index e3f056ecfd7..c0bfe6522dd 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.protocol.model; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java index afcef2a8e67..599ad059f66 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.protocol.model; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java index 81fe4f260e5..0a3c5c6ba4e 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java @@ -15,13 +15,13 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.protocol.model; - import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.model.PlcField; import org.apache.plc4x.java.base.connection.DefaultPlcFieldHandler; import org.apache.plc4x.java.base.messages.items.*; @@ -29,7 +29,6 @@ Licensed to the Apache Software Foundation (ASF) under one import java.math.BigInteger; import java.util.ArrayList; -import java.util.List; public class OpcuaPlcFieldHandler extends DefaultPlcFieldHandler { diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java index 4a033457c4e..582993cfaf5 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.protocol.model; @@ -32,9 +34,11 @@ Licensed to the Apache Software Foundation (ASF) under one import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; -import java.awt.*; import java.time.Instant; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.function.Consumer; public class OpcuaSubsriptionHandle implements PlcSubscriptionHandle { diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java index eb29494d484..462b58a2f04 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java @@ -15,6 +15,8 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.connection; @@ -29,13 +31,11 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.opcua.protocol.OpcuaField; import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; -import java.math.BigInteger; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; public class ManualPLC4XOPCUA { @@ -44,18 +44,18 @@ public static void main(String args[]){ - OPCUATcpPlcConnection adsConnection = null; + OPCUATcpPlcConnection opcuaConnection = null; OpcuaPlcFieldHandler fieldH = new OpcuaPlcFieldHandler(); PlcField field = fieldH.createField("ns=2;i=10855"); try { - adsConnection = (OPCUATcpPlcConnection) + opcuaConnection = (OPCUATcpPlcConnection) new PlcDriverManager().getConnection("opcua:tcp://opcua.demo-this.com:51210/UA/SampleServer"); } catch (PlcConnectionException e) { e.printStackTrace(); } try { - PlcReadRequest.Builder builder = adsConnection.readRequestBuilder(); + PlcReadRequest.Builder builder = opcuaConnection.readRequestBuilder(); //builder.addItem("String", "ns=2;i=10855"); builder.addItem("Bool", "ns=2;i=10844"); builder.addItem("ByteString", "ns=2;i=10858"); @@ -76,10 +76,10 @@ public static void main(String args[]){ builder.addItem("DoesNotExists", "ns=2;i=12512623"); PlcReadRequest request = builder.build(); - PlcReadResponse response = adsConnection.read(request).get(); + PlcReadResponse response = opcuaConnection.read(request).get(); Collection coll = response.getAllStrings("String"); - PlcWriteRequest.Builder wBuilder = adsConnection.writeRequestBuilder(); + PlcWriteRequest.Builder wBuilder = opcuaConnection.writeRequestBuilder(); //wBuilder.addItem("w-Bool", "ns=2;i=10844", "TEST"); //wBuilder.addItem("w-Bool", "ns=2;i=11012", true); //--->> wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); @@ -102,10 +102,10 @@ public static void main(String args[]){ */ PlcWriteRequest writeRequest = wBuilder.build(); - PlcWriteResponse wResponse = adsConnection.write(writeRequest).get(); + PlcWriteResponse wResponse = opcuaConnection.write(writeRequest).get(); - PlcSubscriptionResponse subResp = adsConnection.subscribe(new DefaultPlcSubscriptionRequest( - adsConnection, + PlcSubscriptionResponse subResp = opcuaConnection.subscribe(new DefaultPlcSubscriptionRequest( + opcuaConnection, new LinkedHashMap<>( Collections.singletonMap("field1", new SubscriptionPlcField(PlcSubscriptionType.CHANGE_OF_STATE, OpcuaField.of("ns=2;i=10855"), Duration.of(1, ChronoUnit.SECONDS))) @@ -113,11 +113,11 @@ public static void main(String args[]){ )).get(); Consumer consumer = plcSubscriptionEvent -> System.out.println(plcSubscriptionEvent.toString()); - PlcConsumerRegistration registration = adsConnection.register(consumer, subResp.getSubscriptionHandles()); + PlcConsumerRegistration registration = opcuaConnection.register(consumer, subResp.getSubscriptionHandles()); Thread.sleep(7000); registration.unregister(); Thread.sleep(200000); - adsConnection.close(); + opcuaConnection.close(); } catch (Exception e) { e.printStackTrace(); } From 0905b60fad46503e4da09de2354e37fbb53b5953 Mon Sep 17 00:00:00 2001 From: Matthias Milan Strljic Date: Mon, 13 May 2019 19:52:23 +0200 Subject: [PATCH 4/8] [Fixed] DefaultPlcWriteRequest returns for the types Byte[] and byte[] the wrong handle function "encodeDateTime" it become changed to "encodeByteArray" --- .../plc4x/java/base/messages/DefaultPlcWriteRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java index 67dc29f5d01..641bc7eb5f0 100644 --- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java +++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java @@ -209,12 +209,12 @@ public Builder addItem(String name, String fieldQuery, LocalDateTime... values) @Override public Builder addItem(String name, String fieldQuery, byte[]... values) { - return addItem(name, fieldQuery, values, fieldHandler::encodeDateTime); + return addItem(name, fieldQuery, values, fieldHandler::encodeByteArray); } @Override public Builder addItem(String name, String fieldQuery, Byte[]... values) { - return addItem(name, fieldQuery, values, fieldHandler::encodeDateTime); + return addItem(name, fieldQuery, values, fieldHandler::encodeByteArray); } @Override From 6a189568efa0b3a14caff27842b118b40ab1fb15 Mon Sep 17 00:00:00 2001 From: Matthias Milan Strljic Date: Mon, 13 May 2019 21:45:11 +0200 Subject: [PATCH 5/8] [Fixed] Failure while Timeout of write request [Added] requestTimeout field for variable timeouts --- plc4j/drivers/opcua/pom.xml | 3 ++ .../plc4x/java/opcua/OPCUAPlcDriver.java | 4 +- .../connection/OPCUAConnectionFactory.java | 6 +-- .../connection/OPCUATcpPlcConnection.java | 53 ++++++++----------- .../protocol/model/OpcuaPlcFieldHandler.java | 12 +++-- .../opcua/connection/ManualPLC4XOPCUA.java | 11 ++-- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml index 69a36cd4e88..f0f47df59b8 100644 --- a/plc4j/drivers/opcua/pom.xml +++ b/plc4j/drivers/opcua/pom.xml @@ -64,7 +64,10 @@ org.apache.commons commons-lang3 + + + > wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); - wBuilder.addItem("w-String", "ns=2;i=10855", "TEST"); - + wBuilder.addItem("w-Bool", "ns=2;i=11012", true); /* + wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); wBuilder.addItem("w-Byte", "ns=2;i=10846", (byte)1); wBuilder.addItem("w-Double", "ns=2;i=10854", (double)0.25); wBuilder.addItem("w-Float", "ns=2;i=10853", (float)0.25); @@ -99,8 +97,7 @@ public static void main(String args[]){ wBuilder.addItem("w-UInt32", "ns=2;i=10850", (long)21412); wBuilder.addItem("w-UInt64", "ns=2;i=10852", new BigInteger("1245152")); wBuilder.addItem("w-UInteger", "ns=2;i=10870", new BigInteger("1245152")); - - */ +*/ PlcWriteRequest writeRequest = wBuilder.build(); PlcWriteResponse wResponse = opcuaConnection.write(writeRequest).get(); From a743b5d3dd335bb922077c7e600a493e0f507d57 Mon Sep 17 00:00:00 2001 From: Mathi Date: Tue, 14 May 2019 00:17:38 +0200 Subject: [PATCH 6/8] Added test class bodies and renamed consistently --- ...PCUAPlcDriver.java => OpcuaPlcDriver.java} | 12 ++-- ...ction.java => BaseOpcuaPlcConnection.java} | 8 +-- ...ctory.java => OpcuaConnectionFactory.java} | 8 +-- ...ection.java => OpcuaTcpPlcConnection.java} | 25 +++---- .../plc4x/java/opcua/protocol/OpcuaField.java | 2 +- .../{model => }/OpcuaPlcFieldHandler.java | 3 +- .../{model => }/OpcuaSubsriptionHandle.java | 6 +- .../org.apache.plc4x.java.spi.PlcDriver | 2 +- ...lPLC4XOPCUA.java => ManualPLC4XOpcua.java} | 17 ++--- .../plc4x/java/opcua/OpcuaPlcDriverTest.java | 66 +++++++++++++++++++ .../apache/plc4x/java/opcua/UtilsTest.java | 39 +++++++++++ .../connection/OpcuaTcpPlcConnectionTest.java | 35 ++++++++++ .../java/opcua/protocol/OpcuaFieldTest.java | 50 ++++++++++++++ .../protocol/OpcuaPlcFieldHandlerTest.java | 35 ++++++++++ .../protocol/OpcuaSubscriptionHandleTest.java | 35 ++++++++++ 15 files changed, 300 insertions(+), 43 deletions(-) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/{OPCUAPlcDriver.java => OpcuaPlcDriver.java} (90%) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/{BaseOPCUAPlcConnection.java => BaseOpcuaPlcConnection.java} (93%) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/{OPCUAConnectionFactory.java => OpcuaConnectionFactory.java} (83%) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/{OPCUATcpPlcConnection.java => OpcuaTcpPlcConnection.java} (96%) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/{model => }/OpcuaPlcFieldHandler.java (98%) rename plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/{model => }/OpcuaSubsriptionHandle.java (94%) rename plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/{connection/ManualPLC4XOPCUA.java => ManualPLC4XOpcua.java} (94%) create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java 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 similarity index 90% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OPCUAPlcDriver.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java index 271365ebc07..ef5f9858b78 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 @@ -25,7 +25,7 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.authentication.PlcAuthentication; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; -import org.apache.plc4x.java.opcua.connection.OPCUAConnectionFactory; +import org.apache.plc4x.java.opcua.connection.OpcuaConnectionFactory; import org.apache.plc4x.java.spi.PlcDriver; import java.net.InetAddress; @@ -37,20 +37,20 @@ Licensed to the Apache Software Foundation (ASF) under one * Implementation of the OPC UA protocol, based on: * - Eclipse Milo (https://github.com/eclipse/milo) */ -public class OPCUAPlcDriver implements PlcDriver { +public class OpcuaPlcDriver implements PlcDriver { public static final Pattern INET_ADDRESS_PATTERN = Pattern.compile("tcp://(?[\\w.-]+)(:(?\\d*))?"); public static final Pattern OPCUA_URI_PATTERN = Pattern.compile("^opcua:(" + INET_ADDRESS_PATTERN + ")?" + "(?/[\\w/]+)?"); private static final int requestTimeout = 10000; - private OPCUAConnectionFactory opcuaConnectionFactory; + private OpcuaConnectionFactory opcuaConnectionFactory; - public OPCUAPlcDriver() { - this.opcuaConnectionFactory = new OPCUAConnectionFactory(); + public OpcuaPlcDriver() { + this.opcuaConnectionFactory = new OpcuaConnectionFactory(); } - public OPCUAPlcDriver(OPCUAConnectionFactory opcuaConnectionFactory) { + public OpcuaPlcDriver(OpcuaConnectionFactory opcuaConnectionFactory) { this.opcuaConnectionFactory = opcuaConnectionFactory; } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java similarity index 93% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java index 26cbb0939f7..0585e828174 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOPCUAPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java @@ -27,16 +27,16 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.api.messages.PlcWriteRequest; import org.apache.plc4x.java.base.connection.AbstractPlcConnection; import org.apache.plc4x.java.base.messages.*; -import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; +import org.apache.plc4x.java.opcua.protocol.OpcuaPlcFieldHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class BaseOPCUAPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcSubscriber { +public abstract class BaseOpcuaPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcSubscriber { - private static final Logger logger = LoggerFactory.getLogger(BaseOPCUAPlcConnection.class); + private static final Logger logger = LoggerFactory.getLogger(BaseOpcuaPlcConnection.class); - BaseOPCUAPlcConnection(String params) { + BaseOpcuaPlcConnection(String params) { if (!StringUtils.isEmpty(params)) { for (String param : params.split("&")) { diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java similarity index 83% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java index a49669cf12d..84046ad2916 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUAConnectionFactory.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java @@ -23,15 +23,15 @@ Licensed to the Apache Software Foundation (ASF) under one import java.net.InetAddress; import java.util.Objects; -public class OPCUAConnectionFactory { +public class OpcuaConnectionFactory { - public OPCUATcpPlcConnection opcuaTcpPlcConnectionOf(InetAddress address, Integer port, String params, int requestTimeout) { + public OpcuaTcpPlcConnection opcuaTcpPlcConnectionOf(InetAddress address, Integer port, String params, int requestTimeout) { Objects.requireNonNull(address); if (port == null) { - return OPCUATcpPlcConnection.of(address, params, requestTimeout); + return OpcuaTcpPlcConnection.of(address, params, requestTimeout); } else { - return OPCUATcpPlcConnection.of(address, port, params, requestTimeout); + return OpcuaTcpPlcConnection.of(address, port, params, requestTimeout); } } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java similarity index 96% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java index afd89b59681..b7de4b60268 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OPCUATcpPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java @@ -32,7 +32,7 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.base.messages.items.*; import org.apache.plc4x.java.base.model.SubscriptionPlcField; import org.apache.plc4x.java.opcua.protocol.OpcuaField; -import org.apache.plc4x.java.opcua.protocol.model.OpcuaSubsriptionHandle; +import org.apache.plc4x.java.opcua.protocol.OpcuaSubsriptionHandle; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider; @@ -70,11 +70,11 @@ Licensed to the Apache Software Foundation (ASF) under one import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; -public class OPCUATcpPlcConnection extends BaseOPCUAPlcConnection { +public class OpcuaTcpPlcConnection extends BaseOpcuaPlcConnection { private static final int OPCUA_DEFAULT_TCP_PORT = 4840; - private static final Logger logger = LoggerFactory.getLogger(OPCUATcpPlcConnection.class); + private static final Logger logger = LoggerFactory.getLogger(OpcuaTcpPlcConnection.class); private InetAddress address; private int requestTimeout = 5000; private int port; @@ -82,29 +82,30 @@ public class OPCUATcpPlcConnection extends BaseOPCUAPlcConnection { private OpcUaClient client; private boolean isConnected = false; private final AtomicLong clientHandles = new AtomicLong(1L); - private OPCUATcpPlcConnection(InetAddress address, String params, int requestTimeout) { + + private OpcuaTcpPlcConnection(InetAddress address, String params, int requestTimeout) { this( address, OPCUA_DEFAULT_TCP_PORT, params, requestTimeout); - logger.info("Configured OPCUATcpPlcConnection with: host-name {}", address.getHostAddress()); + logger.info("Configured OpcuaTcpPlcConnection with: host-name {}", address.getHostAddress()); } - public OPCUATcpPlcConnection(InetAddress address, int port, String params, int requestTimeout) { + public OpcuaTcpPlcConnection(InetAddress address, int port, String params, int requestTimeout) { this(params); - logger.info("Configured OPCUATcpPlcConnection with: host-name {}", address.getHostAddress()); + logger.info("Configured OpcuaTcpPlcConnection with: host-name {}", address.getHostAddress()); this.address = address; this.port = port; this.params = params; } - public OPCUATcpPlcConnection(String params) { + public OpcuaTcpPlcConnection(String params) { super(params); } - public static OPCUATcpPlcConnection of(InetAddress address, String params, int requestTimeout) { - return new OPCUATcpPlcConnection(address, params, requestTimeout); + public static OpcuaTcpPlcConnection of(InetAddress address, String params, int requestTimeout) { + return new OpcuaTcpPlcConnection(address, params, requestTimeout); } - public static OPCUATcpPlcConnection of(InetAddress address, int port, String params, int requestTimeout) { - return new OPCUATcpPlcConnection(address, port, params, requestTimeout); + public static OpcuaTcpPlcConnection of(InetAddress address, int port, String params, int requestTimeout) { + return new OpcuaTcpPlcConnection(address, port, params, requestTimeout); } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java index 0ac3c9f121b..cd33c755716 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java @@ -30,7 +30,7 @@ Licensed to the Apache Software Foundation (ASF) under one public class OpcuaField implements PlcField { - private static final Pattern ADDRESS_PATTERN = Pattern.compile("^ns=(?\\d+);(?[isgb])=((?\\w+))?"); + public static final Pattern ADDRESS_PATTERN = Pattern.compile("^ns=(?\\d+);(?[isgb])=((?\\w+))?"); private final OpcuaIdentifierType identifierType; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java similarity index 98% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java index f265e816ea3..c39a35240f5 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaPlcFieldHandler.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java @@ -18,14 +18,13 @@ Licensed to the Apache Software Foundation (ASF) under one * @author Matthias Milan Stlrljic * Created by Matthias Milan Stlrljic on 10.05.2019 */ -package org.apache.plc4x.java.opcua.protocol.model; +package org.apache.plc4x.java.opcua.protocol; import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; import org.apache.plc4x.java.api.model.PlcField; import org.apache.plc4x.java.base.connection.DefaultPlcFieldHandler; import org.apache.plc4x.java.base.messages.items.*; -import org.apache.plc4x.java.opcua.protocol.OpcuaField; import java.math.BigInteger; import java.util.ArrayList; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java similarity index 94% rename from plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java rename to plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java index 582993cfaf5..08da653de95 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaSubsriptionHandle.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java @@ -18,7 +18,7 @@ Licensed to the Apache Software Foundation (ASF) under one * @author Matthias Milan Stlrljic * Created by Matthias Milan Stlrljic on 10.05.2019 */ -package org.apache.plc4x.java.opcua.protocol.model; +package org.apache.plc4x.java.opcua.protocol; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -28,7 +28,7 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionEvent; import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem; -import org.apache.plc4x.java.opcua.connection.OPCUATcpPlcConnection; +import org.apache.plc4x.java.opcua.connection.OpcuaTcpPlcConnection; import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; @@ -66,7 +66,7 @@ public void onSubscriptionValue(UaMonitoredItem item, DataValue value) { if(value.getStatusCode() != StatusCode.GOOD){ resultCode = PlcResponseCode.NOT_FOUND; }else{ - stringItem = OPCUATcpPlcConnection.encodeFieldItem(value); + stringItem = OpcuaTcpPlcConnection.encodeFieldItem(value); } Map> fields = new HashMap<>(); diff --git a/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver b/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver index 860acdcd5af..fe96e3ab7cc 100644 --- a/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver +++ b/plc4j/drivers/opcua/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver @@ -16,4 +16,4 @@ # specific language governing permissions and limitations # under the License. # -org.apache.plc4x.java.opcua.OPCUAPlcDriver +org.apache.plc4x.java.opcua.OpcuaPlcDriver diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java similarity index 94% rename from plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java rename to plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java index f6eb6d5688d..8d12925c7dc 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/ManualPLC4XOPCUA.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java @@ -18,7 +18,7 @@ Licensed to the Apache Software Foundation (ASF) under one * @author Matthias Milan Stlrljic * Created by Matthias Milan Stlrljic on 10.05.2019 */ -package org.apache.plc4x.java.opcua.connection; +package org.apache.plc4x.java.opcua; import org.apache.plc4x.java.PlcDriverManager; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; @@ -28,8 +28,9 @@ Licensed to the Apache Software Foundation (ASF) under one import org.apache.plc4x.java.api.types.PlcSubscriptionType; import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionRequest; import org.apache.plc4x.java.base.model.SubscriptionPlcField; +import org.apache.plc4x.java.opcua.connection.OpcuaTcpPlcConnection; import org.apache.plc4x.java.opcua.protocol.OpcuaField; -import org.apache.plc4x.java.opcua.protocol.model.OpcuaPlcFieldHandler; +import org.apache.plc4x.java.opcua.protocol.OpcuaPlcFieldHandler; import java.math.BigInteger; import java.time.Duration; @@ -39,17 +40,15 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.LinkedHashMap; import java.util.function.Consumer; -public class ManualPLC4XOPCUA { +public class ManualPLC4XOpcua { public static void main(String args[]){ - - - OPCUATcpPlcConnection opcuaConnection = null; + OpcuaTcpPlcConnection opcuaConnection = null; OpcuaPlcFieldHandler fieldH = new OpcuaPlcFieldHandler(); PlcField field = fieldH.createField("ns=2;i=10855"); try { - opcuaConnection = (OPCUATcpPlcConnection) + opcuaConnection = (OpcuaTcpPlcConnection) new PlcDriverManager().getConnection("opcua:tcp://opcua.demo-this.com:51210/UA/SampleServer"); } catch (PlcConnectionException e) { @@ -82,7 +81,6 @@ public static void main(String args[]){ PlcWriteRequest.Builder wBuilder = opcuaConnection.writeRequestBuilder(); wBuilder.addItem("w-Bool", "ns=2;i=11012", true); - /* wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); wBuilder.addItem("w-Byte", "ns=2;i=10846", (byte)1); wBuilder.addItem("w-Double", "ns=2;i=10854", (double)0.25); @@ -97,7 +95,6 @@ public static void main(String args[]){ wBuilder.addItem("w-UInt32", "ns=2;i=10850", (long)21412); wBuilder.addItem("w-UInt64", "ns=2;i=10852", new BigInteger("1245152")); wBuilder.addItem("w-UInteger", "ns=2;i=10870", new BigInteger("1245152")); -*/ PlcWriteRequest writeRequest = wBuilder.build(); PlcWriteResponse wResponse = opcuaConnection.write(writeRequest).get(); @@ -113,7 +110,7 @@ public static void main(String args[]){ PlcConsumerRegistration registration = opcuaConnection.register(consumer, subResp.getSubscriptionHandles()); Thread.sleep(7000); registration.unregister(); - Thread.sleep(200000); + Thread.sleep(20000); opcuaConnection.close(); } catch (Exception e) { e.printStackTrace(); diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java new file mode 100644 index 00000000000..0e0dd01e2ae --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java @@ -0,0 +1,66 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +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.opcua.UtilsTest.assertMatching; + +public class OpcuaPlcDriverTest { + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + + } + + @Test + public void testOpcuaAddressPattern() { + + assertMatching(INET_ADDRESS_PATTERN, "tcp://localhost"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://localhost:3131"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://www.google.de"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://www.google.de:443"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://127.0.0.1"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://127.0.0.1:251"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://254.254.254.254:1337"); + assertMatching(INET_ADDRESS_PATTERN, "tcp://254.254.254.254"); + + + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://localhost"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://localhost:3131"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://www.google.de"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://www.google.de:443"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://127.0.0.1"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://127.0.0.1:251"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://254.254.254.254:1337"); + assertMatching(OPCUA_URI_PATTERN, "opcua:tcp://254.254.254.254"); + + + } + +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java new file mode 100644 index 00000000000..bb1851afcca --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java @@ -0,0 +1,39 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua; + +import java.util.regex.Pattern; + +import static org.junit.Assert.fail; + +public class UtilsTest { + public static void assertMatching(Pattern pattern, String match) { + if (!pattern.matcher(match).matches()) { + fail(pattern + "doesn't match " + match); + } + } + + public static void assertNoMatching(Pattern pattern, String match) { + if (pattern.matcher(match).matches()) { + fail(pattern + "does match " + match + " but should not"); + } + } +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java new file mode 100644 index 00000000000..0e31f613ebf --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java @@ -0,0 +1,35 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua.connection; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +public class OpcuaTcpPlcConnectionTest { + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + + } +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java new file mode 100644 index 00000000000..f838b45aaed --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java @@ -0,0 +1,50 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua.protocol; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.apache.plc4x.java.opcua.UtilsTest.assertMatching; +import static org.apache.plc4x.java.opcua.protocol.OpcuaField.ADDRESS_PATTERN; + +public class OpcuaFieldTest { + + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + + } + + @Test + public void testOpcuaAddressPattern() { + + assertMatching(ADDRESS_PATTERN, "ns=2;i=10846"); + assertMatching(ADDRESS_PATTERN, "ns=2;s=test.variable.name.inspect"); + assertMatching(ADDRESS_PATTERN, "ns=2;g=09087e75-8e5e-499b-954f-f2a8624db28a"); + assertMatching(ADDRESS_PATTERN, "ns=2;b=asvaewavarahreb=="); + + } +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java new file mode 100644 index 00000000000..315358230f8 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java @@ -0,0 +1,35 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua.protocol; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +public class OpcuaPlcFieldHandlerTest { + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + + } +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java new file mode 100644 index 00000000000..bc75d14ef76 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java @@ -0,0 +1,35 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ +package org.apache.plc4x.java.opcua.protocol; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +public class OpcuaSubscriptionHandleTest { + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + + } +} From c1cc0e2b7a028179c1d6073532f06ad07e6b6714 Mon Sep 17 00:00:00 2001 From: Matthias Strljic Date: Tue, 14 May 2019 14:33:58 +0200 Subject: [PATCH 7/8] [Fixed] JavaDoc formatting [Added] Warning messages at exception points with the consideration of adding later some run-time exceptions --- .../plc4x/java/opcua/OpcuaPlcDriver.java | 9 +- .../connection/BaseOpcuaPlcConnection.java | 9 +- .../connection/OpcuaConnectionFactory.java | 9 +- .../connection/OpcuaTcpPlcConnection.java | 175 +++++++++--------- .../plc4x/java/opcua/protocol/OpcuaField.java | 14 +- .../opcua/protocol/OpcuaPlcFieldHandler.java | 9 +- .../protocol/OpcuaSubsriptionHandle.java | 9 +- .../opcua/protocol/model/OpcuaDataTypes.java | 39 ++-- .../protocol/model/OpcuaIdentifierType.java | 33 +++- .../plc4x/java/opcua/ManualPLC4XOpcua.java | 92 +++++---- .../plc4x/java/opcua/OpcuaPlcDriverTest.java | 9 +- .../apache/plc4x/java/opcua/UtilsTest.java | 9 +- .../connection/OpcuaTcpPlcConnectionTest.java | 9 +- .../java/opcua/protocol/OpcuaFieldTest.java | 9 +- .../protocol/OpcuaPlcFieldHandlerTest.java | 9 +- .../protocol/OpcuaSubscriptionHandleTest.java | 9 +- 16 files changed, 250 insertions(+), 202 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 ef5f9858b78..7fefae7c45a 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 @@ -15,10 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua; import org.apache.commons.lang3.StringUtils; @@ -33,9 +30,13 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.regex.Matcher; import java.util.regex.Pattern; + /** * Implementation of the OPC UA protocol, based on: * - Eclipse Milo (https://github.com/eclipse/milo) + * + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 */ public class OpcuaPlcDriver implements PlcDriver { diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java index 0585e828174..50a5bd0633c 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/BaseOpcuaPlcConnection.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.connection; import org.apache.commons.lang3.StringUtils; @@ -31,7 +29,10 @@ Licensed to the Apache Software Foundation (ASF) under one import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public abstract class BaseOpcuaPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcSubscriber { private static final Logger logger = LoggerFactory.getLogger(BaseOpcuaPlcConnection.class); diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java index 84046ad2916..5c399f30843 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaConnectionFactory.java @@ -15,14 +15,15 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.connection; import java.net.InetAddress; import java.util.Objects; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaConnectionFactory { public OpcuaTcpPlcConnection opcuaTcpPlcConnectionOf(InetAddress address, Integer port, String params, int requestTimeout) { diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java index b7de4b60268..c59c36a35ea 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java @@ -94,6 +94,7 @@ public OpcuaTcpPlcConnection(InetAddress address, int port, String params, int r this.address = address; this.port = port; this.params = params; + this.requestTimeout = requestTimeout; } public OpcuaTcpPlcConnection(String params) { @@ -108,7 +109,51 @@ public static OpcuaTcpPlcConnection of(InetAddress address, int port, String par return new OpcuaTcpPlcConnection(address, port, params, requestTimeout); } + public static BaseDefaultFieldItem encodeFieldItem(DataValue value){ + NodeId typeNode = value.getValue().getDataType().get(); + Object objValue = value.getValue().getValue(); + + if(typeNode.equals(Identifiers.Boolean)){ + return new DefaultBooleanFieldItem((Boolean)objValue); + }else if (typeNode.equals(Identifiers.ByteString)){ + byte[] array = ((ByteString)objValue).bytes(); + Byte[] byteArry = new Byte[array.length]; + int counter = 0; + for (byte bytie: array + ) { + byteArry[counter] = bytie; + counter++; + } + return new DefaultByteArrayFieldItem(byteArry); + }else if (typeNode.equals(Identifiers.Integer)){ + return new DefaultIntegerFieldItem((Integer)objValue); + }else if (typeNode.equals(Identifiers.Int16)){ + return new DefaultShortFieldItem((Short)objValue); + }else if (typeNode.equals(Identifiers.Int32)){ + return new DefaultIntegerFieldItem((Integer)objValue); + }else if (typeNode.equals(Identifiers.Int64)){ + return new DefaultLongFieldItem((Long)objValue); + }else if (typeNode.equals(Identifiers.UInteger)){ + return new DefaultLongFieldItem((Long)objValue); + }else if (typeNode.equals(Identifiers.UInt16)){ + return new DefaultIntegerFieldItem(((UShort)objValue).intValue()); + }else if (typeNode.equals(Identifiers.UInt32)){ + return new DefaultLongFieldItem(((UInteger)objValue).longValue()); + }else if (typeNode.equals(Identifiers.UInt64)){ + return new DefaultBigIntegerFieldItem(new BigInteger(objValue.toString())); + }else if (typeNode.equals(Identifiers.Byte)){ + return new DefaultShortFieldItem(Short.valueOf(objValue.toString())); + }else if (typeNode.equals(Identifiers.Float)){ + return new DefaultFloatFieldItem((Float)objValue); + }else if (typeNode.equals(Identifiers.Double)){ + return new DefaultDoubleFieldItem((Double)objValue); + }else if (typeNode.equals(Identifiers.SByte)){ + return new DefaultByteFieldItem((Byte)objValue); + }else { + return new DefaultStringFieldItem(objValue.toString()); + } + } public InetAddress getRemoteAddress() { return address; @@ -120,6 +165,7 @@ public void connect() throws PlcConnectionException { try { endpoints = DiscoveryClient.getEndpoints(getEndpointUrl(address, port, params)).get(); + //TODO Exception should be handeled better when the Discovery-API of Milo is stable } catch (Exception ex) { // try the explicit discovery endpoint as well String discoveryUrl = getEndpointUrl(address, port, params); @@ -144,7 +190,7 @@ public void connect() throws PlcConnectionException { .orElseThrow(() -> new PlcConnectionException("No desired endpoints from")); OpcUaClientConfig config = OpcUaClientConfig.builder() - .setApplicationName(LocalizedText.english("eclipse milo opc-ua client")) + .setApplicationName(LocalizedText.english("eclipse milo opc-ua client of the apache PLC4X:PLC4J project")) .setApplicationUri("urn:eclipse:milo:plc4x:client") .setEndpoint(endpoint) .setIdentityProvider(getIdentityProvider()) @@ -155,9 +201,13 @@ public void connect() throws PlcConnectionException { this.client = OpcUaClient.create(config); this.client.connect().get(); isConnected = true; - } catch (UaException | InterruptedException | ExecutionException e) { + } catch (UaException e) { isConnected = false; - + String message = (config == null) ? "NULL" : config.toString(); + throw new PlcConnectionException("The given input values are a not valid OPC UA connection configuration [CONFIG]: " + message); + } catch (InterruptedException | ExecutionException e) { + isConnected = false; + throw new PlcConnectionException("Error while creation of the connection because of : " + e.getMessage()); } } @@ -232,18 +282,15 @@ public CompletableFuture subscribe(PlcSubscriptionReque subHandle = subsriptionHandle; responseCode = PlcResponseCode.OK; - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); + } catch (InterruptedException | ExecutionException e) { + logger.warn("Unable to subscribe Elements because of: {}", e.getMessage()); } return Pair.of(plcFieldName, Pair.of(responseCode, subHandle)); }) .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); - PlcSubscriptionResponse result = new DefaultPlcSubscriptionResponse(internalPlcSubscriptionRequest, responseItems); - return result; + return (PlcSubscriptionResponse) new DefaultPlcSubscriptionResponse(internalPlcSubscriptionRequest, responseItems); }); return future; @@ -256,10 +303,8 @@ public CompletableFuture unsubscribe(PlcUnsubscriptio OpcuaSubsriptionHandle opcSubHandle = (OpcuaSubsriptionHandle) o; try { client.getSubscriptionManager().deleteSubscription(opcSubHandle.getClientHandle()).get(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); + } catch (InterruptedException | ExecutionException e) { + logger.warn("Unable to unsubscribe Elements because of: {}", e.getMessage()); } }); @@ -295,17 +340,13 @@ public CompletableFuture read(PlcReadRequest readRequest) { List readValues = null; try { readValues = dataValueCompletableFuture.get(); - } catch (InterruptedException e) { - e.printStackTrace(); - readValues = new LinkedList<>(); - } catch (ExecutionException e) { - e.printStackTrace(); - readValues = new LinkedList<>(); + } catch (InterruptedException | ExecutionException e) { + logger.warn("Unable to read Elements because of: {}", e.getMessage()); } - for(int counter = 0; counter < readValues.size(); counter++){ + for(int counter = 0; counter < readValueIds.size(); counter++){ PlcResponseCode resultCode = PlcResponseCode.OK; BaseDefaultFieldItem stringItem = null; - if(readValues.get(counter).getStatusCode() != StatusCode.GOOD){ + if(readValues == null || readValues.size() <= counter || readValues.get(counter).getStatusCode() != StatusCode.GOOD){ resultCode = PlcResponseCode.NOT_FOUND; }else{ stringItem = encodeFieldItem(readValues.get(counter)); @@ -317,81 +358,13 @@ public CompletableFuture read(PlcReadRequest readRequest) { } InternalPlcReadRequest internalPlcReadRequest = checkInternal(readRequest, InternalPlcReadRequest.class); - PlcReadResponse response = new DefaultPlcReadResponse(internalPlcReadRequest, fields ); - return response; + return (PlcReadResponse) new DefaultPlcReadResponse(internalPlcReadRequest, fields ); }); return future; } - private NodeId generateNodeId(OpcuaField uaField){ - NodeId idNode = null; - switch (uaField.getIdentifierType()) { - case s: - idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); - break; - case i: - idNode = new NodeId(uaField.getNamespace(), UInteger.valueOf(uaField.getIdentifier())); - break; - case g: - idNode = new NodeId(uaField.getNamespace(), UUID.fromString(uaField.getIdentifier())); - break; - case b: - idNode = new NodeId(uaField.getNamespace(), new ByteString(uaField.getIdentifier().getBytes())); - break; - - default: idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); - } - - return idNode; - } - - public static BaseDefaultFieldItem encodeFieldItem(DataValue value){ - NodeId typeNode = value.getValue().getDataType().get(); - Object objValue = value.getValue().getValue(); - - if(typeNode.equals(Identifiers.Boolean)){ - return new DefaultBooleanFieldItem((Boolean)objValue); - }else if (typeNode.equals(Identifiers.ByteString)){ - byte[] array = ((ByteString)objValue).bytes(); - Byte[] byteArry = new Byte[array.length]; - int counter = 0; - for (byte bytie: array - ) { - byteArry[counter] = bytie; - counter++; - } - return new DefaultByteArrayFieldItem(byteArry); - }else if (typeNode.equals(Identifiers.Integer)){ - return new DefaultIntegerFieldItem((Integer)objValue); - }else if (typeNode.equals(Identifiers.Int16)){ - return new DefaultShortFieldItem((Short)objValue); - }else if (typeNode.equals(Identifiers.Int32)){ - return new DefaultIntegerFieldItem((Integer)objValue); - }else if (typeNode.equals(Identifiers.Int64)){ - return new DefaultLongFieldItem((Long)objValue); - }else if (typeNode.equals(Identifiers.UInteger)){ - return new DefaultLongFieldItem((Long)objValue); - }else if (typeNode.equals(Identifiers.UInt16)){ - return new DefaultIntegerFieldItem(((UShort)objValue).intValue()); - }else if (typeNode.equals(Identifiers.UInt32)){ - return new DefaultLongFieldItem(((UInteger)objValue).longValue()); - }else if (typeNode.equals(Identifiers.UInt64)){ - return new DefaultBigIntegerFieldItem(new BigInteger(objValue.toString())); - }else if (typeNode.equals(Identifiers.Byte)){ - return new DefaultShortFieldItem(Short.valueOf(objValue.toString())); - }else if (typeNode.equals(Identifiers.Float)){ - return new DefaultFloatFieldItem((Float)objValue); - }else if (typeNode.equals(Identifiers.Double)){ - return new DefaultDoubleFieldItem((Double)objValue); - }else if (typeNode.equals(Identifiers.SByte)){ - return new DefaultByteFieldItem((Byte)objValue); - }else { - return new DefaultStringFieldItem(objValue.toString()); - } - - } @Override public CompletableFuture write(PlcWriteRequest writeRequest) { @@ -451,6 +424,28 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { } + private NodeId generateNodeId(OpcuaField uaField){ + NodeId idNode = null; + switch (uaField.getIdentifierType()) { + case STRING_IDENTIFIER: + idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); + break; + case NUMBER_IDENTIFIER: + idNode = new NodeId(uaField.getNamespace(), UInteger.valueOf(uaField.getIdentifier())); + break; + case GUID_IDENTIFIER: + idNode = new NodeId(uaField.getNamespace(), UUID.fromString(uaField.getIdentifier())); + break; + case BINARY_IDENTIFIER: + idNode = new NodeId(uaField.getNamespace(), new ByteString(uaField.getIdentifier().getBytes())); + break; + + default: idNode = new NodeId(uaField.getNamespace(), uaField.getIdentifier()); + } + + return idNode; + } + private String getEndpointUrl(InetAddress address, Integer port, String params) { return "opc.tcp://" + address.getHostAddress() +":" + port + "/" + params; } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java index cd33c755716..91ece25e682 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaField.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException; @@ -27,7 +25,10 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaField implements PlcField { public static final Pattern ADDRESS_PATTERN = Pattern.compile("^ns=(?\\d+);(?[isgb])=((?\\w+))?"); @@ -64,7 +65,7 @@ public static OpcuaField of(String address) { String identifier = matcher.group("identifier"); String identifierTypeString = matcher.group("identifierType"); - OpcuaIdentifierType identifierType = OpcuaIdentifierType.valueOf(identifierTypeString); + OpcuaIdentifierType identifierType = OpcuaIdentifierType.fromString(identifierTypeString); String namespaceString = matcher.group("namespace"); Integer namespace = namespaceString != null ? Integer.valueOf(namespaceString) : 0; @@ -98,7 +99,7 @@ public boolean equals(Object o) { return false; } OpcuaField that = (OpcuaField) o; - return namespace == that.namespace && identifier.equals(that.identifier); + return namespace == that.namespace && identifier.equals(that.identifier) && identifierType == that.identifierType; } @Override @@ -110,6 +111,7 @@ public int hashCode() { public String toString() { return "OpcuaField{" + "namespace=" + namespace + + "identifierType=" + identifierType.getText() + "identifier=" + identifier + '}'; } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java index c39a35240f5..bb44a8e9a75 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandler.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; @@ -28,7 +26,10 @@ Licensed to the Apache Software Foundation (ASF) under one import java.math.BigInteger; import java.util.ArrayList; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaPlcFieldHandler extends DefaultPlcFieldHandler { @Override diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java index 08da653de95..8080d2209c5 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubsriptionHandle.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -40,7 +38,10 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.Map; import java.util.Set; import java.util.function.Consumer; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaSubsriptionHandle implements PlcSubscriptionHandle { Set< Consumer> consumers = new HashSet<>(); String fieldName; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java index c0bfe6522dd..af951375b6e 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaDataTypes.java @@ -15,31 +15,32 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +*/ +package org.apache.plc4x.java.opcua.protocol.model; +/** * @author Matthias Milan Stlrljic * Created by Matthias Milan Stlrljic on 10.05.2019 */ -package org.apache.plc4x.java.opcua.protocol.model; - public enum OpcuaDataTypes { BOOL, SByte, Byte, - Int16, - UInt16, - Int32, - UInt32, - Int64, - Uint64, - Float, - Double, - StatusCode, - String, - DateTime, - Guid, - ByteString, - XMLElement, - NodeId, - ExpandedNodeId, - QualifiedName + INT16, + UINT16, + INT32, + UINT32, + INT64, + UINT64, + FLOAT, + DOUBLE, + STATUS_CODE, + STRING, + DATE_TIME, + GUID, + BYTE_STRING, + XML_ELEMENT, + NODE_ID, + EXPANDABLE_NODE_ID, + QUALIFIED_NAME } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java index 599ad059f66..3122deb11b7 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/model/OpcuaIdentifierType.java @@ -15,14 +15,35 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 */ package org.apache.plc4x.java.opcua.protocol.model; +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public enum OpcuaIdentifierType { - s, - i, - g, - b + STRING_IDENTIFIER("s"), + NUMBER_IDENTIFIER("i"), + GUID_IDENTIFIER("g"), + BINARY_IDENTIFIER("BINARY_IDENTIFIER"); + + private String text; + + OpcuaIdentifierType(String text) { + this.text = text; + } + + public String getText() { + return this.text; + } + + public static OpcuaIdentifierType fromString(String text) { + for (OpcuaIdentifierType type : OpcuaIdentifierType.values()) { + if (type.text.equalsIgnoreCase(text)) { + return type; + } + } + throw new IllegalArgumentException("No constant with text " + text + " found"); + } } diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java index 8d12925c7dc..57d1f798a75 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua; import org.apache.plc4x.java.PlcDriverManager; @@ -39,8 +37,29 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.Collections; import java.util.LinkedHashMap; import java.util.function.Consumer; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class ManualPLC4XOpcua { + private static final String BOOL_IDENTIFIER = "ns=2;i=10844"; + private static final String BYTE_STRING_IDENTIFIER = "ns=2;i=10858"; + private static final String BYTE_IDENTIFIER = "ns=2;i=10846"; + private static final String DOUBLE_IDENTIFIER = "ns=2;i=10854"; + private static final String FLOAT_IDENTIFIER = "ns=2;i=10853"; + private static final String INT16_IDENTIFIER = "ns=2;i=10847"; + private static final String INT32_IDENTIFIER = "ns=2;i=10849"; + private static final String INT64_IDENTIFIER = "ns=2;i=10851"; + private static final String INTEGER_IDENTIFIER = "ns=2;i=10869"; + private static final String SBYTE_IDENTIFIER = "ns=2;i=10845"; + private static final String STRING_IDENTIFIER = "ns=2;i=10855"; + private static final String UINT16_IDENTIFIER = "ns=2;i=10848"; + private static final String UINT32_IDENTIFIER = "ns=2;i=10850"; + private static final String UINT64_IDENTIFIER = "ns=2;i=10852"; + private static final String UINTEGER_IDENTIFIER = "ns=2;i=10870"; + private static final String DOES_NOT_EXIST_IDENTIFIER = "ns=2;i=12512623"; + + public static void main(String args[]){ @@ -56,45 +75,44 @@ public static void main(String args[]){ } try { PlcReadRequest.Builder builder = opcuaConnection.readRequestBuilder(); - //builder.addItem("String", "ns=2;i=10855"); - builder.addItem("Bool", "ns=2;i=10844"); - builder.addItem("ByteString", "ns=2;i=10858"); - builder.addItem("Byte", "ns=2;i=10846"); - builder.addItem("Double", "ns=2;i=10854"); - builder.addItem("Float", "ns=2;i=10853"); - builder.addItem("Int16", "ns=2;i=10847"); - builder.addItem("Int32", "ns=2;i=10849"); - builder.addItem("Int64", "ns=2;i=10851"); - builder.addItem("Integer", "ns=2;i=10869"); - builder.addItem("SByte", "ns=2;i=10845"); - builder.addItem("String", "ns=2;i=10855"); - builder.addItem("UInt16", "ns=2;i=10848"); - builder.addItem("UInt32", "ns=2;i=10850"); - builder.addItem("UInt64", "ns=2;i=10852"); - builder.addItem("UInteger", "ns=2;i=10870"); + builder.addItem("Bool", BOOL_IDENTIFIER); + builder.addItem("ByteString", BYTE_STRING_IDENTIFIER); + builder.addItem("Byte", BYTE_IDENTIFIER); + builder.addItem("Double", DOUBLE_IDENTIFIER); + builder.addItem("Float", FLOAT_IDENTIFIER); + builder.addItem("Int16", INT16_IDENTIFIER); + builder.addItem("Int32", INT32_IDENTIFIER); + builder.addItem("Int64", INT64_IDENTIFIER); + builder.addItem("Integer", INTEGER_IDENTIFIER); + builder.addItem("SByte", SBYTE_IDENTIFIER); + builder.addItem("String", STRING_IDENTIFIER); + builder.addItem("UInt16", UINT16_IDENTIFIER); + builder.addItem("UInt32", UINT32_IDENTIFIER); + builder.addItem("UInt64", UINT64_IDENTIFIER); + builder.addItem("UInteger", UINTEGER_IDENTIFIER); - builder.addItem("DoesNotExists", "ns=2;i=12512623"); + builder.addItem("DoesNotExists", DOES_NOT_EXIST_IDENTIFIER); PlcReadRequest request = builder.build(); PlcReadResponse response = opcuaConnection.read(request).get(); Collection coll = response.getAllStrings("String"); PlcWriteRequest.Builder wBuilder = opcuaConnection.writeRequestBuilder(); - wBuilder.addItem("w-Bool", "ns=2;i=11012", true); - wBuilder.addItem("w-ByteString", "ns=2;i=10858", "TEST".getBytes()); - wBuilder.addItem("w-Byte", "ns=2;i=10846", (byte)1); - wBuilder.addItem("w-Double", "ns=2;i=10854", (double)0.25); - wBuilder.addItem("w-Float", "ns=2;i=10853", (float)0.25); - wBuilder.addItem("w-Int16", "ns=2;i=10847", (short)12); - wBuilder.addItem("w-Int32", "ns=2;i=10849", (int)314); - wBuilder.addItem("w-Int64", "ns=2;i=10851", (long)123125); - wBuilder.addItem("w-Integer", "ns=2;i=10869", (int)314); - wBuilder.addItem("w-SByte", "ns=2;i=10845", (short)23); - wBuilder.addItem("w-String", "ns=2;i=10855", "TEST"); - wBuilder.addItem("w-UInt16", "ns=2;i=10848", (int)222); - wBuilder.addItem("w-UInt32", "ns=2;i=10850", (long)21412); - wBuilder.addItem("w-UInt64", "ns=2;i=10852", new BigInteger("1245152")); - wBuilder.addItem("w-UInteger", "ns=2;i=10870", new BigInteger("1245152")); + wBuilder.addItem("w-Bool", BOOL_IDENTIFIER, true); + wBuilder.addItem("w-ByteString", BYTE_STRING_IDENTIFIER, "TEST".getBytes()); + wBuilder.addItem("w-Byte", BYTE_IDENTIFIER, (byte)1); + wBuilder.addItem("w-Double", DOUBLE_IDENTIFIER, (double)0.25); + wBuilder.addItem("w-Float", FLOAT_IDENTIFIER, (float)0.25); + wBuilder.addItem("w-INT16", INT16_IDENTIFIER, (short)12); + wBuilder.addItem("w-Int32", INT32_IDENTIFIER, (int)314); + wBuilder.addItem("w-Int64", INT64_IDENTIFIER, (long)123125); + wBuilder.addItem("w-Integer", INTEGER_IDENTIFIER, (int)314); + wBuilder.addItem("w-SByte", SBYTE_IDENTIFIER, (short)23); + wBuilder.addItem("w-String", STRING_IDENTIFIER, "TEST"); + wBuilder.addItem("w-UInt16", UINT16_IDENTIFIER, (int)222); + wBuilder.addItem("w-UInt32", UINT32_IDENTIFIER, (long)21412); + wBuilder.addItem("w-UInt64", UINT64_IDENTIFIER, new BigInteger("1245152")); + wBuilder.addItem("w-UInteger", UINTEGER_IDENTIFIER, new BigInteger("1245152")); PlcWriteRequest writeRequest = wBuilder.build(); PlcWriteResponse wResponse = opcuaConnection.write(writeRequest).get(); @@ -102,7 +120,7 @@ public static void main(String args[]){ opcuaConnection, new LinkedHashMap<>( Collections.singletonMap("field1", - new SubscriptionPlcField(PlcSubscriptionType.CHANGE_OF_STATE, OpcuaField.of("ns=2;i=10855"), Duration.of(1, ChronoUnit.SECONDS))) + new SubscriptionPlcField(PlcSubscriptionType.CHANGE_OF_STATE, OpcuaField.of(STRING_IDENTIFIER), Duration.of(1, ChronoUnit.SECONDS))) ) )).get(); diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java index 0e0dd01e2ae..8c502ed2fed 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua; import org.junit.jupiter.api.AfterEach; @@ -27,7 +25,10 @@ Licensed to the Apache Software Foundation (ASF) under one 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.opcua.UtilsTest.assertMatching; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaPlcDriverTest { @BeforeEach public void before() { diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java index bb1851afcca..2e84a0b63a6 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/UtilsTest.java @@ -15,15 +15,16 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua; import java.util.regex.Pattern; import static org.junit.Assert.fail; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class UtilsTest { public static void assertMatching(Pattern pattern, String match) { if (!pattern.matcher(match).matches()) { diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java index 0e31f613ebf..5a42c5e28ae 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnectionTest.java @@ -15,14 +15,15 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.connection; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaTcpPlcConnectionTest { @BeforeEach public void before() { diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java index f838b45aaed..828a0e6ac80 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaFieldTest.java @@ -15,9 +15,7 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; import org.junit.jupiter.api.AfterEach; @@ -26,7 +24,10 @@ Licensed to the Apache Software Foundation (ASF) under one import static org.apache.plc4x.java.opcua.UtilsTest.assertMatching; import static org.apache.plc4x.java.opcua.protocol.OpcuaField.ADDRESS_PATTERN; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaFieldTest { @BeforeEach diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java index 315358230f8..044de340e3f 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaPlcFieldHandlerTest.java @@ -15,14 +15,15 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaPlcFieldHandlerTest { @BeforeEach public void before() { diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java index bc75d14ef76..153d4ca85dc 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandleTest.java @@ -15,14 +15,15 @@ Licensed to the Apache Software Foundation (ASF) under one KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * @author Matthias Milan Stlrljic - * Created by Matthias Milan Stlrljic on 10.05.2019 - */ +*/ package org.apache.plc4x.java.opcua.protocol; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; - +/** + * @author Matthias Milan Stlrljic + * Created by Matthias Milan Stlrljic on 10.05.2019 + */ public class OpcuaSubscriptionHandleTest { @BeforeEach public void before() { From deb48b6c44c0c699dbc4af6ac1706e492959581b Mon Sep 17 00:00:00 2001 From: Matthias Strljic Date: Tue, 14 May 2019 14:41:03 +0200 Subject: [PATCH 8/8] [Added] descriptive class comments to ManualPLC4XOpcua --- .../org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java index 57d1f798a75..7708a89e5cd 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualPLC4XOpcua.java @@ -38,6 +38,14 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.LinkedHashMap; import java.util.function.Consumer; /** + * This class serves only as a manual entry point for ad-hoc tests of the OPC UA PLC4J driver. + * + * + * The current version is tested against a public server, which is to be replaced later by a separate instance of the Milo framework. + * Afterwards the code represented here will be used as an example for the introduction page. + * + * TODO: replace current public server with local Milo instance + * * @author Matthias Milan Stlrljic * Created by Matthias Milan Stlrljic on 10.05.2019 */