Merge branch 'develop' into release/2.0

This commit is contained in:
Robert von Burg 2023-08-03 10:23:46 +02:00
commit ee1f34001d
Signed by: eitch
GPG Key ID: 75DB9C85C74331F7
12 changed files with 180 additions and 274 deletions

View File

@ -5,7 +5,7 @@
A soft real time PLC written in Strolch running on Strolch
Checkout the documentation at https://strolch.li/plc.html
Checkout the documentation at https://strolch.li/plc/
## Features
Strolch PLC supports the following features:

View File

@ -44,6 +44,12 @@
</Role>
<Role name="StrolchAdmin">
<Privilege name="Inspector" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="Agent" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeAddUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>

View File

@ -5,7 +5,6 @@
<applicationName>Strolch PLC</applicationName>
<Properties>
<locale>en</locale>
<verbose>true</verbose>
<timezone>Europe/Zurich</timezone>
</Properties>
</Runtime>

View File

@ -1,19 +1,5 @@
package li.strolch.plc.core;
import static java.lang.System.nanoTime;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
import static li.strolch.plc.model.PlcConstants.*;
import static li.strolch.utils.helper.ExceptionHelper.getCallerMethod;
import static li.strolch.utils.helper.ExceptionHelper.getExceptionMessageWithCauses;
import static li.strolch.utils.helper.StringHelper.formatNanoDuration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Consumer;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchComponent;
import li.strolch.model.Locator;
@ -35,9 +21,23 @@ import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.utils.collections.MapOfMaps;
import li.strolch.utils.dbc.DBC;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Consumer;
import static java.lang.System.nanoTime;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static li.strolch.model.StrolchModelConstants.BAG_PARAMETERS;
import static li.strolch.plc.model.PlcConstants.*;
import static li.strolch.utils.helper.ExceptionHelper.getCallerMethod;
import static li.strolch.utils.helper.ExceptionHelper.getExceptionMessageWithCauses;
import static li.strolch.utils.helper.StringHelper.formatNanoDuration;
public class DefaultPlcHandler extends StrolchComponent implements PlcHandler, PlcConnectionStateChangeListener {
public static final int SILENT_THRESHOLD = 60;
public static final int SILENT_THRESHOLD = 100;
private static final int MAX_MESSAGE_QUEUE = 200;
private PrivilegeContext ctx;
@ -257,8 +257,8 @@ public class DefaultPlcHandler extends StrolchComponent implements PlcHandler, P
try {
getContainer().getPrivilegeHandler().validateSystemSession(this.ctx);
} catch (Exception e) {
logger.error("PrivilegeContext for session " + this.ctx.getCertificate().getSessionId()
+ " is not valid, reopening.", e);
logger.error("PrivilegeContext for session " + this.ctx.getCertificate().getSessionId() +
" is not valid, reopening.", e);
this.ctx = getContainer().getPrivilegeHandler().openAgentSystemUserContext();
}
}
@ -380,7 +380,7 @@ public class DefaultPlcHandler extends StrolchComponent implements PlcHandler, P
logger.error("Failed to update PlcAddress " + addressId + " with new value " + value, e);
}
if (this.verbose)
if (this.verbose && (nanoTime() - s > MILLISECONDS.toNanos(SILENT_THRESHOLD)))
logger.info("async update " + address.toKey() + " took " + (formatNanoDuration(nanoTime() - s)));
}

View File

