org.bidib.wizard.mvc.ping.model.PingTableModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-client Show documentation
Show all versions of bidibwizard-client Show documentation
jBiDiB BiDiB Wizard Client Application POM
package org.bidib.wizard.mvc.ping.model;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.event.ConsoleMessageEvent;
import org.bidib.wizard.api.service.console.ConsoleColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jgoodies.binding.beans.Model;
import com.jgoodies.common.collect.ArrayListModel;
public class PingTableModel extends Model {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(PingTableModel.class);
public static final String PROPERTY_NODES = "nodes";
public static final String PROPERTY_NODE_PING_STATUS = "nodePingStatus";
private ArrayListModel nodeList = new ArrayListModel<>();
private final PropertyChangeListener pclNodePingModel;
private int defaultPingInterval = 200;
private final PingTablePreferences pingTablePreferences;
public PingTableModel(final PingTablePreferences pingTablePreferences) {
this.pingTablePreferences = pingTablePreferences;
pclNodePingModel = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
LOGGER.info("The property of the node ping model has changed: {}", evt.getSource());
if (evt.getSource() instanceof NodePingModel) {
NodePingModel nodePingModel = (NodePingModel) evt.getSource();
switch (evt.getPropertyName()) {
case NodePingModel.PROPERTY_NODE_PING_STATUS:
firePropertyChange(PROPERTY_NODE_PING_STATUS, null, nodePingModel.getNode());
break;
case NodePingModel.PROPERTY_PING_INTERVAL:
try {
PingTableNodePreferenceEntry prefs =
PingTableModel.this.pingTablePreferences
.getPrefencesOrDefault(nodePingModel.getNode().getUniqueId());
prefs.setPingInterval(nodePingModel.getPingInterval());
PingTableModel.this.pingTablePreferences.store();
}
catch (Exception ex) {
LOGGER.warn("Store ping table preferences failed.", ex);
}
break;
case NodePingModel.PROPERTY_ADDITIONAL_FILL_BYTES_COUNT:
try {
PingTableNodePreferenceEntry prefs =
PingTableModel.this.pingTablePreferences
.getPrefencesOrDefault(nodePingModel.getNode().getUniqueId());
prefs.setAdditionalFillBytesCount(nodePingModel.getAdditionalFillBytesCount());
PingTableModel.this.pingTablePreferences.store();
}
catch (Exception ex) {
LOGGER.warn("Store ping table preferences failed.", ex);
}
break;
case NodePingModel.PROPERTY_ADDITIONAL_TOTAL_BYTES_COUNT:
try {
PingTableNodePreferenceEntry prefs =
PingTableModel.this.pingTablePreferences
.getPrefencesOrDefault(nodePingModel.getNode().getUniqueId());
prefs.setAdditionalTotalBytesCount(nodePingModel.getAdditionalTotalBytesCount());
PingTableModel.this.pingTablePreferences.store();
}
catch (Exception ex) {
LOGGER.warn("Store ping table preferences failed.", ex);
}
break;
case NodePingModel.PROPERTY_IDENTIFY_PROCESSING_WAIT_DURATION:
try {
PingTableNodePreferenceEntry prefs =
PingTableModel.this.pingTablePreferences
.getPrefencesOrDefault(nodePingModel.getNode().getUniqueId());
prefs
.setIdentityProcessingWaitDuration(
nodePingModel.getIdentifyProcessingWaitDuration());
PingTableModel.this.pingTablePreferences.store();
}
catch (Exception ex) {
LOGGER.warn("Store ping table preferences failed.", ex);
}
break;
default:
break;
}
}
}
};
}
/**
* Set the default ping interval.
*
* @param pingInterval
* the default ping interval
*/
public void setDefaultPingInterval(int pingInterval) {
LOGGER.info("Set the defaultPingInterval: {}", pingInterval);
this.defaultPingInterval = pingInterval;
}
public void addNode(final NodeInterface node) {
synchronized (nodeList) {
NodePingModel nodePingModel = new NodePingModel(node);
if (!nodeList.contains(nodePingModel)) {
LOGGER.info("Add node to ping node list: {}", node);
nodePingModel.registerNode();
// set the default interval
nodePingModel.setPingInterval(this.defaultPingInterval);
nodePingModel.setLastPingTimestamp(System.currentTimeMillis());
nodePingModel.setNodePingState(NodePingState.OFF);
String nodeLabel = nodePingModel.prepareNodeLabel();
nodePingModel.setNodeLabel(nodeLabel);
// check if we have preferences for this node
PingTableNodePreferenceEntry prefs = this.pingTablePreferences.getPrefences(node.getUniqueId());
if (prefs != null) {
nodePingModel.setPingInterval(prefs.getPingInterval());
nodePingModel.setAdditionalFillBytesCount(prefs.getAdditionalFillBytesCount());
nodePingModel.setAdditionalTotalBytesCount(prefs.getAdditionalTotalBytesCount());
nodePingModel.setAdditionalPayloadStartValue(prefs.getAdditionalPayloadStartValue());
nodePingModel.setIdentifyProcessingWaitDuration(prefs.getIdentityProcessingWaitDuration());
}
List oldValue = new LinkedList<>(nodeList);
nodeList.add(nodePingModel);
firePropertyChange(PROPERTY_NODES, oldValue, nodeList);
nodePingModel
.addPropertyChangeListener(/* NodePingModel.PROPERTY_NODE_PING_STATUS, */ pclNodePingModel);
}
else {
LOGGER.warn("Node is already in ping node list: {}", node);
}
}
}
public void removeNode(final NodeInterface node) {
synchronized (nodeList) {
LOGGER.info("Remove node from ping node list: {}", node);
List oldValue = new LinkedList<>(nodeList);
int index = nodeList.indexOf(new NodePingModel(node));
if (index > -1) {
NodePingModel removed = nodeList.remove(index);
LOGGER.info("Removed node: {}", removed);
removed.removePropertyChangeListener(/* NodePingModel.PROPERTY_NODE_PING_STATUS, */ pclNodePingModel);
if (removed != null) {
removed.freeNode();
}
firePropertyChange(PROPERTY_NODES, oldValue, nodeList);
}
}
}
public ArrayListModel getNodeListModel() {
return nodeList;
}
public List getNodes() {
return Collections.unmodifiableList(nodeList);
}
public void setNodePingState(final NodeInterface node, NodePingState nodePingState) {
synchronized (nodeList) {
int index = nodeList.indexOf(new NodePingModel(node));
if (index > -1) {
NodePingModel nodePingModel = nodeList.get(index);
if (nodePingModel != null) {
nodePingModel.setNodePingState(nodePingState);
// firePropertyChange(PROPERTY_NODE_PING_STATUS, null, node);
}
}
}
}
public void setPongMarker(byte[] address, int marker, final Consumer consoleCallback) {
final NodePingModel pingModel;
synchronized (nodeList) {
pingModel =
nodeList
.stream().filter(npm -> Arrays.equals(address, npm.getNode().getAddr())).findFirst().orElse(null);
}
if (pingModel != null) {
long lastPongMarker = pingModel.getLastPongMarker();
if (lastPongMarker < 0) {
// invalid marker, ignore evaluation
}
else {
// check if the pong marker is correct
lastPongMarker += 1;
if (lastPongMarker > 255) {
lastPongMarker = 0;
}
if (marker != lastPongMarker) {
LOGGER.warn("Invalid pong marker detected. Received: {}, expected: {}", marker, lastPongMarker);
// prepare the console message event
final ConsoleMessageEvent consoleMessageEvent =
new ConsoleMessageEvent(ConsoleColor.red,
"Invalid pong marker detected. Received: " + marker + ", expected: " + lastPongMarker);
consoleCallback.accept(consoleMessageEvent);
}
else {
LOGGER.info("The pong marker is valid! Received: {}, expected: {}", marker, lastPongMarker);
}
}
// update the last pong marker
pingModel.setLastPongMarker(marker);
}
}
public void checkIdentifyWaitTime(byte[] address) {
final NodePingModel pingModel;
synchronized (nodeList) {
pingModel =
nodeList
.stream().filter(npm -> Arrays.equals(address, npm.getNode().getAddr())).findFirst().orElse(null);
}
if (pingModel != null) {
int identifyProcessingWaitDuration = pingModel.getIdentifyProcessingWaitDuration();
if (identifyProcessingWaitDuration > 0) {
LOGGER
.info("Simulate long duration for processing, identifyProcessingWaitDuration: {}",
identifyProcessingWaitDuration);
try {
Thread.sleep(identifyProcessingWaitDuration);
LOGGER.info("identifyProcessingWaitDuration elapsed.");
}
catch (Exception ex) {
LOGGER.warn("Wait for expiration of identifyProcessingWaitDuration failed.", ex);
}
}
}
}
}