Merge branch 'develop' into release/2.0
This commit is contained in:
commit
ee1f34001d
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<applicationName>Strolch PLC</applicationName>
|
||||
<Properties>
|
||||
<locale>en</locale>
|
||||
<verbose>true</verbose>
|
||||
<timezone>Europe/Zurich</timezone>
|
||||
</Properties>
|
||||
</Runtime>
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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
25
pom.xml
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue