/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.resourcemanager.rmnode; import java.io.Serializable; import java.util.Date; import org.ow2.proactive.jmx.naming.JMXTransportProtocol; import org.ow2.proactive.resourcemanager.authentication.Client; import org.ow2.proactive.resourcemanager.common.NodeState; import org.ow2.proactive.resourcemanager.common.event.RMEventType; import org.ow2.proactive.resourcemanager.common.event.RMNodeDescriptor; import org.ow2.proactive.resourcemanager.common.event.RMNodeEvent; import org.ow2.proactive.resourcemanager.nodesource.NodeSource; /** * Defines abstractions common to all RM node implementations. * * @author ActiveEon Team * @since 16/01/17 * * @see RMDeployingNode * @see RMNodeImpl */ public abstract class AbstractRMNode implements RMNode, Serializable { /** The add event */ protected RMNodeEvent addEvent; /** * Status associated to a ProActive Node. * When a Node is locked, it is no longer eligible for Tasks execution. * A ProActive node can be locked whatever its state is. */ protected boolean isLocked; /** The last event */ protected RMNodeEvent lastEvent; /** * Defines who has locked the node. * This field has a meaning when {@code isLocked} is {@code true} only. */ protected Client lockedBy; /** * Defines the time at which the node has been locked. * This field has a meaning when {@code isLocked} is {@code true} only. */ protected long lockTime = -1; /** Name of the node */ protected final String nodeName; /** {@link NodeSource} Stub that handles the node */ protected NodeSource nodeSource; /** Name of the NodeSource that handles the RMNode */ protected String nodeSourceName; /** URL of the node, considered as its unique ID */ private final String nodeURL; /** client registered the node in the resource manager */ protected Client provider; /** State of the node */ protected NodeState state; /** Time stamp of the latest state change */ protected long stateChangeTime; public AbstractRMNode() { this.nodeName = null; this.nodeURL = null; } public AbstractRMNode(NodeSource nodeSource, String nodeName, String nodeURL, Client provider) { this.addEvent = null; this.lastEvent = null; this.nodeSource = nodeSource; if (nodeSource != null) { this.nodeSourceName = nodeSource.getName(); } this.nodeName = nodeName; this.nodeURL = nodeURL; this.provider = provider; } public void copyLockStatusFrom(RMNode node) { if (this == node || isLocked != node.isLocked()) { isLocked = node.isLocked(); lockedBy = node.getLockedBy(); lockTime = node.getLockTime(); } } /** * {@inheritDoc} */ @Override public RMNodeEvent createNodeEvent() { return createNodeEvent(null, null, null); } /** * {@inheritDoc} */ @Override public RMNodeEvent createNodeEvent(RMEventType eventType, NodeState previousNodeState, String initiator) { RMNodeEvent rmNodeEvent = new RMNodeEvent(toNodeDescriptor(), eventType, previousNodeState, initiator); // The rm node always keeps track on its last event, this is needed for rm node events logic if (eventType != null) { if (eventType == RMEventType.NODE_ADDED) { this.setAddEvent(rmNodeEvent); } this.setLastEvent(rmNodeEvent); } return rmNodeEvent; } protected void changeState(NodeState newState) { this.state = newState; this.stateChangeTime = System.currentTimeMillis(); } /** * {@inheritDoc} */ @Override public void lock(Client client) { this.isLocked = true; this.lockTime = System.currentTimeMillis(); this.lockedBy = client; } /** * {@inheritDoc} */ @Override public void unlock(Client client) { this.isLocked = false; this.lockTime = -1; this.lockedBy = null; } /** * {@inheritDoc} */ @Override public RMNodeEvent getAddEvent() { return addEvent; } /** * {@inheritDoc} */ @Override public RMNodeEvent getLastEvent() { return lastEvent; } /** * {@inheritDoc} */ @Override public long getLockTime() { return lockTime; } /** * {@inheritDoc} */ @Override public Client getLockedBy() { return lockedBy; } protected String getLockStatus() { String result = "Locked: " + Boolean.toString(isLocked); if (isLocked) { result += " ("; if (lockedBy != null) { result += "by " + lockedBy.getName() + " "; } result += "since " + new Date(lockTime); result += ")"; } result += System.lineSeparator(); return result; } /** * {@inheritDoc} */ @Override public boolean equals(Object rmNode) { return this == rmNode || rmNode instanceof RMNode && this.getNodeURL().equals(((RMNode) rmNode).getNodeURL()); } /** * {@inheritDoc} */ @Override public int hashCode() { return this.getNodeURL().hashCode(); } /** * {@inheritDoc} */ @Override public String getNodeName() { return nodeName; } /** * {@inheritDoc} */ @Override public NodeSource getNodeSource() { return nodeSource; } /** * {@inheritDoc} */ @Override public String getNodeSourceName() { return nodeSourceName; } /** * {@inheritDoc} */ @Override public NodeState getState() { return state; } /** * {@inheritDoc} */ @Override public long getStateChangeTime() { return stateChangeTime; } /** * {@inheritDoc} */ @Override public String getNodeURL() { return nodeURL; } /** * {@inheritDoc} */ @Override public Client getProvider() { return provider; } /** * {@inheritDoc} */ @Override public boolean isLocked() { return isLocked; } /** * {@inheritDoc} */ @Override public void setAddEvent(final RMNodeEvent addEvent) { this.addEvent = addEvent; } /** * {@inheritDoc} */ @Override public void setLastEvent(final RMNodeEvent lastEvent) { this.lastEvent = lastEvent; } /** * {@inheritDoc} */ @Override public void setNodeSource(NodeSource nodeSource) { this.nodeSource = nodeSource; this.nodeSourceName = nodeSource.getName(); } protected RMNodeDescriptor toNodeDescriptor() { RMNodeDescriptor rmNodeDescriptor = new RMNodeDescriptor(); rmNodeDescriptor.setDefaultJMXUrl(getJMXUrl(JMXTransportProtocol.RMI)); rmNodeDescriptor.setDescriptorVMName(getDescriptorVMName()); rmNodeDescriptor.setHostName(getHostName()); rmNodeDescriptor.setLocked(isLocked()); rmNodeDescriptor.setLockedBy(getLockedBy() == null ? null : getLockedBy().getName()); rmNodeDescriptor.setLockTime(getLockTime()); rmNodeDescriptor.setNodeInfo(getNodeInfo()); rmNodeDescriptor.setNodeSourceName(getNodeSourceName()); rmNodeDescriptor.setNodeURL(getNodeURL()); rmNodeDescriptor.setOwnerName(getOwner() == null ? null : getOwner().getName()); rmNodeDescriptor.setProactiveJMXUrl(getJMXUrl(JMXTransportProtocol.RO)); rmNodeDescriptor.setProviderName(getProvider() == null ? null : getProvider().getName()); rmNodeDescriptor.setState(getState()); rmNodeDescriptor.setStateChangeTime(getStateChangeTime()); rmNodeDescriptor.setVNodeName(getVNodeName()); return rmNodeDescriptor; } @Override public String toString() { return getNodeInfo(); } }