This is an automated email from the ASF dual-hosted git repository. sruehl pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push: new eced38a06f feat(plc4j/api): Convert the string address into a PlcTag (#1468) eced38a06f is described below commit eced38a06f40acf6f72b986e858bf60483826bce Author: Qing <qtvb...@vip.qq.com> AuthorDate: Tue Apr 23 16:41:29 2024 +0800 feat(plc4j/api): Convert the string address into a PlcTag (#1468) * Priority judgment using discovery parameter When the parameter discovery=false is configured, prefer using the custom address. If the transportEndpoint is empty, directly replace it with the TransportEndpoint returned by the server. * add setter for transportEndpoint * Convert the string address into a PlcTag. * rename string tag address to parseTagAddressSafe * rename parseTagAddressSafe to parseTagAddress * move function parseTagAddress to PlcConnection * add logging for exceptions in PlcTag conversion. * Implement the parseTagAddress method for LeasedPlcConnection. --- .../org/apache/plc4x/java/api/PlcConnection.java | 14 +++++++------ .../plc4x/java/api/messages/PlcReadRequest.java | 2 +- .../readwrite/connection/CtrlXConnection.java | 23 ++++++++++++++++++++-- .../plc4x/java/mock/connection/MockConnection.java | 22 +++++++++++++++++---- .../apache/plc4x/java/opcua/ManualPLC4XOpcua.java | 2 ++ .../java/spi/connection/AbstractPlcConnection.java | 17 ++++++++++++++++ .../java/spi/messages/DefaultPlcReadRequest.java | 4 ++-- .../java/utils/cache/LeasedPlcConnection.java | 10 ++++++++++ 8 files changed, 79 insertions(+), 15 deletions(-) diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java index 116cc25890..560e29c939 100644 --- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java +++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java @@ -23,6 +23,7 @@ import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcTag; +import java.util.Optional; import java.util.concurrent.CompletableFuture; /** @@ -52,14 +53,15 @@ public interface PlcConnection extends AutoCloseable { void close() throws Exception; /** - * Parse a tagAddress for the given connection type. + * Parses a string representation of a tag address into a {@link PlcTag} object. + * <p> + * This method safely attempts to convert the given tag address string into a PlcTag, returning an + * {@link Optional} that is empty if the parsing fails. * - * @throws PlcRuntimeException If the string cannot be parsed + * @param tagAddress The string representation of the tag address to parse. + * @return An optional holding the parsed PLC tag if successful, otherwise an empty optional. */ - @Deprecated - default PlcTag parseTagAddress(String tagAddress) throws PlcInvalidTagException { - throw new PlcRuntimeException("Parse method is not implemented for this connection / driver"); - } + Optional<PlcTag> parseTagAddress(String tagAddress); /** * Provides connection metadata. diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java index b11ec41f9d..476b0e0500 100644 --- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java +++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java @@ -20,6 +20,7 @@ package org.apache.plc4x.java.api.messages; import org.apache.plc4x.java.api.model.PlcTag; +import java.util.Optional; import java.util.concurrent.CompletableFuture; /** @@ -37,7 +38,6 @@ public interface PlcReadRequest extends PlcTagRequest { Builder addTagAddress(String name, String tagAddress); Builder addTag(String name, PlcTag tag); - } } diff --git a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java index 78b9799a15..44324ab09b 100644 --- a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java +++ b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java @@ -28,6 +28,7 @@ import org.apache.plc4x.java.api.exceptions.PlcProtocolException; import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcQuery; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.ApiClient; @@ -41,6 +42,8 @@ import org.apache.plc4x.java.ctrlx.readwrite.tag.CtrlXTag; import org.apache.plc4x.java.ctrlx.readwrite.tag.CtrlXTagHandler; import org.apache.plc4x.java.ctrlx.readwrite.utils.ApiClientFactory; import org.apache.plc4x.java.spi.messages.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -50,6 +53,8 @@ import java.util.stream.Collectors; public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { + private static final Logger logger = LoggerFactory.getLogger(CtrlXConnection.class); + private final String baseUrl; private final String username; private final String password; @@ -60,6 +65,8 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { private NodesApi nodesApi; private DataLayerInformationAndSettingsApi dataLayerApi; + private final CtrlXTagHandler controlXTagHandler = new CtrlXTagHandler(); + public CtrlXConnection(String baseUrl, String username, String password) { this.baseUrl = baseUrl; this.username = username; @@ -69,7 +76,7 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { @Override public void connect() throws PlcConnectionException { - if(apiClient != null) { + if (apiClient != null) { throw new PlcConnectionException("Already connected"); } apiClient = ApiClientFactory.getApiClient(baseUrl, username, password); @@ -90,6 +97,18 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { executorService.shutdown(); } + @Override + public Optional<PlcTag> parseTagAddress(String tagAddress) { + PlcTag plcTag; + try { + plcTag = controlXTagHandler.parseTag(tagAddress); + } catch (Exception e) { + logger.error("Error parsing tag address {}", tagAddress); + return Optional.empty(); + } + return Optional.ofNullable(plcTag); + } + @Override public PlcConnectionMetadata getMetadata() { return new PlcConnectionMetadata() { @@ -122,7 +141,7 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { @Override public PlcBrowseRequest.Builder browseRequestBuilder() { - return new DefaultPlcBrowseRequest.Builder(this, new CtrlXTagHandler()); + return new DefaultPlcBrowseRequest.Builder(this, controlXTagHandler); } @Override diff --git a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java index 12d287591d..0ad98b39e6 100644 --- a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java +++ b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java @@ -25,6 +25,7 @@ import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.mock.tag.MockTagHandler; @@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.function.Function; @@ -58,6 +60,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS return device; } + private final MockTagHandler mockTagHandler = new MockTagHandler(); public void setDevice(MockDevice device) { LOGGER.info("Set Mock Device on Mock Connection {} with device {}", this, device); this.device = device; @@ -111,7 +114,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS @Override public PlcBrowseRequest.Builder browseRequestBuilder() { - return new DefaultPlcBrowseRequest.Builder(this, new MockTagHandler()); + return new DefaultPlcBrowseRequest.Builder(this, mockTagHandler); } @Override @@ -134,7 +137,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS @Override public PlcReadRequest.Builder readRequestBuilder() { - return new DefaultPlcReadRequest.Builder(this, new MockTagHandler()); + return new DefaultPlcReadRequest.Builder(this, mockTagHandler); } @Override @@ -204,12 +207,12 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS @Override public PlcWriteRequest.Builder writeRequestBuilder() { - return new DefaultPlcWriteRequest.Builder(this, new MockTagHandler(), new PlcValueHandler()); + return new DefaultPlcWriteRequest.Builder(this, mockTagHandler, new PlcValueHandler()); } @Override public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() { - return new DefaultPlcSubscriptionRequest.Builder(this, new MockTagHandler()); + return new DefaultPlcSubscriptionRequest.Builder(this, mockTagHandler); } @Override @@ -221,4 +224,15 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS return authentication; } + @Override + public Optional<PlcTag> parseTagAddress(String tagAddress) { + PlcTag plcTag; + try { + plcTag = mockTagHandler.parseTag(tagAddress); + } catch (Exception e) { + LOGGER.error("Error parsing tag address {}", tagAddress); + return Optional.empty(); + } + return Optional.ofNullable(plcTag); + } } 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 8e2297d1fc..2c6882040a 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 @@ -21,6 +21,7 @@ package org.apache.plc4x.java.opcua; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.opcua.protocol.OpcuaSubscriptionHandle; import org.eclipse.milo.examples.server.ExampleServer; @@ -29,6 +30,7 @@ import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; /** * This class serves only as a manual entry point for ad-hoc tests of the OPC UA PLC4J driver. diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java index ec16fdc33a..b9d2545432 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java @@ -26,13 +26,17 @@ import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.generation.Message; import org.apache.plc4x.java.spi.messages.*; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.api.value.PlcValueHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collection; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -44,6 +48,8 @@ import java.util.function.Consumer; */ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnectionMetadata, PlcPinger, PlcReader, PlcWriter, PlcSubscriber, PlcBrowser { + protected static final Logger logger = LoggerFactory.getLogger(AbstractPlcConnection.class); + private boolean canPing = false; private boolean canRead = false; private boolean canWrite = false; @@ -229,4 +235,15 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect return protocol.browseWithInterceptor(browseRequest, interceptor); } + @Override + public Optional<PlcTag> parseTagAddress(String tagAddress) { + PlcTag plcTag; + try { + plcTag = tagHandler.parseTag(tagAddress); + } catch (Exception e) { + logger.error("Error parsing tag address {}", tagAddress); + return Optional.empty(); + } + return Optional.ofNullable(plcTag); + } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java index d5f8e21f1a..3d189926ff 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java @@ -19,9 +19,9 @@ package org.apache.plc4x.java.spi.messages; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; -import org.apache.plc4x.java.api.messages.PlcTagRequest; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; +import org.apache.plc4x.java.api.messages.PlcTagRequest; import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.SerializationException; @@ -33,6 +33,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; @@ -138,7 +139,6 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser tags.forEach((name, tagSupplier) -> parsedTags.put(name, tagSupplier.get())); return new DefaultPlcReadRequest(reader, parsedTags); } - } } diff --git a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java index d400e386d8..866365620e 100644 --- a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java +++ b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java @@ -80,6 +80,16 @@ public class LeasedPlcConnection implements PlcConnection { connectionContainer.returnConnection(this, invalidateConnection); } + @Override + public Optional<PlcTag> parseTagAddress(String tagAddress) { + PlcConnection plcConnection = connection.get(); + if(plcConnection == null) { + throw new PlcRuntimeException("Error using leased connection after returning it to the cache."); + } + return plcConnection.parseTagAddress(tagAddress); + } + + @Override public void connect() throws PlcConnectionException { throw new PlcConnectionException("Error connecting leased connection");