You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/08/31 08:12:02 UTC
[plc4x] branch develop updated: fix(plc4j/ads): Updated the ADS connect logic to be a bit more asynchronous (At least on an API level)
This is an automated email from the ASF dual-hosted git repository.
cdutz 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 6fb1dea1f fix(plc4j/ads): Updated the ADS connect logic to be a bit more asynchronous (At least on an API level)
6fb1dea1f is described below
commit 6fb1dea1ff8e6776c974794de02a1e640b676be3
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 31 10:11:44 2022 +0200
fix(plc4j/ads): Updated the ADS connect logic to be a bit more asynchronous (At least on an API level)
---
.../java/ads/configuration/AdsConfiguration.java | 13 ++++
.../plc4x/java/ads/protocol/AdsProtocolLogic.java | 82 ++++++++++++++--------
2 files changed, 67 insertions(+), 28 deletions(-)
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
index 5a1134dc2..2d74033c8 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
@@ -26,6 +26,7 @@ import org.apache.plc4x.java.spi.configuration.ConfigurationParameterConverter;
import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter;
import org.apache.plc4x.java.spi.configuration.annotations.ParameterConverter;
import org.apache.plc4x.java.spi.configuration.annotations.Required;
+import org.apache.plc4x.java.spi.configuration.annotations.defaults.BooleanDefaultValue;
import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue;
import org.apache.plc4x.java.transport.serial.SerialTransportConfiguration;
import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration;
@@ -64,6 +65,10 @@ public class AdsConfiguration implements Configuration, TcpTransportConfiguratio
@IntDefaultValue(4000)
protected int timeoutRequest;
+ @ConfigurationParameter("load-symbol-and-data-type-tables")
+ @BooleanDefaultValue(true)
+ protected boolean loadSymbolAndDataTypeTables;
+
public AmsNetId getTargetAmsNetId() {
return targetAmsNetId;
}
@@ -112,6 +117,14 @@ public class AdsConfiguration implements Configuration, TcpTransportConfiguratio
this.timeoutRequest = timeoutRequest;
}
+ public boolean isLoadSymbolAndDataTypeTables() {
+ return loadSymbolAndDataTypeTables;
+ }
+
+ public void setLoadSymbolAndDataTypeTables(boolean loadSymbolAndDataTypeTables) {
+ this.loadSymbolAndDataTypeTables = loadSymbolAndDataTypeTables;
+ }
+
@Override
public int getDefaultPort() {
return AdsConstants.ADSTCPDEFAULTPORT;
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index 4f905e39c..3f2c09a9c 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -104,10 +104,10 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
@Override
public void onConnect(ConversationContext<AmsTCPPacket> context) {
- LOGGER.debug("Fetching sizes of symbol and datatype table sizes.");
final CompletableFuture<Void> future = new CompletableFuture<>();
// If we have connection credentials available, try to set up the AMS routes.
+ CompletableFuture<Void> setupAmsRouteFuture;
if(context.getAuthentication() != null) {
if(!(context.getAuthentication() instanceof PlcUsernamePasswordAuthentication)) {
future.completeExceptionally(new PlcConnectionException(
@@ -117,8 +117,40 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
PlcUsernamePasswordAuthentication usernamePasswordAuthentication =
(PlcUsernamePasswordAuthentication) context.getAuthentication();
- // Prepre the request message.
- org.apache.plc4x.java.ads.discovery.readwrite.AmsNetId sourceAmsNetId = new AmsNetId(
+ setupAmsRouteFuture = setupAmsRoute(usernamePasswordAuthentication);
+ } else {
+ setupAmsRouteFuture = CompletableFuture.completedFuture(null);
+ }
+
+ // If the configuration asks us to load the symbol and data type tables, do so,
+ // otherwise just mark the connection as completed instantly.
+ setupAmsRouteFuture.whenComplete((unused, throwable) -> {
+ if(configuration.isLoadSymbolAndDataTypeTables()) {
+ LOGGER.debug("Fetching sizes of symbol and datatype table sizes.");
+ CompletableFuture<Void> readSymbolTableFuture = readSymbolTableAndDatatypeTable(context);
+ readSymbolTableFuture.whenComplete((unused2, throwable2) -> {
+ if (throwable2 != null) {
+ LOGGER.error("Error fetching symbol and datatype table sizes");
+ } else {
+ context.fireConnected();
+ }
+ });
+ } else {
+ context.fireConnected();
+ }
+ });
+ }
+
+ protected CompletableFuture<Void> setupAmsRoute(PlcUsernamePasswordAuthentication authentication) {
+ CompletableFuture<Void> future = new CompletableFuture<>();
+
+ new Thread(() -> {
+ LOGGER.debug("Setting up remote AMS routes.");
+ SocketAddress localSocketAddress = context.getChannel().localAddress();
+ InetAddress localAddress = ((InetSocketAddress) localSocketAddress).getAddress();
+
+ // Prepare the request message.
+ AmsNetId sourceAmsNetId = new AmsNetId(
configuration.getSourceAmsNetId().getOctet1(), configuration.getSourceAmsNetId().getOctet2(),
configuration.getSourceAmsNetId().getOctet3(), configuration.getSourceAmsNetId().getOctet4(),
configuration.getSourceAmsNetId().getOctet5(), configuration.getSourceAmsNetId().getOctet6());
@@ -129,9 +161,9 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
sourceAmsNetId, AdsPortNumbers.SYSTEM_SERVICE,
Arrays.asList(new AdsDiscoveryBlockRouteName(new AmsString(routeName)),
new AdsDiscoveryBlockAmsNetId(sourceAmsNetId),
- new AdsDiscoveryBlockUserName(new AmsString(usernamePasswordAuthentication.getUsername())),
- new AdsDiscoveryBlockPassword(new AmsString(usernamePasswordAuthentication.getPassword())),
- new AdsDiscoveryBlockHostName(new AmsString("host-name-or-ip"))));
+ new AdsDiscoveryBlockUserName(new AmsString(authentication.getUsername())),
+ new AdsDiscoveryBlockPassword(new AmsString(authentication.getPassword())),
+ new AdsDiscoveryBlockHostName(new AmsString(localAddress.getHostAddress()))));
// Send the request to the PLC using a UDP socket.
try (DatagramSocket adsDiscoverySocket = new DatagramSocket(AdsDiscoveryConstants.ADSDISCOVERYUDPDEFAULTPORT)) {
@@ -163,22 +195,28 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
// Check if adding the route was successful
if (addOrUpdateRouteResponse.getRequestId() == 1) {
for (AdsDiscoveryBlock block : addOrUpdateRouteResponse.getBlocks()) {
- if(block.getBlockType() == AdsDiscoveryBlockType.STATUS) {
+ if (block.getBlockType() == AdsDiscoveryBlockType.STATUS) {
AdsDiscoveryBlockStatus statusBlock = (AdsDiscoveryBlockStatus) block;
- if(statusBlock.getStatus() != Status.SUCCESS) {
- future.completeExceptionally(new PlcConnectionException("Error adding AMS route"));
+ if (statusBlock.getStatus() != Status.SUCCESS) {
+ future.completeExceptionally(new PlcException("Error adding AMS route"));
return;
}
}
}
}
+
+ future.complete(null);
} catch (Exception e) {
- e.printStackTrace();
+ future.completeExceptionally(new PlcException("Error adding AMS route", e));
}
- }
+ }).start();
+
+ return future;
+ }
+
+ protected CompletableFuture<Void> readSymbolTableAndDatatypeTable(ConversationContext<AmsTCPPacket> context) {
+ final CompletableFuture<Void> future = new CompletableFuture<>();
- List<AdsDataTypeTableEntry> dataTypes = new ArrayList<>();
- List<AdsSymbolTableEntry> symbols = new ArrayList<>();
// Initialize the request.
AmsPacket amsPacket = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
@@ -220,7 +258,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
for (int i = 0; i < adsTableSizes.getDataTypeCount(); i++) {
try {
AdsDataTypeTableEntry adsDataTypeTableEntry = AdsDataTypeTableEntry.staticParse(rb);
- dataTypes.add(adsDataTypeTableEntry);
+ dataTypeTable.put(adsDataTypeTableEntry.getDataTypeName(), adsDataTypeTableEntry);
} catch (ParseException e) {
throw new RuntimeException(e);
}
@@ -244,7 +282,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
for (int i = 0; i < adsTableSizes.getSymbolCount(); i++) {
try {
AdsSymbolTableEntry adsSymbolTableEntry = AdsSymbolTableEntry.staticParse(rb2);
- symbols.add(adsSymbolTableEntry);
+ symbolTable.put(adsSymbolTableEntry.getName(), adsSymbolTableEntry);
} catch (ParseException e) {
throw new RuntimeException(e);
}
@@ -262,19 +300,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
future.completeExceptionally(new PlcException("Result is " + responseAdsData.getResult()));
}
}));
- future.whenComplete((unused, throwable) -> {
- if(throwable != null) {
- LOGGER.error("Error fetching symbol and datatype table sizes");
- } else {
- for (AdsDataTypeTableEntry dataType : dataTypes) {
- dataTypeTable.put(dataType.getDataTypeName(), dataType);
- }
- for (AdsSymbolTableEntry symbol : symbols) {
- symbolTable.put(symbol.getName(), symbol);
- }
- context.fireConnected();
- }
- });
+ return future;
}
@Override