public NodeType findNodeById(String nodeIdentifier) { for (NodeType node : tasks.keySet()) { if (node.getNodeIdentifier().equals(nodeIdentifier)) { return node; } } return null; }
/** * Returns how many threads are available for execution of a given group on a list of nodes. * If returned key is null, this means "unlimited" (i.e. limited only by the node thread pool size). */ @NotNull public static Map<String, Integer> getNodeRestrictions(String group, @NotNull List<NodeType> nodes) { Map<String, Integer> rv = new HashMap<>(); for (NodeType node : nodes) { rv.put(node.getNodeIdentifier(), getNodeLimitation(node, group)); } return rv; }
public String dumpNodeInfo(NodeType node) { return node.getNodeIdentifier() + " (" + node.getHostname() + ")"; }
boolean isCurrentNode(PrismObject<NodeType> node) { return taskManager.getNodeId().equals(node.asObjectable().getNodeIdentifier()); }
/** * Generates an identifier that is used to ensure that this Node object is not (by mistake) overwritten * by another node in cluster. ClusterManager thread periodically checks if this identifier has not been changed. */ private void generateInternalNodeIdentifier(NodeType node) { String id = node.getNodeIdentifier() + ":" + node.getJmxPort() + ":" + Math.round(Math.random() * 10000000000000.0); LOGGER.trace("internal node identifier generated: " + id); node.setInternalNodeIdentifier(id); }
private Collection<String> getNodeIdentifiers(WorkerTasksPerNodeConfigurationType perNodeConfig, OperationResult opResult) throws SchemaException { if (!perNodeConfig.getNodeIdentifier().isEmpty()) { return perNodeConfig.getNodeIdentifier(); } else { SearchResultList<PrismObject<NodeType>> nodes = taskManager.searchObjects(NodeType.class, null, null, opResult); return nodes.stream() .filter(n -> n.asObjectable().getExecutionStatus() == NodeExecutionStatusType.RUNNING) .map(n -> n.asObjectable().getNodeIdentifier()) .collect(Collectors.toSet()); } }
/** * There may be either exactly one non-clustered node (and no other nodes), or clustered nodes only. */ void checkNonClusteredNodes(OperationResult result) { LOGGER.trace("Checking non-clustered nodes."); List<String> clustered = new ArrayList<>(); List<String> nonClustered = new ArrayList<>(); List<PrismObject<NodeType>> allNodes = clusterManager.getAllNodes(result); for (PrismObject<NodeType> nodePrism : allNodes) { NodeType n = nodePrism.asObjectable(); if (isUp(n)) { if (n.isClustered()) { clustered.add(n.getNodeIdentifier()); } else { nonClustered.add(n.getNodeIdentifier()); } } } LOGGER.trace("Clustered nodes: " + clustered); LOGGER.trace("Non-clustered nodes: " + nonClustered); int all = clustered.size() + nonClustered.size(); if (!taskManager.getConfiguration().isClustered() && all > 1) { LOGGER.error("This node is a non-clustered one, mixed with other nodes. In this system, there are " + nonClustered.size() + " non-clustered nodes (" + nonClustered + ") and " + clustered.size() + " clustered ones (" + clustered + "). Stopping this node."); registerNodeError(NodeErrorStatusType.NON_CLUSTERED_NODE_WITH_OTHERS); } }
public static void copyFromJAXB(NodeType jaxb, RNode repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { copyObjectInformationFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); repo.setNodeIdentifier(jaxb.getNodeIdentifier()); } }
private QuartzSchedulerMBean getSchedulerBean(NodeType node, Holder<JMXConnector> connectorHolder, OperationResult result) { String nodeName = node.getNodeIdentifier(); String address = node.getHostname() + ":" + node.getJmxPort(); try { JMXConnector connector = connectViaJmx(address); connectorHolder.setValue(connector); MBeanServerConnection serverConnection = connector.getMBeanServerConnection(); QuartzSchedulerMBean bean = getMBeanProxy(nodeName, serverConnection); if (bean == null) { String message = "Cannot connect to the Quartz Scheduler bean at remote node " + nodeName + " at " + address + " because the JMX object for scheduler cannot be found on that node."; LOGGER.warn("{}", message); result.recordFatalError(message); } return bean; } catch (IOException|MalformedObjectNameException e) { LoggingUtils.logUnexpectedException(LOGGER, "Cannot connect to the quartz scheduler bean at remote node {} at {}", e, nodeName, address); result.recordFatalError("Cannot connect to the quartz scheduler bean at remote node " + nodeName + " at " + address + ": " + e.getMessage(), e); return null; } }
public void redirectTaskToNode(@NotNull Task task, @NotNull NodeType node, @NotNull OperationResult result) { LOGGER.trace("Trying to schedule task {} on {}", task, node.getNodeIdentifier()); Holder<JMXConnector> connectorHolder = new Holder<>(); try { QuartzSchedulerMBean mbeanProxy = getSchedulerBean(node, connectorHolder, result); if (mbeanProxy != null) { try { createStarterJobIfNeeded(); mbeanProxy.triggerJob(STARTER_JOB_KEY.getName(), STARTER_JOB_KEY.getGroup(), Collections.singletonMap(JobStarter.TASK_OID, task.getOid())); LOGGER.debug("Successfully requested start of " + task + " at " + getClusterManager().dumpNodeInfo(node)); result.recordSuccessIfUnknown(); } catch (Exception e) { // necessary because of mbeanProxy String message = "Cannot schedule " + task + " at " + getClusterManager().dumpNodeInfo(node); LoggingUtils.logUnexpectedException(LOGGER, message, e); result.recordFatalError(message + ":" + e.getMessage(), e); } } else { LOGGER.warn("Couldn't obtain Quartz MBean so couldn't reschedule task {} on {}", task, node.getNodeIdentifier()); } } finally { closeJmxConnection(connectorHolder, getClusterManager().dumpNodeInfo(node)); } }
String nodeName = node.getNodeIdentifier(); String address = node.getHostname() + ":" + node.getJmxPort();
private void addNodeAndTaskInformation(ClusterStatusInformation info, PrismObject<NodeType> node, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(ExecutionManager.class.getName() + ".addNodeAndTaskInformation"); result.addParam("node", node); if (isCurrentNode(node)) { LOGGER.trace("Getting node and task info from the current node ({})", node.asObjectable().getNodeIdentifier()); List<ClusterStatusInformation.TaskInfo> taskInfoList = new ArrayList<>(); Set<Task> tasks = localNodeManager.getLocallyRunningTasks(result); for (Task task : tasks) { taskInfoList.add(new ClusterStatusInformation.TaskInfo(task.getOid())); } node.asObjectable().setExecutionStatus(localNodeManager.getLocalNodeExecutionStatus()); node.asObjectable().setErrorStatus(taskManager.getLocalNodeErrorStatus()); info.addNodeAndTaskInfo(node.asObjectable(), taskInfoList); } else { // if remote LOGGER.debug("Getting running task info from remote node ({}, {})", node.asObjectable().getNodeIdentifier(), node.asObjectable().getHostname()); remoteNodesManager.addNodeStatusFromRemoteNode(info, node, result); } result.recordSuccessIfUnknown(); }
String nodeName = node.getNodeIdentifier(); String address = node.getHostname() + ":" + node.getJmxPort();
private void stopTaskRun(Task task, ClusterStatusInformation csi, boolean clusterwide, OperationResult parentResult) { String oid = task.getOid(); LOGGER.trace("stopTaskRun: task = {}, csi = {}, clusterwide = {}", task, csi, clusterwide); if (!clusterwide) { stopLocalTaskIfRunning(oid, parentResult); } else { NodeType node = csi.findNodeInfoForTask(task.getOid()); if (node != null) { if (taskManager.getClusterManager().isCurrentNode(node.getNodeIdentifier())) { stopLocalTaskIfRunning(oid, parentResult); } else { remoteNodesManager.stopRemoteTaskRun(task.getOid(), node, parentResult); } } } }
private TaskType addTransientTaskInformation(PrismObject<TaskType> taskInRepository, ClusterStatusInformation clusterStatusInformation, boolean retrieveNextRunStartTime, boolean retrieveRetryTime, boolean retrieveNodeAsObserved, OperationResult result) { Validate.notNull(taskInRepository.getOid(), "Task OID is null"); TaskType taskInResult = taskInRepository.asObjectable(); if (clusterStatusInformation != null && retrieveNodeAsObserved) { NodeType runsAt = clusterStatusInformation.findNodeInfoForTask(taskInResult.getOid()); if (runsAt != null) { taskInResult.setNodeAsObserved(runsAt.getNodeIdentifier()); } } if (retrieveNextRunStartTime || retrieveRetryTime) { NextStartTimes times = getNextStartTimes(taskInResult.getOid(), retrieveNextRunStartTime, retrieveRetryTime, result); if (retrieveNextRunStartTime && times.nextScheduledRun != null) { taskInResult.setNextRunStartTimestamp(XmlTypeConverter.createXMLGregorianCalendar(times.nextScheduledRun)); } if (retrieveRetryTime && times.nextRetry != null) { taskInResult.setNextRetryTimestamp(XmlTypeConverter.createXMLGregorianCalendar(times.nextRetry)); } } Long stalledSince = stalledTasksWatcher.getStalledSinceForTask(taskInResult); if (stalledSince != null) { taskInResult.setStalledSince(XmlTypeConverter.createXMLGregorianCalendar(stalledSince)); } return taskInResult; }
void stopRemoteTaskRun(String oid, NodeType node, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(RemoteNodesManager.class.getName() + ".stopRemoteTaskRun"); result.addParam("oid", oid); result.addParam("node", node.toString()); LOGGER.debug("Interrupting task " + oid + " running at " + getClusterManager().dumpNodeInfo(node)); String nodeName = node.getNodeIdentifier(); String address = node.getHostname() + ":" + node.getJmxPort(); Holder<JMXConnector> connectorHolder = new Holder<>(); try { QuartzSchedulerMBean mbeanProxy = getSchedulerBean(node, connectorHolder, result); if (mbeanProxy != null) { try { mbeanProxy.interruptJob(oid, Scheduler.DEFAULT_GROUP); LOGGER.debug("Successfully signalled shutdown to task " + oid + " running at " + getClusterManager().dumpNodeInfo(node)); result.recordSuccessIfUnknown(); } catch (Exception e) { // necessary because of mbeanProxy String message = "Cannot signal task "+oid+" interruption to remote node "+nodeName+" at "+address; LoggingUtils.logUnexpectedException(LOGGER, message, e); result.recordFatalError(message + ":" + e.getMessage(), e); } } } finally { closeJmxConnection(connectorHolder, address); } }
if (StringUtils.isBlank(httpUrlPattern)) { LOGGER.warn("Node URL nor intra-cluster URL pattern specified, skipping cache clearing for node {}", nodeType.getNodeIdentifier()); continue;
NodeType returnedNode = nodeInRepositoryPrism.asObjectable(); NodeType nodeRuntimeInfo = clusterStatusInformation.findNodeById(returnedNode.getNodeIdentifier()); if (nodeRuntimeInfo != null) { returnedNode.setExecutionStatus(nodeRuntimeInfo.getExecutionStatus());
String nodeIdentifier = nodeInfo.getNodeIdentifier(); String address = nodeInfo.getHostname() + ":" + nodeInfo.getJmxPort();
LOGGER.info("Registering this node in the repository as " + nodeToBe.getNodeIdentifier() + " at " + nodeToBe.getHostname() + ":" + nodeToBe.getJmxPort());