@ -1,15 +1,5 @@
package li.strolch.plc.core;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static li.strolch.plc.model.PlcConstants.PARAM_VALUE;
import static li.strolch.plc.model.PlcConstants.TYPE_PLC_ADDRESS;
import static li.strolch.runtime.StrolchConstants.DEFAULT_REALM;
import static li.strolch.utils.helper.ExceptionHelper.getCallerMethod;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.*;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.model.Locator;
import li.strolch.model.Resource;
@ -28,6 +18,18 @@ import li.strolch.runtime.privilege.PrivilegedRunnableWithResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static li.strolch.plc.model.PlcConstants.PARAM_VALUE;
import static li.strolch.plc.model.PlcConstants.TYPE_PLC_ADDRESS;
import static li.strolch.runtime.StrolchConstants.DEFAULT_REALM;
import static li.strolch.utils.helper.ExceptionHelper.getCallerMethod;
/**
* <p>This is an interface to implement short use cases in a plc.</p>
*
@ -51,6 +53,7 @@ public abstract class PlcService implements PlcListener {
protected final PlcHandler plcHandler;
protected final Map<PlcAddress, Future<?>> debounceMap;
protected final List<PlcAddressKey> registeredKeys;
private PlcServiceState state;
@ -59,6 +62,7 @@ public abstract class PlcService implements PlcListener {
this.plcHandler = plcHandler;
this.state = PlcServiceState.Unregistered;
this.debounceMap = new ConcurrentHashMap<>();
this.registeredKeys = new ArrayList<>();
}
public PlcServiceState getState() {
@ -74,8 +78,7 @@ public abstract class PlcService implements PlcListener {
* Called to initialize this service, here one would read the model state of a given address using
* {@link #getAddressState(StrolchTransaction, String, String)}
*
* @param tx
* the transaction giving access to the model
* @param tx the transaction giving access to the model
*/
public void start(StrolchTransaction tx) {
this.state = PlcServiceState.Started;
@ -99,42 +102,44 @@ public abstract class PlcService implements PlcListener {
* Called to unregister this service from previously registered addresses
*/
public void unregister() {
unregisterAll();
this.state = PlcServiceState.Unregistered;
}
/**
* Register this service with the given resource and action
*
* @param resource
* the resource ID
* @param action
* the action
* @param resource the resource ID
* @param action the action
*/
public void register(String resource, String action) {
this.plcHandler.register(resource, action, this);
this.registeredKeys.add(PlcAddressKey.keyFor(resource, action));
}
/**
* Unregister this service with the given resource and action
*
* @param resource
* the resource ID
* @param action
* the action
* @param resource the resource ID
* @param action the action
*/
public void unregister(String resource, String action) {
this.plcHandler.unregister(resource, action, this);
}
/**
* Unregisters this {@link PlcService} from all previously registered addresses
*/
protected void unregisterAll() {
this.registeredKeys.forEach(key -> this.plcHandler.unregister(key.resource, key.action, this));
}
/**
* Returns the {@link Resource} of type #TYPE_PLC_ADDRESS for the given resource and action
*
* @param tx
* the current TX
* @param resource
* the resource
* @param action
* the action
* @param tx the current TX
* @param resource the resource
* @param action the action
*
* @return the {@link Resource}
*/
@ -147,14 +152,10 @@ public abstract class PlcService implements PlcListener {
* Returns the value of a plc address by calling {@link #getPlcAddress(StrolchTransaction, String, String)} for the
* given resource and action
*
* @param tx
* the current TX
* @param resource
* the resource
* @param action
* the action
* @param <T>
* the type of value to return
* @param tx the current TX
* @param resource the resource
* @param action the action
* @param <T> the type of value to return
*
* @return the value of the given address
*/
@ -166,12 +167,9 @@ public abstract class PlcService implements PlcListener {
/**
* Enables an operations log message to be seen by a user
*
* @param addressKey
* the address for which the message is enabled
* @param bundle
* the resource bundle containing the message
* @param severity
* the severity of the message
* @param addressKey the address for which the message is enabled
* @param bundle the resource bundle containing the message
* @param severity the severity of the message
*/
protected void enableMsg(PlcAddressKey addressKey, ResourceBundle bundle, LogSeverity severity) {
sendMsg(logMessageFor(addressKey, bundle, severity, LogMessageState.Active));
@ -180,8 +178,7 @@ public abstract class PlcService implements PlcListener {
/**
* Disables an operations log message which was previously enabled
*
* @param addressKey
* the address for which the message was enabled
* @param addressKey the address for which the message was enabled
*/
protected void disableMsg(PlcAddressKey addressKey) {
disableMsg(Locator.valueOf("Plc", this.plcHandler.getPlcId(), addressKey.resource, addressKey.action));
@ -190,12 +187,9 @@ public abstract class PlcService implements PlcListener {
/**
* Enables an operations log message to be seen by a user
*
* @param i18nKey
* the key of the message in the resource bundle
* @param bundle
* the resource bundle containing the message
* @param severity
* the severity of the message
* @param i18nKey the key of the message in the resource bundle
* @param bundle the resource bundle containing the message
* @param severity the severity of the message
*/
protected void enableMsg(String i18nKey, ResourceBundle bundle, LogSeverity severity) {
sendMsg(logMessageFor(i18nKey, bundle, severity, LogMessageState.Active));
@ -204,10 +198,8 @@ public abstract class PlcService implements PlcListener {
/**
* Disables an operations log message which was previously enabled
*
* @param i18nKey
* the key of the message in the resource bundle for which the message was enabled
* @param bundle
* the resource bundle containing the message
* @param i18nKey the key of the message in the resource bundle for which the message was enabled
* @param bundle the resource bundle containing the message
*/
protected void disableMsg(String i18nKey, ResourceBundle bundle) {
disableMsg(Locator.valueOf("Plc", this.plcHandler.getPlcId(), bundle.getBaseBundleName(), i18nKey));
@ -216,12 +208,9 @@ public abstract class PlcService implements PlcListener {
/**
* Sends a message created for the given properties to a remote listener
*
* @param i18nKey
* the key of the message
* @param bundle
* the bundle containing the key
* @param severity
* the severity of the message
* @param i18nKey the key of the message
* @param bundle the bundle containing the key
* @param severity the severity of the message
*/
protected void sendMsg(String i18nKey, ResourceBundle bundle, LogSeverity severity) {
sendMsg(logMessageFor(i18nKey, bundle, severity));
@ -230,12 +219,9 @@ public abstract class PlcService implements PlcListener {
/**
* Creates a {@link LogMessage} for the given fields
*
* @param addressKey
* the address for the key
* @param bundle
* the bundle containing the message
* @param severity
* the severity of the message
* @param addressKey the address for the key
* @param bundle the bundle containing the message
* @param severity the severity of the message
*
* @return the {@link LogMessage} instance
*/
@ -246,14 +232,10 @@ public abstract class PlcService implements PlcListener {
/**
* Creates a {@link LogMessage} for the given fields
*
* @param addressKey
* the address for the key
* @param bundle
* the bundle containing the message
* @param severity
* the severity of the message
* @param state
* the state of the message
* @param addressKey the address for the key
* @param bundle the bundle containing the message
* @param severity the severity of the message
* @param state the state of the message
*
* @return the {@link LogMessage} instance
*/
@ -267,12 +249,9 @@ public abstract class PlcService implements PlcListener {
/**
* Creates a {@link LogMessage} for the given fields
*
* @param i18nKey
* the key of the message
* @param bundle
* the bundle containing the message
* @param severity
* the severity of the message
* @param i18nKey the key of the message
* @param bundle the bundle containing the message
* @param severity the severity of the message
*
* @return the {@link LogMessage} instance
*/
@ -283,14 +262,10 @@ public abstract class PlcService implements PlcListener {
/**
* Creates a {@link LogMessage} for the given fields
*
* @param i18nKey
* the key of the message
* @param bundle
* the bundle containing the message
* @param severity
* the severity of the message
* @param state
* the state of the message
* @param i18nKey the key of the message
* @param bundle the bundle containing the message
* @param severity the severity of the message
* @param state the state of the message
*
* @return the {@link LogMessage} instance
*/
@ -304,14 +279,13 @@ public abstract class PlcService implements PlcListener {
/**
* Sends the given {@link LogMessage} to the remote listener
*
* @param logMessage
* the message to send
* @param logMessage the message to send
*/
protected void sendMsg(LogMessage logMessage) {
switch (logMessage.getSeverity()) {
case Info, Notification -> logger.info(logMessage.toString());
case Warning -> logger.warn(logMessage.toString());
case Error, Exception -> logger.error(logMessage.toString());
case Info, Notification -> logger.info(logMessage.toString());
case Warning -> logger.warn(logMessage.toString());
case Error, Exception -> logger.error(logMessage.toString());
}
this.plcHandler.sendMsg(logMessage);
}
@ -319,8 +293,7 @@ public abstract class PlcService implements PlcListener {
/**
* Disables a message with the given {@link Locator}
*
* @param locator
* the locator of the message
* @param locator the locator of the message
*/
protected void disableMsg(Locator locator) {
logger.info("Disabling message for locator " + locator);
@ -330,10 +303,8 @@ public abstract class PlcService implements PlcListener {
/**
* Causes the {@link PlcAddress} for the given resource and action to be sent as a telegram with its default value
*
* @param resource
* the resource
* @param action
* the action
* @param resource the resource
* @param action the action
*/
protected void send(String resource, String action) {
this.plcHandler.send(resource, action);
@ -342,12 +313,9 @@ public abstract class PlcService implements PlcListener {
/**
* Causes the {@link PlcAddress} for the given resource and action to be sent as a telegram with the given value
*
* @param resource
* the resource
* @param action
* the action
* @param value
* the value to send with the {@link PlcAddress}
* @param resource the resource
* @param action the action
* @param value the value to send with the {@link PlcAddress}
*/
protected void send(String resource, String action, Object value) {
this.plcHandler.send(resource, action, value);
@ -356,12 +324,9 @@ public abstract class PlcService implements PlcListener {
/**
* Notifies listeners on the {@link PlcAddress} for the given resource and action, of the new value
*
* @param resource
* the resource
* @param action
* the action
* @param value
* the value to notify the listeners with
* @param resource the resource
* @param action the action
* @param value the value to notify the listeners with
*/
protected void notify(String resource, String action, Object value) {
this.plcHandler.notify(resource, action, value);
@ -370,8 +335,7 @@ public abstract class PlcService implements PlcListener {
/**
* Runs the given {@link PrivilegedRunnable} as the agent user
*
* @param runnable
* the runnable to run
* @param runnable the runnable to run
*/
protected void run(PrivilegedRunnable runnable) throws Exception {
this.container.getPrivilegeHandler().runAsAgent(runnable);
@ -380,10 +344,8 @@ public abstract class PlcService implements PlcListener {
/**
* Runs the given {@link PrivilegedRunnableWithResult} as the agent user, returning a value as the result
*
* @param runnable
* the runnable to run
* @param <T>
* the type of object being returned in the runnable
* @param runnable the runnable to run
* @param <T> the type of object being returned in the runnable
*
* @return the result of the runnable
*/
@ -394,10 +356,8 @@ public abstract class PlcService implements PlcListener {
/**
* Opens a new {@link StrolchTransaction} with the given {@link PrivilegeContext}
*
* @param ctx
* the {@link PrivilegeContext}
* @param readOnly
* true for the TX to be read only
* @param ctx the {@link PrivilegeContext}
* @param readOnly true for the TX to be read only
*
* @return the new TX to be used in a try-with-resource block
*/
@ -425,9 +385,8 @@ public abstract class PlcService implements PlcListener {
/**
* <p>Delays the execution of the given runnable by the given delay in milliseconds. Subsequent calls with the
* given
* {@link PlcAddress} will cancel any previous calls with the same address, delaying the execution again by the
* given amount of time.</p>
* given {@link PlcAddress} will cancel any previous calls with the same address, delaying the execution again by
* the given amount of time.</p>
*
* <p>This methods is used to handle hardware where the bits change often, before resting at a new state. E.g. a
* light barrier where it might toggle between true and false a few times, before staying true when the light
@ -445,8 +404,7 @@ public abstract class PlcService implements PlcListener {
/**
* Submits the given runnable for asynchronous execution
*
* @param runnable
* the runnable to execute asynchronously
* @param runnable the runnable to execute asynchronously
*/
protected void async(Runnable runnable) {
getExecutor().submit(() -> {
@ -461,12 +419,9 @@ public abstract class PlcService implements PlcListener {
/**
* Delay the execution of the given {@link Runnable} by the given delay
*
* @param runnable
* the runnable to delay
* @param delay
* the time to delay
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param delay the time to delay
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -483,12 +438,9 @@ public abstract class PlcService implements PlcListener {
/**
* Delay the execution of the given {@link PrivilegedRunnable} by the given delay
*
* @param runnable
* the runnable to delay
* @param delay
* the time to delay
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param delay the time to delay
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -505,14 +457,10 @@ public abstract class PlcService implements PlcListener {
/**
* Submit the given {@link Runnable} for repeated execution
*
* @param runnable
* the runnable to delay
* @param initialDelay
* the initial delay
* @param period
* the delay between subsequent executions
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param initialDelay the initial delay
* @param period the delay between subsequent executions
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -530,14 +478,10 @@ public abstract class PlcService implements PlcListener {
/**
* Submit the given {@link PrivilegedRunnable} for repeated execution
*
* @param runnable
* the runnable to delay
* @param initialDelay
* the initial delay
* @param period
* the delay between subsequent executions
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param initialDelay the initial delay
* @param period the delay between subsequent executions
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -555,14 +499,10 @@ public abstract class PlcService implements PlcListener {
/**
* Submit the given {@link Runnable} for repeated execution
*
* @param runnable
* the runnable to delay
* @param initialDelay
* the initial delay
* @param period
* the delay between subsequent executions
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param initialDelay the initial delay
* @param period the delay between subsequent executions
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -580,14 +520,10 @@ public abstract class PlcService implements PlcListener {
/**
* Submit the given {@link PrivilegedRunnable} for repeated execution
*
* @param runnable
* the runnable to delay
* @param initialDelay
* the initial delay
* @param period
* the delay between subsequent executions
* @param delayUnit
* the unit of the time to delay
* @param runnable the runnable to delay
* @param initialDelay the initial delay
* @param period the delay between subsequent executions
* @param delayUnit the unit of the time to delay
*
* @return a future to cancel the executor before execution
*/
@ -605,8 +541,7 @@ public abstract class PlcService implements PlcListener {
/**
* Notifies the caller of one of the async, or schedule methods that the execution of a runnable failed
*
* @param e
* the exception which occurred
* @param e the exception which occurred
*/
protected void handleFailedAsync(Exception e) {
logger.error("Failed to execute " + getClass().getSimpleName(), e);

View File

@ -87,14 +87,14 @@ public class DefaultPlc implements Plc {
if (this.listeners.removeElement(address, listener)) {
logger.info(address + ": " + listener.getClass().getName());
} else {
logger.warn("Listener not registered with key " + address.toKeyAddress() + ": " + listener.getClass()
.getSimpleName());
logger.warn("Listener not registered with key " + address.toKeyAddress() + ": " +
listener.getClass().getSimpleName());
}
}
@Override
public void syncNotify(String address, Object value) {
doNotify(address, value, true);
doNotify(address, value);
}
@Override
@ -102,7 +102,7 @@ public class DefaultPlc implements Plc {
this.notificationTasks.add(new NotificationTask(address, value));
}
private void doNotify(String address, Object value, boolean verbose) {
private void doNotify(String address, Object value) {
PlcAddress plcAddress = this.notificationMappings.get(address);
if (plcAddress == null) {
logger.warn("No mapping to PlcAddress for hwAddress " + address);
@ -113,15 +113,14 @@ public class DefaultPlc implements Plc {
if (value instanceof Boolean)
value = !((boolean) value);
else
logger.error(plcAddress + " is marked as inverted, but the value is not a boolean, but a "
+ value.getClass());
logger.error(plcAddress + " is marked as inverted, but the value is not a boolean, but a " +
value.getClass());
}
doNotify(plcAddress, value, verbose, true, true);
doNotify(plcAddress, value, true, true);
}
private void doNotify(PlcAddress plcAddress, Object value, boolean verbose, boolean catchExceptions,
boolean notifyGlobalListener) {
private void doNotify(PlcAddress plcAddress, Object value, boolean catchExceptions, boolean notifyGlobalListener) {
List<PlcListener> listeners = this.listeners.getList(plcAddress);
if (listeners == null || listeners.isEmpty()) {
@ -153,7 +152,7 @@ public class DefaultPlc implements Plc {
NotificationTask task = null;
try {
task = this.notificationTasks.take();
doNotify(task.address, task.value, this.verbose);
doNotify(task.address, task.value);
} catch (InterruptedException e) {
logger.error("Interrupted!");
} catch (Exception e) {
@ -181,7 +180,7 @@ public class DefaultPlc implements Plc {
logger.info("Sending {}: {} (default)", plcAddress.toKey(), plcAddress.defaultValue);
if (!isVirtual(plcAddress))
validateConnection(plcAddress).send(plcAddress.address, plcAddress.defaultValue);
doNotify(plcAddress, plcAddress.defaultValue, false, catchExceptions, notifyGlobalListener);
doNotify(plcAddress, plcAddress.defaultValue, catchExceptions, notifyGlobalListener);
}
@Override
@ -189,7 +188,7 @@ public class DefaultPlc implements Plc {
logger.info("Sending {}: {}", plcAddress.toKey(), value);
if (!isVirtual(plcAddress))
validateConnection(plcAddress).send(plcAddress.address, value);
doNotify(plcAddress, value, false, catchExceptions, notifyGlobalListener);
doNotify(plcAddress, value, catchExceptions, notifyGlobalListener);
}
private PlcConnection validateConnection(PlcAddress plcAddress) {
@ -210,8 +209,8 @@ public class DefaultPlc implements Plc {
public void addConnection(PlcConnection connection) {
this.connections.put(connection.getId(), connection);
Set<String> addresses = connection.getAddresses();
logger.info("Adding connection " + connection.getId() + " " + connection.getClass().getName() + " with "
+ addresses.size() + " addresses...");
logger.info("Adding connection " + connection.getId() + " " + connection.getClass().getName() + " with " +
addresses.size() + " addresses...");
for (String address : addresses) {
logger.info(" Adding " + address + "...");
this.connectionsByAddress.put(address, connection);

View File

@ -229,17 +229,6 @@ public class ExamplePlcConveyorPlcService extends PlcService {
super.register();
}
@Override
public void unregister() {
unregister(R_CONVEYOR_01, A_OCCUPIED);
unregister(R_CONVEYOR_02, A_OCCUPIED);
unregister(R_CONVEYOR_03, A_OCCUPIED);
unregister(R_CONVEYOR_04, A_OCCUPIED);
unregister(R_CONVEYOR_03, A_BARCODE);
super.unregister();
}
@Override
public void start(StrolchTransaction tx) {

View File

@ -150,10 +150,6 @@
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -2,6 +2,7 @@ package li.strolch.plc.gw.client;
import static java.net.NetworkInterface.getByInetAddress;
import static li.strolch.model.Tags.Json.*;
import static li.strolch.plc.core.DefaultPlcHandler.SILENT_THRESHOLD;
import static li.strolch.plc.model.ModelHelper.valueToJson;
import static li.strolch.plc.model.PlcConstants.*;
import static li.strolch.runtime.StrolchConstants.DEFAULT_REALM;
@ -89,7 +90,7 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
this.plcId = getComponent(PlcHandler.class).getPlcId();
this.gwConnectToServer = configuration.getBoolean("gwConnectToServer", true);
this.gwUsername = configuration.getString("gwUsername", null);
this.gwPassword = configuration.getString("gwPassword", null);
this.gwPassword = configuration.getSecret("gwPassword");
this.gwServerUrl = configuration.getString("gwServerUrl", null);
this.maxMessageQueue = configuration.getInt("maxMessageQueue", 100);
@ -178,10 +179,10 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
if (rootCause.getMessage() != null && rootCause.getMessage().contains("Connection refused")) {
logger.error(
"Connection refused to connect to server. Will try to connect again in " + RETRY_DELAY + "s: "
+ getExceptionMessageWithCauses(e));
} else if (rootCause.getMessage() != null && rootCause.getMessage()
.contains("Response code was not 101: 404.")) {
"Connection refused to connect to server. Will try to connect again in " + RETRY_DELAY + "s: " +
getExceptionMessageWithCauses(e));
} else if (rootCause.getMessage() != null &&
rootCause.getMessage().contains("Response code was not 101: 404.")) {
logger.error("Connection failed with 404 error code. Is URL " + this.gwServerUrl + " correct?");
logger.error("Server not yet ready with 404 error. Will try again in " + RETRY_DELAY + "s");
} else {
@ -189,8 +190,8 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
}
closeBrokenGwSessionUpdateState("Failed to connect to server",
"Connection refused to connect to server. Will try to connect again in " + RETRY_DELAY + "s: "
+ getExceptionMessageWithCauses(e));
"Connection refused to connect to server. Will try to connect again in " + RETRY_DELAY + "s: " +
getExceptionMessageWithCauses(e));
delayConnect(RETRY_DELAY, TimeUnit.SECONDS);
return;
}
@ -393,7 +394,8 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
private void handleGetAddressState(PrivilegeContext ctx, JsonObject telegramJ) throws Exception {
PlcAddress plcAddress = null;
try (StrolchTransaction tx = openTx(ctx.getCertificate(), true)) {
try (StrolchTransaction tx = openTx(ctx.getCertificate(), true).silentThreshold(SILENT_THRESHOLD,
TimeUnit.MILLISECONDS)) {
plcAddress = parsePlcAddress(telegramJ);
String plcAddressId = this.plcHandler.getPlcAddressId(plcAddress.resource, plcAddress.action);
@ -404,8 +406,7 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
telegramJ.addProperty(PARAM_STATE, PlcResponseState.Done.name());
telegramJ.addProperty(PARAM_STATE_MSG, "");
if (this.verbose)
logger.info("Sent address state for " + plcAddress.toKey() + " = " + value + " to server");
logger.info("Sent address state for " + plcAddress.toKey() + " = " + value + " to server");
} catch (Exception e) {
handleFailedTelegram(telegramJ, plcAddress, e);
@ -423,9 +424,9 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
if (telegramJ.has(PARAM_VALUE)) {
String valueS = telegramJ.get(PARAM_VALUE).getAsString();
Object value = plcAddress.valueType.parseValue(valueS);
this.plcHandler.send(plcAddress.resource, plcAddress.action, value, false, false);
this.plcHandler.send(plcAddress.resource, plcAddress.action, value, false, true);
} else {
this.plcHandler.send(plcAddress.resource, plcAddress.action, false, false);
this.plcHandler.send(plcAddress.resource, plcAddress.action, false, true);
}
telegramJ.addProperty(PARAM_STATE, PlcResponseState.Done.name());
@ -438,8 +439,8 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
sendDataToClient(telegramJ);
if (this.verbose)
logger.info("Sent Telegram response for " + (plcAddress == null ? "unknown" : plcAddress.toKey())
+ " to server");
logger.info("Sent Telegram response for " + (plcAddress == null ? "unknown" : plcAddress.toKey()) +
" to server");
}
private void handleAuthResponse(PrivilegeContext ctx, JsonObject response) {
@ -447,12 +448,12 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
if (!response.has(PARAM_STATE) || !response.has(PARAM_STATE_MSG) || !response.has(PARAM_AUTH_TOKEN)) {
closeBrokenGwSessionUpdateState(ctx, "Auth failed!",
"Failed to authenticated with Server: At least one of " + PARAM_STATE + ", " + PARAM_STATE_MSG
+ ", " + PARAM_AUTH_TOKEN + " params is missing on Auth Response");
"Failed to authenticated with Server: At least one of " + PARAM_STATE + ", " + PARAM_STATE_MSG +
", " + PARAM_AUTH_TOKEN + " params is missing on Auth Response");
throw new IllegalStateException(
"Failed to authenticated with Server: At least one of " + PARAM_STATE + ", " + PARAM_STATE_MSG
+ ", " + PARAM_AUTH_TOKEN + " params is missing on Auth Response");
"Failed to authenticated with Server: At least one of " + PARAM_STATE + ", " + PARAM_STATE_MSG +
", " + PARAM_AUTH_TOKEN + " params is missing on Auth Response");
}
if (PlcResponseState.valueOf(response.get(PARAM_STATE).getAsString()) != PlcResponseState.Sent) {
@ -491,13 +492,13 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
public void onWsClose(Session session, CloseReason closeReason) {
this.authenticated = false;
logger.info("Session closed with ID " + session.getId() + " due to " + closeReason.getCloseCode() + " "
+ closeReason.getReasonPhrase() + ". Reconnecting in " + RETRY_DELAY + "s.");
logger.info("Session closed with ID " + session.getId() + " due to " + closeReason.getCloseCode() + " " +
closeReason.getReasonPhrase() + ". Reconnecting in " + RETRY_DELAY + "s.");
if (this.gwSession != null) {
closeBrokenGwSessionUpdateState(closeReason.getReasonPhrase(),
"Session closed with ID " + session.getId() + " due to " + closeReason.getCloseCode() + " "
+ closeReason.getReasonPhrase() + ". Reconnecting in " + RETRY_DELAY + "s.");
"Session closed with ID " + session.getId() + " due to " + closeReason.getCloseCode() + " " +
closeReason.getReasonPhrase() + ". Reconnecting in " + RETRY_DELAY + "s.");
}
delayConnect(RETRY_DELAY, TimeUnit.SECONDS);
@ -560,7 +561,8 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
private void saveServerConnectionState(PrivilegeContext ctx, ConnectionState state, String stateMsg) {
StrolchRealm realm = getContainer().getRealm(ctx.getCertificate());
try (StrolchTransaction tx = realm.openTx(ctx.getCertificate(), "saveServerConnectionState", false)) {
try (StrolchTransaction tx = realm.openTx(ctx.getCertificate(), "saveServerConnectionState", false)
.silentThreshold(SILENT_THRESHOLD, TimeUnit.MILLISECONDS)) {
Resource plc = tx.getResourceBy(TYPE_PLC, this.plcId, true);
StringParameter stateP = plc.getParameter(PARAM_CONNECTION_STATE, true);
@ -580,18 +582,17 @@ public class PlcGwClientHandler extends StrolchComponent implements GlobalPlcLis
VersionQueryResult versionQueryResult = getContainer().getAgent().getVersion();
this.versions.add(AGENT_VERSION, versionQueryResult.getAgentVersion().toJson());
this.versions.add(APP_VERSION, versionQueryResult.getAppVersion().toJson());
this.versions.add(COMPONENT_VERSIONS, versionQueryResult.getComponentVersions()
.stream()
.map(ComponentVersion::toJson)
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
this.versions.add(COMPONENT_VERSIONS,
versionQueryResult.getComponentVersions().stream().map(ComponentVersion::toJson)
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
}
return this.versions;
}
public JsonArray getIpAddresses() {
if (this.ipAddresses == null || this.ipAddresses.size() == 0 || (
System.currentTimeMillis() - this.ipAddressesUpdateTime > 10000L)) {
if (this.ipAddresses == null || this.ipAddresses.size() == 0 ||
(System.currentTimeMillis() - this.ipAddressesUpdateTime > 10000L)) {
try {
this.ipAddresses = NetworkHelper.findInet4Addresses().stream().map(add -> {
String mac;

View File

@ -149,10 +149,6 @@
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -143,10 +143,6 @@
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

25
pom.xml
View File

@ -27,13 +27,13 @@
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<organization>
<name>Strolch</name>
<url>http://www.strolch.li/plc</url>
<url>https://www.strolch.li/plc</url>
</organization>
<developers>
@ -66,7 +66,8 @@
<hikaricp.version>5.0.1</hikaricp.version>
<postgresql.version>42.5.1</postgresql.version>
<antlr.version>4.9.3</antlr.version>
<javaxmail.version>1.6.2</javaxmail.version>
<jakarta-mail.version>2.1.0</jakarta-mail.version>
<angus-mail.version>2.0.1</angus-mail.version>
<csv.version>1.9.0</csv.version>
<cron.version>1.6.2</cron.version>
@ -94,15 +95,14 @@
<!-- maven plug-in dependencies -->
<maven-scm-plugin.version>1.12.2</maven-scm-plugin.version>
<buildnumber-maven-plugin.version>3.0.0</buildnumber-maven-plugin.version>
<git-versioner-maven-plugin.version>0.2.0</git-versioner-maven-plugin.version>
<versions-maven-plugin.version>2.8.1</versions-maven-plugin.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<dependency-check-maven-plugin.version>6.5.2</dependency-check-maven-plugin.version>
<maven-site-plugin.version>3.10.0</maven-site-plugin.version>
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<maven-site-plugin.version>3.12.1</maven-site-plugin.version>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
<tomcat7-maven-plugin.version>2.2</tomcat7-maven-plugin.version>
<maven-war-plugin.version>3.4.0</maven-war-plugin.version>
<maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>
<maven-deploy-plugin.version>3.0.0-M2</maven-deploy-plugin.version>
<maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
@ -327,7 +327,6 @@
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
@ -424,16 +423,6 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<downloadJavadocs>true</downloadJavadocs>
<downloadSources>true</downloadSources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>