/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.communication.views.contributors;
import static de.rcenvironment.core.monitoring.system.api.SystemMonitoringConstants.PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.graphics.Image;
import de.rcenvironment.core.communication.api.CommunicationService;
import de.rcenvironment.core.communication.common.InstanceNodeSessionId;
import de.rcenvironment.core.communication.spi.NetworkTopologyChangeListener;
import de.rcenvironment.core.communication.spi.NetworkTopologyChangeListenerAdapter;
import de.rcenvironment.core.gui.communication.views.NetworkViewContentProvider;
import de.rcenvironment.core.gui.communication.views.model.NetworkGraphNodeWithContext;
import de.rcenvironment.core.gui.communication.views.spi.ContributedNetworkViewNode;
import de.rcenvironment.core.gui.communication.views.spi.ContributedNetworkViewNodeWithParent;
import de.rcenvironment.core.gui.communication.views.spi.NetworkViewContributor;
import de.rcenvironment.core.gui.communication.views.spi.SelfRenderingNetworkViewNode;
import de.rcenvironment.core.gui.resources.api.ImageManager;
import de.rcenvironment.core.gui.resources.api.StandardImages;
import de.rcenvironment.core.monitoring.system.api.SystemMonitoringDataPollingManager;
import de.rcenvironment.core.monitoring.system.api.SystemMonitoringDataSnapshotListener;
import de.rcenvironment.core.monitoring.system.api.model.ProcessInformation;
import de.rcenvironment.core.monitoring.system.api.model.FullSystemAndProcessDataSnapshot;
import de.rcenvironment.core.utils.common.StringUtils;
import de.rcenvironment.core.utils.incubator.ServiceRegistry;
import de.rcenvironment.core.utils.incubator.ServiceRegistryAccess;
import de.rcenvironment.core.utils.incubator.ServiceRegistryPublisherAccess;
import de.rcenvironment.toolkit.modules.concurrency.api.AsyncTaskService;
/**
* Contributes a subtree for node resource informations.
*
* @author David Scholz
* @author Robert Mischke
*/
public class MonitoringDataContributor extends NetworkViewContributorBase {
private static final double DOUBLE_0_01 = 0.01;
private static final double DOUBLE_0_2 = 0.2;
private static final double DOUBLE_0_4 = 0.4;
private static final double DOUBLE_0_6 = 0.6;
private static final double DOUBLE_0_8 = 0.8;
private static final double DOUBLE_0_99 = 0.99;
private static final int MONITORING_DATA_PRIORITY = 15;
private final Map<InstanceNodeSessionId, ContributedNetworkViewNode> idToNodeMap;
private final Map<InstanceNodeSessionId, ContributedNetworkViewNode> expansionsMap;
private final Map<InstanceNodeSessionId, List<RceNode>> nodeIdToRceNodeMap;
private final Map<InstanceNodeSessionId, List<InstanceResourceInfoNode>> nodeIdToInstanceResourceInfoMap;
private final SystemMonitoringDataPollingManager pollingManager;
private final Image cpuMonitorImage0;
private final Image cpuMonitorImage1;
private final Image cpuMonitorImage2;
private final Image cpuMonitorImage3;
private final Image cpuMonitorImage4;
private final Image cpuMonitorImage5;
private final Image cpuMonitorImage6;
private final Image ramMonitorImage0;
private final Image ramMonitorImage1;
private final Image ramMonitorImage2;
private final Image ramMonitorImage3;
private final Image ramMonitorImage4;
private final Image ramMonitorImage5;
private final Image ramMonitorImage6;
private final Image sharedFolderImage;
private final Image dummyImage;
private final ServiceRegistryPublisherAccess servicePublisher;
private final Log log = LogFactory.getLog(getClass());
public MonitoringDataContributor() {
final ServiceRegistryAccess serviceAccess = ServiceRegistry.createAccessFor(this);
final CommunicationService communicationService = serviceAccess.getService(CommunicationService.class);
final AsyncTaskService asyncTaskService = serviceAccess.getService(AsyncTaskService.class);
pollingManager = new SystemMonitoringDataPollingManager(communicationService, asyncTaskService);
sharedFolderImage = ImageManager.getInstance().getSharedImage(StandardImages.FOLDER_16);
dummyImage = ImageManager.getInstance().getSharedImage(StandardImages.INFORMATION_16);
// TODO this should be handled via arrays, not copy&paste
cpuMonitorImage0 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor0_16.gif")).createImage();
cpuMonitorImage1 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor1_16.gif")).createImage();
cpuMonitorImage2 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor2_16.gif")).createImage();
cpuMonitorImage3 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor3_16.gif")).createImage();
cpuMonitorImage4 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor4_16.gif")).createImage();
cpuMonitorImage5 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor5_16.gif")).createImage();
cpuMonitorImage6 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/cpuMonitor/cpuMonitor6_16.gif")).createImage();
ramMonitorImage0 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor0_16.gif")).createImage();
ramMonitorImage1 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor1_16.gif")).createImage();
ramMonitorImage2 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor2_16.gif")).createImage();
ramMonitorImage3 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor3_16.gif")).createImage();
ramMonitorImage4 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor4_16.gif")).createImage();
ramMonitorImage5 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor5_16.gif")).createImage();
ramMonitorImage6 = ImageDescriptor.createFromURL(
getClass().getResource("/resources/icons/ramMonitor/ramMonitor6_16.gif")).createImage();
idToNodeMap = new HashMap<>();
expansionsMap = new HashMap<>();
nodeIdToRceNodeMap = new HashMap<>();
nodeIdToInstanceResourceInfoMap = new HashMap<>();
servicePublisher = ServiceRegistry.createPublisherAccessFor(this);
registerChangeListeners();
}
/**
* A tree node representing the root node of the monitoring data.
*
* @author David Scholz
*/
private class MonitoringDataFolderRootNode implements ContributedNetworkViewNode {
private final NetworkGraphNodeWithContext instanceNode;
MonitoringDataFolderRootNode(NetworkGraphNodeWithContext instanceNode) {
this.instanceNode = instanceNode;
}
public NetworkGraphNodeWithContext getInstanceNode() {
return instanceNode;
}
@Override
public NetworkViewContributor getContributor() {
return MonitoringDataContributor.this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
if (instanceNode == null) {
result = prime * result;
} else {
result = prime * result + instanceNode.hashCode();
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MonitoringDataFolderRootNode other = (MonitoringDataFolderRootNode) obj;
if (!getOuterType().equals(other.getOuterType())) {
return false;
}
if (instanceNode == null) {
if (other.instanceNode != null) {
return false;
}
} else if (!instanceNode.equals(other.instanceNode)) {
return false;
}
return true;
}
private MonitoringDataContributor getOuterType() {
return MonitoringDataContributor.this;
}
}
/**
*
* Context of a {@link InstanceCpuInfoNode}.
*
* @author David Scholz
*/
public enum InstanceNodeContext {
// /**
// * Idle.
// */
// IDLE,
// /**
// * Sum of other processes.
// */
// OTHER_PROCESSES,
/**
* Total node cpu usage.
*/
NODE_CPU_USAGE,
/**
* Total node ram usage.
*/
NODE_RAM_USAGE
// /**
// * Total node ram.
// */
// TOTAL_NODE_RAM
}
/**
*
* A tree node representing the different instance resource informations such as idle and system ram.
*
* @author David Scholz
* @author Robert Mischke
*/
private class InstanceResourceInfoNode implements ContributedNetworkViewNodeWithParent {
private double cpuUsage;
private double cpuOther;
private double cpuIdle;
private long ramUsed;
private final long ramTotal;
private final InstanceNodeContext context;
private final String nodeIdString;
private final Object parentNode;
InstanceResourceInfoNode(Object parentNode, InstanceNodeContext context, double cpuUsage, double otherCpuUsage,
double idleCpu, String nodeId) {
this.parentNode = parentNode;
this.cpuUsage = cpuUsage;
this.context = context;
this.cpuOther = otherCpuUsage;
this.cpuIdle = idleCpu;
this.ramTotal = 0;
this.nodeIdString = nodeId;
}
InstanceResourceInfoNode(Object parentNode, InstanceNodeContext context, long ram, long ramTotal) {
this.parentNode = parentNode;
this.ramUsed = ram;
this.ramTotal = ramTotal;
this.context = context;
this.nodeIdString = null;
}
@Override
public Object getParentNode() {
return parentNode;
}
public double getCpuUsage() {
return cpuUsage;
}
public InstanceNodeContext getInstanceNodeContext() {
return context;
}
public long getRam() {
return ramUsed;
}
public void setRam(long ram) {
this.ramUsed = ram;
}
public void setCpuUsage(double usage, double other, double idle) {
this.cpuUsage = usage;
this.cpuOther = other;
this.cpuIdle = idle;
}
@Override
public NetworkViewContributor getContributor() {
return MonitoringDataContributor.this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
if (context == null) {
result = prime * result;
} else {
result = prime * result + context.hashCode();
}
if (nodeIdString == null) {
result = prime * result;
} else {
result = prime * result + nodeIdString.hashCode();
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
InstanceResourceInfoNode other = (InstanceResourceInfoNode) obj;
if (!getOuterType().equals(other.getOuterType())) {
return false;
}
if (context != other.context) {
return false;
}
if (nodeIdString == null) {
if (other.nodeIdString != null) {
return false;
}
} else if (!nodeIdString.equals(other.nodeIdString)) {
return false;
}
return true;
}
private MonitoringDataContributor getOuterType() {
return MonitoringDataContributor.this;
}
}
/**
*
* A tree node representing process information.
*
* @author David Scholz
*/
private class ProcessInfoNode implements ContributedNetworkViewNodeWithParent {
private ProcessInformation processInfo;
private long pid;
private Object parentNode;
ProcessInfoNode(Object parentNode, ProcessInformation processInfo) {
this.parentNode = parentNode;
this.processInfo = processInfo;
this.pid = processInfo.getPid();
}
public ProcessInformation getProcessInfo() {
return processInfo;
}
public List<ProcessInformation> getChildren() {
return processInfo.getChildren();
}
public Object getParentNode() {
return parentNode;
}
@Override
public NetworkViewContributor getContributor() {
return MonitoringDataContributor.this;
}
@Override
public int hashCode() {
final int prime = 31;
final int i = 32;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + (int) (pid ^ (pid >>> i));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ProcessInfoNode other = (ProcessInfoNode) obj;
if (!getOuterType().equals(other.getOuterType())) {
return false;
}
if (pid != other.pid) {
return false;
}
return true;
}
private MonitoringDataContributor getOuterType() {
return MonitoringDataContributor.this;
}
}
/**
*
* A tree node representing rce subprocesses or rce instance informations.
*
* @author David Scholz
*/
private class RceNode implements ContributedNetworkViewNodeWithParent {
private final boolean typeIsSubProcessRoot;
private double cpuUsage;
private List<ProcessInformation> children;
private String nodeIdString;
private final Object parentNode;
RceNode(Object parentNode, boolean typeIsSubProcessRoot, double cpuUsage, List<ProcessInformation> children,
String nodeIdString) {
this.parentNode = parentNode;
this.typeIsSubProcessRoot = typeIsSubProcessRoot;
this.cpuUsage = cpuUsage;
this.children = children;
this.nodeIdString = nodeIdString;
}
public boolean getTypeIsSubProcessRoot() {
return typeIsSubProcessRoot;
}
public double getCpuUsage() {
return cpuUsage;
}
public void setCpuUsage(double usage) {
this.cpuUsage = usage;
}
public void setChildren(List<ProcessInformation> children) {
this.children = children;
}
public List<ProcessInformation> getChildren() {
return children;
}
@Override
public Object getParentNode() {
return parentNode;
}
@Override
public NetworkViewContributor getContributor() {
return MonitoringDataContributor.this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
final int f = 1237;
final int t = 1231;
result = prime * result + getOuterType().hashCode();
if (nodeIdString == null) {
result = prime * result;
} else {
result = prime * result + nodeIdString.hashCode();
}
if (typeIsSubProcessRoot) {
result = prime * result + t;
} else {
result = prime * result + f;
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
RceNode other = (RceNode) obj;
if (!getOuterType().equals(other.getOuterType())) {
return false;
}
if (nodeIdString == null) {
if (other.nodeIdString != null) {
return false;
}
} else if (!nodeIdString.equals(other.nodeIdString)) {
return false;
}
if (typeIsSubProcessRoot != other.typeIsSubProcessRoot) {
return false;
}
return true;
}
private MonitoringDataContributor getOuterType() {
return MonitoringDataContributor.this;
}
}
@Override
public int getRootElementsPriority() {
return 0; // disabled
}
@Override
public Object[] getTopLevelElements(Object parentNode) {
return null; // disabled
}
@Override
public int getInstanceDataElementsPriority() {
return MONITORING_DATA_PRIORITY;
}
@Override
public Object[] getChildrenForNetworkInstanceNode(NetworkGraphNodeWithContext instanceNode) {
Object[] objectArray = new Object[1];
objectArray[0] = new MonitoringDataFolderRootNode(instanceNode);
return objectArray;
}
@Override
public boolean hasChildren(Object parentNode) {
if (parentNode instanceof MonitoringDataFolderRootNode) {
return true;
} else if (parentNode instanceof InstanceResourceInfoNode) {
return false;
} else if (parentNode instanceof RceNode) {
List<ProcessInformation> children = ((RceNode) parentNode).getChildren();
return !children.isEmpty();
} else if (parentNode instanceof ProcessInfoNode) {
List<ProcessInformation> children = ((ProcessInfoNode) parentNode).getChildren();
return !children.isEmpty();
}
return false;
}
@Override
public Object[] getChildren(Object parentNode) {
if (parentNode instanceof MonitoringDataFolderRootNode) {
return createMonitoringRootFolderContent(parentNode);
} else if (parentNode instanceof RceNode) {
return createRceNodeFolderContent(parentNode);
} else if (parentNode instanceof ProcessInfoNode) {
return createProcessInfoNodeContent(parentNode);
}
return null;
}
@Override
public Object getParent(Object node) {
if (node instanceof MonitoringDataFolderRootNode) {
return ((MonitoringDataFolderRootNode) node).getInstanceNode();
} else {
return null; // error; will cause an upstream warning
}
}
@Override
public String getText(Object node) {
if (node instanceof MonitoringDataFolderRootNode) {
return "Monitoring Data";
} else if (node instanceof InstanceResourceInfoNode) {
InstanceResourceInfoNode infoNode = (InstanceResourceInfoNode) node;
String text;
switch (infoNode.getInstanceNodeContext()) {
// case IDLE:
// text = StringUtils.format("System Idle: %.2f%%", infoNode.getCpuUsage() * CONVERT_PERCENTAGE);
// break;
// case OTHER_PROCESSES:
// text = StringUtils.format("Other processes: %.2f%%", infoNode.getCpuUsage() * CONVERT_PERCENTAGE);
// break;
case NODE_CPU_USAGE:
// note: difficult to phrase "processes not related to this instance" understandably;
// "Non-Instance processes" is the best solution found so far
text =
StringUtils.format("Total CPU usage: %.2f%% (Non-Instance processes: %.2f%%, Idle: %.2f%%)", infoNode.getCpuUsage()
* PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER, infoNode.cpuOther * PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER,
infoNode.cpuIdle * PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER);
break;
// case TOTAL_NODE_RAM:
// text = StringUtils.format("Total RAM: %d MB", infoNode.getRam());
// break;
case NODE_RAM_USAGE:
text = StringUtils.format("Total RAM usage: %d / %d MiB", infoNode.getRam(), infoNode.ramTotal);
break;
default:
text = "Fail..."; // should never happen. would be funny though..
break;
}
return text;
} else if (node instanceof RceNode) {
RceNode rce = (RceNode) node;
if (rce.getTypeIsSubProcessRoot()) {
return StringUtils.format("RCE Tools CPU Usage: %.2f%%", rce.getCpuUsage() * PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER);
} else {
return StringUtils.format("RCE CPU Usage: %.2f%%", rce.getCpuUsage() * PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER);
}
} else if (node instanceof ProcessInfoNode) {
ProcessInfoNode processInfo = (ProcessInfoNode) node;
return StringUtils.format(processInfo.getProcessInfo().getName() + ": %.2f%% [%d]", processInfo.getProcessInfo().getCpuUsage()
* PERCENTAGE_TO_DISPLAY_VALUE_MULTIPLIER, processInfo.getProcessInfo().getPid());
}
return null;
}
@Override
public Image getImage(Object node) {
if (node instanceof MonitoringDataFolderRootNode || node instanceof RceNode) {
return sharedFolderImage;
} else if (node instanceof InstanceResourceInfoNode) {
InstanceResourceInfoNode infoNode = (InstanceResourceInfoNode) node;
switch (infoNode.getInstanceNodeContext()) {
case NODE_CPU_USAGE:
return getDynamicCPUImage(infoNode.getCpuUsage());
case NODE_RAM_USAGE:
return getDynamicRamImage(infoNode.getRam(), infoNode.ramTotal);
default:
return dummyImage;
}
} else if (node instanceof ProcessInfoNode) {
ProcessInfoNode infoNode = (ProcessInfoNode) node;
return getDynamicCPUImage(infoNode.getProcessInfo().getCpuUsage());
}
return null;
}
private Image getDynamicRamImage(long ram, long ramTotal) {
double percentage = ((float) ram / (float) ramTotal);
if (percentage > DOUBLE_0_99) {
return ramMonitorImage6;
}
if (percentage > DOUBLE_0_8) {
return ramMonitorImage5;
}
if (percentage > DOUBLE_0_6) {
return ramMonitorImage4;
}
if (percentage > DOUBLE_0_4) {
return ramMonitorImage3;
}
if (percentage > DOUBLE_0_2) {
return ramMonitorImage2;
}
if (percentage > DOUBLE_0_01) {
return ramMonitorImage1;
}
return ramMonitorImage0;
}
private Image getDynamicCPUImage(double percentage) {
if (percentage > DOUBLE_0_99) {
return cpuMonitorImage6;
}
if (percentage > DOUBLE_0_8) {
return cpuMonitorImage5;
}
if (percentage > DOUBLE_0_6) {
return cpuMonitorImage4;
}
if (percentage > DOUBLE_0_4) {
return cpuMonitorImage3;
}
if (percentage > DOUBLE_0_2) {
return cpuMonitorImage2;
}
if (percentage > DOUBLE_0_01) {
return cpuMonitorImage1;
}
return cpuMonitorImage0;
}
@Override
public void dispose() {
servicePublisher.dispose();
}
@Override
public void setTreeViewer(TreeViewer viewer) {
super.setTreeViewer(viewer);
treeViewer.addTreeListener(getTreeListener());
}
private Object[] createMonitoringRootFolderContent(Object parentNode) {
List<Object> result = new ArrayList<>(7);
MonitoringDataFolderRootNode rootNode = (MonitoringDataFolderRootNode) parentNode;
FullSystemAndProcessDataSnapshot model =
currentModel.getMonitoringDataModelMap().get(rootNode.getInstanceNode().getNode().getNodeId());
if (model == null) {
Object[] placeHolder = new Object[1];
placeHolder[0] = "Fetching monitoring data...";
return placeHolder;
}
final InstanceNodeSessionId nodeId = rootNode.getInstanceNode().getNode().getNodeId();
final String nodeIdString = nodeId.getInstanceNodeSessionIdString();
boolean keyExists = false;
synchronized (nodeIdToInstanceResourceInfoMap) {
keyExists = nodeIdToRceNodeMap.containsKey(nodeId);
}
if (!keyExists) {
RceNode subProcess =
new RceNode(parentNode, true, model.getTotalSubProcessesCpuUsage(), model.getRceSubProcesses(), nodeIdString);
RceNode rce =
new RceNode(parentNode, false, model.getTotalRceOwnProcessesCpuUsage(), model.getRceProcessesInfo(), nodeIdString);
List<RceNode> rceNodeList = new ArrayList<>(2);
rceNodeList.add(rce);
rceNodeList.add(subProcess);
synchronized (nodeIdToInstanceResourceInfoMap) {
nodeIdToRceNodeMap.put(nodeId, rceNodeList);
}
expansionsMap.put(nodeId, subProcess);
} else {
List<RceNode> rceList = new ArrayList<>();
synchronized (nodeIdToInstanceResourceInfoMap) {
rceList.addAll(nodeIdToRceNodeMap.get(nodeId));
}
for (RceNode node : rceList) {
if (node.getTypeIsSubProcessRoot()) {
node.setChildren(model.getRceSubProcesses());
node.setCpuUsage(model.getTotalSubProcessesCpuUsage());
} else {
node.setChildren(model.getRceProcessesInfo());
node.setCpuUsage(model.getTotalRceOwnProcessesCpuUsage());
}
}
}
boolean valid = false;
synchronized (nodeIdToInstanceResourceInfoMap) {
valid = nodeIdToInstanceResourceInfoMap.containsKey(nodeId);
}
if (!valid) {
InstanceResourceInfoNode cpuUsage =
new InstanceResourceInfoNode(parentNode, InstanceNodeContext.NODE_CPU_USAGE, model.getNodeCPUusage(), model.getIdle(),
model.getOtherProcessCpuUsage(), nodeIdString);
// InstanceResourceInfoNode nodeIdle = new InstanceResourceInfoNode(InstanceNodeContext.IDLE, model.getIdle(), nodeIdString);
// InstanceResourceInfoNode other =
// new InstanceResourceInfoNode(InstanceNodeContext.OTHER_PROCESSES, model.getOtherProcessCpuUsage(), nodeIdString);
// InstanceResourceInfoNode totalRam = new InstanceResourceInfoNode(InstanceNodeContext.TOTAL_NODE_RAM,
// model.getNodeSystemRAM());
InstanceResourceInfoNode ramUsage =
new InstanceResourceInfoNode(parentNode, InstanceNodeContext.NODE_RAM_USAGE, model.getNodeRAMUsage(),
model.getNodeSystemRAM());
List<InstanceResourceInfoNode> instanceResourceInfoList = new ArrayList<>(5);
instanceResourceInfoList.add(cpuUsage);
instanceResourceInfoList.add(ramUsage);
// instanceResourceInfoList.add(nodeIdle);
// instanceResourceInfoList.add(other);
synchronized (nodeIdToInstanceResourceInfoMap) {
nodeIdToInstanceResourceInfoMap.put(nodeId, instanceResourceInfoList);
}
} else {
List<InstanceResourceInfoNode> nodeList = new ArrayList<>();
synchronized (nodeIdToInstanceResourceInfoMap) {
nodeList.addAll(nodeIdToInstanceResourceInfoMap.get(nodeId));
}
for (InstanceResourceInfoNode node : nodeList) {
switch (node.getInstanceNodeContext()) {
// case IDLE:
// node.setCpuUsage(model.getIdle());
// break;
case NODE_CPU_USAGE:
node.setCpuUsage(model.getNodeCPUusage(), model.getOtherProcessCpuUsage(), model.getIdle());
break;
// case OTHER_PROCESSES:
// node.setCpuUsage(model.getOtherProcessCpuUsage());
// break;
case NODE_RAM_USAGE:
// no need to update total node ram as it won't change.
node.setRam(model.getNodeRAMUsage());
break;
// case TOTAL_NODE_RAM:
// break;
default:
log.info("Wrong context of InstanceResourceInfoNode");
break;
}
}
}
synchronized (nodeIdToInstanceResourceInfoMap) {
result.addAll(nodeIdToRceNodeMap.get(nodeId));
result.addAll(nodeIdToInstanceResourceInfoMap.get(nodeId));
}
return result.toArray();
}
private Object[] createRceNodeFolderContent(Object parentNode) {
RceNode rce = (RceNode) parentNode;
List<ProcessInformation> childList = rce.getChildren();
List<Object> result = new ArrayList<>(childList.size());
for (ProcessInformation child : childList) {
ProcessInfoNode processInfoNode = new ProcessInfoNode(parentNode, child);
result.add(processInfoNode);
}
return result.toArray();
}
private Object[] createProcessInfoNodeContent(Object parentNode) {
ProcessInfoNode processInfoNode = (ProcessInfoNode) parentNode;
List<ProcessInformation> childList = processInfoNode.getChildren();
List<Object> result = new ArrayList<>(childList.size());
for (ProcessInformation child : childList) {
ProcessInfoNode newProcessInfoNode = new ProcessInfoNode(parentNode, child);
result.add(newProcessInfoNode);
}
return result.toArray();
}
private ITreeViewerListener getTreeListener() {
return new ITreeViewerListener() {
@Override
public void treeExpanded(TreeExpansionEvent expanded) {
Object element = expanded.getElement();
if (element instanceof MonitoringDataFolderRootNode) {
startSystemMonitoring(element);
} else {
checkChildrenForSystemMonitoring(true, element);
}
}
@Override
public void treeCollapsed(TreeExpansionEvent collapsed) {
Object element = collapsed.getElement();
if (element instanceof MonitoringDataFolderRootNode) {
stopSystemMonitoring((MonitoringDataFolderRootNode) element);
} else {
checkChildrenForSystemMonitoring(false, element);
}
}
/**
* Checks for an element of the network tree, if a direct or indirect child of this element is an instance of
* {@link MonitoringDataFolderRootNode} and starts or stops the system monitoring of the corresponding network instance if the
* node became visible respectively invisible in the network tree.
*
* @param expanding True, if the node was expanded by the user. False, otherwise.
* @param element The element of the network tree whose state changed.
*/
private void checkChildrenForSystemMonitoring(boolean expanding, Object element) {
IContentProvider tmpProvider = treeViewer.getContentProvider();
if (tmpProvider instanceof ITreeContentProvider) {
NetworkViewContentProvider provider = (NetworkViewContentProvider) tmpProvider;
Stack<Object> children = new Stack<Object>();
children.push(element);
while (!children.isEmpty()) {
Object child = children.pop();
if (child instanceof MonitoringDataFolderRootNode) {
if (treeViewer.getExpandedState(child)) {
if (expanding) {
startSystemMonitoring(child);
} else {
stopSystemMonitoring((MonitoringDataFolderRootNode) child);
}
}
} else if (!(child instanceof SelfRenderingNetworkViewNode)) {
// add further children to the stack if they are expanded
if (provider.hasChildren(child)) {
for (Object tmpChild : provider.getChildren(child)) {
if (treeViewer.getExpandedState(tmpChild)) {
children.add(tmpChild);
}
}
}
}
}
} else {
log.debug("The current content provider is not an instance of ITreeContentProvider");
}
}
private void stopSystemMonitoring(MonitoringDataFolderRootNode element) {
final InstanceNodeSessionId nodeId = (element).getInstanceNode().getNode().getNodeId();
pollingManager.cancelPollingTask(nodeId);
synchronized (nodeIdToInstanceResourceInfoMap) {
nodeIdToInstanceResourceInfoMap.clear();
nodeIdToRceNodeMap.clear();
}
}
private void startSystemMonitoring(Object element) {
final InstanceNodeSessionId node = ((MonitoringDataFolderRootNode) element).getInstanceNode().getNode().getNodeId();
// TODO check: this looks like a (minor) memory leak; the map is never reduced - misc_ro, Nov 2015
idToNodeMap.put(node, (ContributedNetworkViewNode) element);
if (node != null) {
pollingManager.startPollingTask(node, new SystemMonitoringDataSnapshotListener() {
@Override
public void onMonitoringDataChanged(final FullSystemAndProcessDataSnapshot monitoringModel) {
if (display.isDisposed()) {
pollingManager.cancelPollingTask(node);
return;
}
display.asyncExec(new Runnable() {
@Override
public void run() {
currentModel.monitoringDataModelMap.put(node, monitoringModel);
if (treeViewer.getControl().isDisposed()) {
pollingManager.cancelPollingTask(node);
return;
}
final ContributedNetworkViewNode monitoringRootElementForInstance = idToNodeMap.get(node);
if (monitoringRootElementForInstance != null) {
treeViewer.refresh(monitoringRootElementForInstance, true);
} else {
log.debug("Root element is null for node " + node + " - skipping refresh");
}
ContributedNetworkViewNode expansionNode = expansionsMap.get(node);
if (expansionNode != null) {
treeViewer.expandToLevel(expansionNode, TreeViewer.ALL_LEVELS);
} else {
// this will currently happen most of the time until fixed - misc_ro
log.debug("Expansion node is null for node " + node + " - skipping auto-expansion");
}
}
});
}
});
}
}
};
}
private void registerChangeListeners() {
servicePublisher.registerService(NetworkTopologyChangeListener.class, new NetworkTopologyChangeListenerAdapter() {
@Override
public void onReachableNodesChanged(Set<InstanceNodeSessionId> reachableNodes, Set<InstanceNodeSessionId> addedNodes,
Set<InstanceNodeSessionId> removedNodes) {
synchronized (nodeIdToInstanceResourceInfoMap) {
for (InstanceNodeSessionId removedNode : removedNodes) {
if (nodeIdToInstanceResourceInfoMap.containsKey(removedNode)) {
nodeIdToInstanceResourceInfoMap.remove(removedNode);
}
if (nodeIdToRceNodeMap.containsKey(removedNode)) {
nodeIdToRceNodeMap.remove(removedNode);
}
}
}
pollingManager.cancelPollingTasks(removedNodes);
}
});
}
}