use of org.knime.core.node.workflow.WorkflowPersistor.NodeContainerTemplateLinkUpdateResult in project knime-core by knime.
the class WorkflowManager method updateMetaNodeLinkWithCache.
/**
* Implementation of {@link #updateMetaNodeLink(NodeID, ExecutionMonitor, WorkflowLoadHelper)} with an extra cache
* argument.
*
* @param visitedTemplateMap The map to avoid loading duplicate
*/
private NodeContainerTemplateLinkUpdateResult updateMetaNodeLinkWithCache(final NodeID id, final ExecutionMonitor exec, final WorkflowLoadHelper loadHelper, final Map<URI, NodeContainerTemplate> visitedTemplateMap) throws CanceledExecutionException {
final NodeContainerTemplateLinkUpdateResult loadRes = new NodeContainerTemplateLinkUpdateResult("Update node link \"" + getNameWithID() + "\"");
NodeContainer nc = getNodeContainer(id);
if (!(nc instanceof NodeContainerTemplate)) {
throw new IllegalArgumentException("Node \"" + nc.getNameWithID() + "\" is not a template node (can't update link)");
}
NodeContainerTemplate tnc = (NodeContainerTemplate) nc;
final MetaNodeTemplateInformation tempInfo = tnc.getTemplateInformation();
if (!tempInfo.getRole().equals(Role.Link)) {
loadRes.addError("Node \"" + getNameWithID() + "\" is not a template node link");
return loadRes;
}
try (WorkflowLock lock = lock()) {
boolean needsUpdate;
try {
needsUpdate = checkUpdateMetaNodeLinkWithCache(id, loadHelper, loadRes, visitedTemplateMap, false);
} catch (IOException e2) {
String msg = "Unable to check node update for " + tnc.getNameWithID() + ": " + e2.getMessage();
LOGGER.error(msg, e2);
loadRes.addError(msg);
return loadRes;
}
WorkflowCopyContent.Builder oldContent = WorkflowCopyContent.builder();
oldContent.setNodeIDs(id);
oldContent.setIncludeInOutConnections(true);
WorkflowPersistor copy = copy(true, oldContent.build());
NodeContainerTemplate updatedTemplate = null;
try {
NodeContainerTemplate recursionManager;
if (needsUpdate) {
updatedTemplate = updateNodeTemplateLinkInternal(id, exec, loadHelper, visitedTemplateMap, loadRes);
recursionManager = updatedTemplate;
} else {
// didn't update so this will be its own reference
loadRes.setNCTemplate(tnc);
recursionManager = tnc;
}
recursionManager.updateMetaNodeLinkInternalRecursively(exec, loadHelper, visitedTemplateMap, loadRes);
} catch (Exception e) {
String error = e.getClass().getSimpleName() + " while loading template: " + e.getMessage();
LOGGER.error(error, e);
loadRes.addError(error);
if (updatedTemplate != null) {
removeNode(updatedTemplate.getID());
}
paste(copy);
return loadRes;
}
loadRes.setUndoPersistor(copy);
return loadRes;
}
}
use of org.knime.core.node.workflow.WorkflowPersistor.NodeContainerTemplateLinkUpdateResult in project knime-core by knime.
the class WorkflowManager method updateMetaNodeLinks.
/**
* Update metanode links (recursively finding all metanodes but not updating metanodes in metanodes).
*
* @param lH Load helper.
* @param failOnLoadError If to fail if there errors updating the links
* @param exec Progress monitor
* @return The update summary
* @throws CanceledExecutionException If canceled
* @throws IOException Special errors during update (not accessible)
* @noreference This method is not intended to be referenced by clients.
*/
public NodeContainerTemplateLinkUpdateResult updateMetaNodeLinks(final WorkflowLoadHelper lH, final boolean failOnLoadError, final ExecutionMonitor exec) throws IOException, CanceledExecutionException {
// all linked metanodes that need to be checked.
Map<NodeID, NodeContainerTemplate> linkedMetaNodes = fillLinkedTemplateNodesList(new LinkedHashMap<NodeID, NodeContainerTemplate>(), true, true);
int linksChecked = 0;
int linksUpdated = 0;
NodeContainerTemplateLinkUpdateResult update = new NodeContainerTemplateLinkUpdateResult("Update on " + linkedMetaNodes.size() + " node(s) in " + getNameWithID());
HashMap<URI, NodeContainerTemplate> visitedTemplateMap = new HashMap<URI, NodeContainerTemplate>();
try {
for (NodeContainerTemplate tnc : linkedMetaNodes.values()) {
linksChecked += 1;
WorkflowManager parent = tnc.getParent();
exec.setProgress(linksChecked / (double) linkedMetaNodes.size(), "node " + tnc.getNameWithID());
exec.checkCanceled();
LoadResult checkTemplateResult = new LoadResult("update check");
final boolean updatesAvail = parent.checkUpdateMetaNodeLinkWithCache(tnc.getID(), lH, checkTemplateResult, visitedTemplateMap, true);
if (failOnLoadError && checkTemplateResult.hasErrors()) {
LOGGER.error(checkTemplateResult.getFilteredError("", LoadResultEntryType.Error));
throw new IOException("Error(s) while updating metanode links");
}
if (updatesAvail) {
NodeContainerTemplateLinkUpdateResult loadResult = parent.updateMetaNodeLinkWithCache(tnc.getID(), exec.createSubProgress(1.0 / linkedMetaNodes.size()), lH, visitedTemplateMap);
update.addChildError(loadResult);
linksUpdated += 1;
if (failOnLoadError && loadResult.hasErrors()) {
LOGGER.error(loadResult.getFilteredError("", LoadResultEntryType.Error));
throw new IOException("Error(s) while updating metanode links");
}
}
}
if (linksChecked == 0) {
LOGGER.debug("No metanode links in workflow, nothing updated");
} else {
LOGGER.debug("Workflow contains " + linksChecked + " metanode link(s), " + linksUpdated + " were updated");
}
return update;
} finally {
for (NodeContainerTemplate tempLink : visitedTemplateMap.values()) {
tempLink.getParent().removeNode(tempLink.getID());
}
}
}
use of org.knime.core.node.workflow.WorkflowPersistor.NodeContainerTemplateLinkUpdateResult in project knime-core by knime.
the class WorkflowManager method updateMetaNodeLinkInternalRecursively.
/**
* {@inheritDoc}
*
* @noreference This method is not intended to be referenced by clients.
*/
@Override
public void updateMetaNodeLinkInternalRecursively(final ExecutionMonitor exec, final WorkflowLoadHelper loadHelper, final Map<URI, NodeContainerTemplate> visitedTemplateMap, final NodeContainerTemplateLinkUpdateResult loadRes) throws Exception {
for (NodeID id : m_workflow.createBreadthFirstSortedList(m_workflow.getNodeIDs(), true).keySet()) {
NodeContainer nc = getNodeContainer(id);
if (nc instanceof NodeContainerTemplate) {
NodeContainerTemplate t = (NodeContainerTemplate) nc;
if (t.getTemplateInformation().getRole().equals(Role.Link)) {
final NodeContainerTemplateLinkUpdateResult childResult = new NodeContainerTemplateLinkUpdateResult("Update child link \"" + getNameWithID() + "\"");
t = updateNodeTemplateLinkInternal(t.getID(), exec, loadHelper, visitedTemplateMap, childResult);
}
t.updateMetaNodeLinkInternalRecursively(exec, loadHelper, visitedTemplateMap, loadRes);
}
}
}
use of org.knime.core.node.workflow.WorkflowPersistor.NodeContainerTemplateLinkUpdateResult in project knime-core by knime.
the class BugPE37_subnode_update method testRunAfterUpdate.
/**
* Runs the workflow after updating linked metanodes and expects the 'right' side to be green.
*/
@Test(timeout = 10000L)
public void testRunAfterUpdate() throws Exception {
WorkflowManager manager = getManager();
List<NodeID> linkedMetaNodes = manager.getLinkedMetaNodes(true);
WorkflowLoadHelper lH = new WorkflowLoadHelper(true, manager.getContext());
for (NodeID id : linkedMetaNodes) {
NodeContainerTemplate tnc = (NodeContainerTemplate) manager.findNodeContainer(id);
WorkflowManager parent = tnc.getParent();
Assert.assertThat("No update for " + tnc.getNameWithID(), parent.checkUpdateMetaNodeLink(id, lH), is(true));
}
for (NodeID id : linkedMetaNodes) {
NodeContainerTemplate tnc = (NodeContainerTemplate) manager.findNodeContainer(id);
WorkflowManager parent = tnc.getParent();
Assert.assertThat("No update for " + tnc.getNameWithID(), parent.checkUpdateMetaNodeLink(id, lH), is(true));
Assert.assertThat("Update should be flagged", parent.hasUpdateableMetaNodeLink(id), is(true));
Assert.assertThat("Can't update metanode link", parent.canUpdateMetaNodeLink(id), is(true));
}
for (NodeID id : linkedMetaNodes) {
NodeContainerTemplate tnc = (NodeContainerTemplate) manager.findNodeContainer(id);
WorkflowManager parent = tnc.getParent();
NodeContainerTemplateLinkUpdateResult updateRes = parent.updateMetaNodeLink(id, new ExecutionMonitor(), lH);
Assert.assertThat("Not expected to have errors", updateRes.hasErrors(), is(false));
}
executeAllAndWait();
waitWhileInExecution();
checkStateOfMany(CONFIGURED, m_diffChecker_Before_5, m_diffChecker_Before_8, m_diffChecker_Before_9, m_diffChecker_Before_13);
checkStateOfMany(EXECUTED, m_diffChecker_After_19, m_diffChecker_After_22, m_diffChecker_After_23, m_diffChecker_After_27);
}
use of org.knime.core.node.workflow.WorkflowPersistor.NodeContainerTemplateLinkUpdateResult in project knime-core by knime.
the class UpdateMetaNodeTemplateRunnable method run.
/**
* {@inheritDoc}
*/
@Override
public void run(final IProgressMonitor pm) throws InterruptedException {
m_newIDs = new ArrayList<NodeID>();
m_undoPersistors = new ArrayList<WorkflowPersistor>();
// create progress monitor
ProgressHandler progressHandler = new ProgressHandler(pm, 101, "Updating node links...");
final CheckCancelNodeProgressMonitor progressMonitor = new CheckCancelNodeProgressMonitor(pm);
progressMonitor.addProgressListener(progressHandler);
final Display d = Display.getDefault();
ExecutionMonitor exec = new ExecutionMonitor(progressMonitor);
IStatus[] stats = new IStatus[m_ids.length];
for (int i = 0; i < m_ids.length; i++) {
NodeID id = m_ids[i];
NodeContainerTemplate tnc = (NodeContainerTemplate) m_parentWFM.findNodeContainer(id);
LOGGER.debug("Updating " + tnc.getNameWithID() + " from " + tnc.getTemplateInformation().getSourceURI());
ExecutionMonitor subExec = exec.createSubProgress(1.0 / m_ids.length);
String progMsg = "Node Link \"" + tnc.getNameWithID() + "\"";
exec.setMessage(progMsg);
GUIWorkflowLoadHelper loadHelper = new GUIWorkflowLoadHelper(d, progMsg, null, null, null, true);
NodeContainerTemplateLinkUpdateResult updateMetaNodeLinkResult;
try {
updateMetaNodeLinkResult = tnc.getParent().updateMetaNodeLink(id, subExec, loadHelper);
} catch (CanceledExecutionException e) {
String message = "Node update canceled";
LOGGER.warn(message, e);
throw new InterruptedException(message);
}
WorkflowPersistor p = updateMetaNodeLinkResult.getUndoPersistor();
if (p != null) {
// no error
m_newIDs.add(updateMetaNodeLinkResult.getNCTemplate().getID());
m_undoPersistors.add(p);
}
// metanodes don't have data
// data load errors are unexpected but OK
IStatus status = createStatus(updateMetaNodeLinkResult, true);
subExec.setProgress(1.0);
switch(status.getSeverity()) {
case IStatus.OK:
break;
case IStatus.WARNING:
logPreseveLineBreaks("Warnings during load: " + updateMetaNodeLinkResult.getFilteredError("", LoadResultEntryType.Warning), false);
break;
default:
logPreseveLineBreaks("Errors during load: " + updateMetaNodeLinkResult.getFilteredError("", LoadResultEntryType.Warning), true);
}
stats[i] = status;
}
pm.done();
final IStatus status = createMultiStatus("Update node links", stats);
final String message;
switch(status.getSeverity()) {
case IStatus.OK:
message = "No problems during node link update.";
break;
case IStatus.WARNING:
message = "Warnings during node link update";
break;
default:
message = "Errors during node link update";
}
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
// will not open if status is OK.
ErrorDialog.openError(Display.getDefault().getActiveShell(), "Update Node Links", message, status);
}
});
}
Aggregations