use of org.knime.core.node.workflow.WorkflowContext in project knime-core by knime.
the class ChangeMetaNodeLinkAction method internalCalculateEnabled.
/**
* @return true, if underlying model instance of <code>WorkflowManager</code>, otherwise false
*/
@Override
protected boolean internalCalculateEnabled() {
NodeContainerEditPart[] nodes = getSelectedParts(NodeContainerEditPart.class);
if (nodes.length != 1) {
return false;
}
NodeContainerUI nc = nodes[0].getNodeContainer();
if (!(nc instanceof WorkflowManagerUI)) {
return false;
}
WorkflowManagerUI metaNode = (WorkflowManagerUI) nc;
if (!Role.Link.equals(unwrapWFM(metaNode).getTemplateInformation().getRole()) || metaNode.getParent().isWriteProtected()) {
// metanode must be linked and parent must not forbid the change
return false;
}
// we can reconfigure the template link - but only if template and flow are in the same mountpoint
URI targetURI = unwrapWFM(metaNode).getTemplateInformation().getSourceURI();
try {
if (ResolverUtil.isMountpointRelativeURL(targetURI) || ResolverUtil.isWorkflowRelativeURL(targetURI)) {
return true;
}
} catch (IOException e) {
return false;
}
// we can change absolute links if the mount points of flow and template are the same
AbstractContentProvider workflowMountPoint = null;
WorkflowContext wfc = metaNode.getProjectWFM().getContext();
LocalExplorerFileStore fs = ExplorerFileSystem.INSTANCE.fromLocalFile(wfc.getMountpointRoot());
if (fs != null) {
workflowMountPoint = fs.getContentProvider();
}
if (workflowMountPoint == null) {
return false;
}
AbstractExplorerFileStore targetfs = ExplorerFileSystem.INSTANCE.getStore(targetURI);
if (targetfs == null) {
return false;
}
return workflowMountPoint.equals(targetfs.getContentProvider());
}
use of org.knime.core.node.workflow.WorkflowContext in project knime-core by knime.
the class ChangeSubNodeLinkAction method internalCalculateEnabled.
/**
* @return true, if underlying model instance of <code>WorkflowManager</code>, otherwise false
*/
@Override
protected boolean internalCalculateEnabled() {
NodeContainerEditPart[] nodes = getSelectedParts(NodeContainerEditPart.class);
if (nodes.length != 1) {
return false;
}
NodeContainer nc = Wrapper.unwrapNC(nodes[0].getNodeContainer());
if (!(nc instanceof SubNodeContainer)) {
return false;
}
SubNodeContainer subNode = (SubNodeContainer) nc;
if (!Role.Link.equals(subNode.getTemplateInformation().getRole()) || subNode.getParent().isWriteProtected()) {
// sub node must be linked and parent must not forbid the change
return false;
}
// we can reconfigure the template link - but only if template and flow are in the same mountpoint
URI targetURI = subNode.getTemplateInformation().getSourceURI();
try {
if (ResolverUtil.isMountpointRelativeURL(targetURI) || ResolverUtil.isWorkflowRelativeURL(targetURI)) {
return true;
}
} catch (IOException e) {
return false;
}
// we can change absolute links if the mount points of flow and template are the same
AbstractContentProvider workflowMountPoint = null;
WorkflowContext wfc = subNode.getProjectWFM().getContext();
LocalExplorerFileStore fs = ExplorerFileSystem.INSTANCE.fromLocalFile(wfc.getMountpointRoot());
if (fs != null) {
workflowMountPoint = fs.getContentProvider();
}
if (workflowMountPoint == null) {
return false;
}
AbstractExplorerFileStore targetfs = ExplorerFileSystem.INSTANCE.getStore(targetURI);
if (targetfs == null) {
return false;
}
return workflowMountPoint.equals(targetfs.getContentProvider());
}
use of org.knime.core.node.workflow.WorkflowContext in project knime-core by knime.
the class WorkflowEditor method doSaveAs.
/**
* {@inheritDoc}
*/
@Override
public void doSaveAs() {
if (m_parentEditor != null) {
// parent does it if this is a metanode editor
m_parentEditor.doSaveAs();
return;
}
URI fileResource = m_fileResource;
Display display = Display.getDefault();
Shell activeShell = display.getActiveShell();
if (fileResource == null) {
MessageDialog.openError(activeShell, "Workflow file resource", "Could not determine the save location to the workflow.");
return;
}
File workflowDir = new File(fileResource);
// Only continue if no other editor to this workflow is open
if (isOtherEditorToWorkflowOpen(workflowDir.toURI())) {
MessageDialog.openError(activeShell, "\"Save As...\" not available", "\"Save As...\" is not possible while another editor to this workflow is open.");
return;
}
OverwriteAndMergeInfo newLocationInfo = getNewLocation(fileResource, isTempRemoteWorkflowEditor());
if (newLocationInfo == null) {
// user canceled
return;
}
AbstractExplorerFileStore newWorkflowDir;
try {
newWorkflowDir = ExplorerFileSystem.INSTANCE.getStore(new URI(newLocationInfo.getNewName()));
} catch (URISyntaxException e2) {
LOGGER.error("Unable to create a URI from the selected destination: " + e2.getMessage() + " Canceling the SaveAs.");
MessageDialog.openError(getSite().getShell(), "Internal Error", "Unable to create a URI from the selected destination. \n" + e2.getMessage() + "\nCanceling the SaveAs.");
return;
}
if (newLocationInfo.createSnapshot()) {
try {
((RemoteExplorerFileStore) newWorkflowDir).createSnapshot(newLocationInfo.getComment());
} catch (CoreException e) {
String msg = "Unable to create the desired snapshot before overwriting the workflow:\n" + e.getMessage() + "\n\nCanceling the upload!";
LOGGER.error("Unable to create the desired snapshot before overwriting the workflow: " + e.getMessage() + " Upload canceled!", e);
MessageDialog.openError(getSite().getShell(), "Server Error", msg);
return;
}
}
if (newWorkflowDir instanceof RemoteExplorerFileStore) {
// selected a remote location: save + upload
if (isDirty()) {
saveTo(m_fileResource, new NullProgressMonitor(), true, null);
}
AbstractExplorerFileStore localFS = getFileStore(fileResource);
if (localFS == null || !(localFS instanceof LocalExplorerFileStore)) {
LOGGER.error("Unable to resolve current workflow location. Flow not uploaded!");
return;
}
try {
m_workflowCanBeDeleted.acquire();
newWorkflowDir.getContentProvider().performUploadAsync((LocalExplorerFileStore) localFS, (RemoteExplorerFileStore) newWorkflowDir, /*deleteSource=*/
false, false, t -> m_workflowCanBeDeleted.release());
} catch (CoreException | InterruptedException e) {
String msg = "\"Save As...\" failed to upload the workflow to the selected remote location\n(" + e.getMessage() + ")";
LOGGER.error(msg, e);
MessageDialog.openError(activeShell, "\"Save As...\" failed.", msg);
}
// no need to change any registered locations as this was a save+upload (didn't change flow location)
} else {
// this is messy. Some methods want the URI with the folder, others the file store denoting workflow.knime
AbstractExplorerFileStore newWorkflowFile = newWorkflowDir.getChild(WorkflowPersistor.WORKFLOW_FILE);
File localNewWorkflowDir = null;
try {
localNewWorkflowDir = newWorkflowDir.toLocalFile();
} catch (CoreException e1) {
LOGGER.error("Unable to resolve selection to local file path: " + e1.getMessage(), e1);
return;
}
File mountPointRoot = null;
try {
mountPointRoot = newWorkflowDir.getContentProvider().getFileStore("/").toLocalFile();
} catch (CoreException ex) {
LOGGER.warn("Could not determine mount point root for " + newWorkflowDir + ": " + ex.getMessage(), ex);
}
WorkflowContext context = new WorkflowContext.Factory(m_manager.getContext()).setCurrentLocation(localNewWorkflowDir).setMountpointRoot(mountPointRoot).setMountpointURI(newWorkflowDir.toURI()).createContext();
saveTo(localNewWorkflowDir.toURI(), new NullProgressMonitor(), true, context);
setInput(new FileStoreEditorInput(newWorkflowFile));
if (newWorkflowDir.getParent() != null) {
newWorkflowDir.getParent().refresh();
}
registerProject(localNewWorkflowDir);
}
}
use of org.knime.core.node.workflow.WorkflowContext in project knime-core by knime.
the class SandboxedNodeCreator method createSandbox.
/**
* Creates that temporary mini workflow that is executed remotely on the cluster/stream executor.
* The returned value should be {@link SandboxedNode#close()} when done (using try-with-resources). After this
* method is called no other set-method should be called.
*
* @param exec for progress/cancelation
* @return the index of the node that represents this node (the node to execute) in the temporary mini workflow
* @throws InvalidSettingsException
* @throws IOException
* @throws CanceledExecutionException
* @throws LockFailedException
* @throws InterruptedException
*/
public SandboxedNode createSandbox(final ExecutionMonitor exec) throws InvalidSettingsException, IOException, CanceledExecutionException, LockFailedException, InterruptedException {
exec.setMessage("Creating virtual workflow");
final WorkflowManager parent = m_nc.getParent();
// derive workflow context via NodeContext as the parent could only a be a metanode in a metanode...
final WorkflowContext origContext = NodeContext.getContext().getWorkflowManager().getContext();
WorkflowContext.Factory ctxFactory;
// (specifically reading knime://knime.workflow files)
if (!m_copyDataIntoNewContext) {
ctxFactory = new WorkflowContext.Factory(origContext);
if (m_localWorkflowDir != null) {
ctxFactory.setOriginalLocation(origContext.getCurrentLocation()).setCurrentLocation(m_localWorkflowDir);
}
} else if (m_localWorkflowDir != null) {
ctxFactory = new WorkflowContext.Factory(m_localWorkflowDir);
} else {
ctxFactory = new WorkflowContext.Factory(FileUtil.createTempDir("sandbox-" + m_nc.getNameWithID()));
}
// We have to use the same location for the temporary files
ctxFactory.setTempLocation(origContext.getTempLocation());
origContext.getMountpointURI().ifPresent(u -> ctxFactory.setMountpointURI(u));
WorkflowCreationHelper creationHelper = new WorkflowCreationHelper();
creationHelper.setWorkflowContext(ctxFactory.createContext());
if (!m_copyDataIntoNewContext) {
creationHelper.setDataHandlers(parent.getGlobalTableRepository(), parent.getFileStoreHandlerRepository());
}
WorkflowManager tempWFM = m_rootWFM.createAndAddProject("Sandbox Exec on " + m_nc.getNameWithID(), creationHelper);
// Add the workflow variables
List<FlowVariable> workflowVariables = parent.getProjectWFM().getWorkflowVariables();
tempWFM.addWorkflowVariables(true, workflowVariables.toArray(new FlowVariable[workflowVariables.size()]));
// update credentials store of the workflow
CredentialsStore cs = tempWFM.getCredentialsStore();
workflowVariables.stream().filter(f -> f.getType().equals(FlowVariable.Type.CREDENTIALS)).filter(f -> !cs.contains(f.getName())).forEach(cs::addFromFlowVariable);
final int inCnt = m_inData.length;
// port object IDs in static port object map, one entry for
// each connected input (no value for unconnected optional inputs)
List<Integer> portObjectRepositoryIDs = new ArrayList<Integer>(inCnt);
try {
NodeID[] ins = new NodeID[inCnt];
for (int i = 0; i < inCnt; i++) {
final PortObject in = m_inData[i];
final NodeInPort inPort = m_nc.getInPort(i);
final PortType portType = inPort.getPortType();
if (in == null) {
// unconnected optional input
CheckUtils.checkState(portType.isOptional(), "No data at port %d, although port is mandatory (port type %s)", i, portType.getName());
continue;
}
int portObjectRepositoryID = PortObjectRepository.add(in);
portObjectRepositoryIDs.add(portObjectRepositoryID);
boolean isTable = BufferedDataTable.TYPE.equals(portType);
NodeID inID = tempWFM.createAndAddNode(isTable ? TABLE_READ_NODE_FACTORY : OBJECT_READ_NODE_FACTORY);
NodeSettings s = new NodeSettings("temp_data_in");
tempWFM.saveNodeSettings(inID, s);
List<FlowVariable> flowVars = getFlowVariablesOnPort(i);
PortObjectInNodeModel.setInputNodeSettings(s, portObjectRepositoryID, flowVars, m_copyDataIntoNewContext);
// update credentials store of the workflow
flowVars.stream().filter(f -> f.getType().equals(FlowVariable.Type.CREDENTIALS)).filter(f -> !cs.contains(f.getName())).forEach(cs::addFromFlowVariable);
tempWFM.loadNodeSettings(inID, s);
ins[i] = inID;
}
// execute inPort object nodes to store the input data in them
if (ins.length > 0 && !tempWFM.executeAllAndWaitUntilDoneInterruptibly()) {
String error = "Unable to execute virtual workflow, status sent to log facilities";
LOGGER.debug(error + ":");
LOGGER.debug(tempWFM.toString());
throw new RuntimeException(error);
}
// add the target node to the workflow
WorkflowCopyContent.Builder content = WorkflowCopyContent.builder();
content.setNodeIDs(m_nc.getID());
final NodeID targetNodeID = tempWFM.copyFromAndPasteHere(parent, content.build()).getNodeIDs()[0];
NodeContainer targetNode = tempWFM.getNodeContainer(targetNodeID);
// connect target node to inPort object nodes, skipping unconnected (optional) inputs
IntStream.range(0, inCnt).filter(i -> ins[i] != null).forEach(i -> tempWFM.addConnection(ins[i], 1, targetNodeID, i));
if (m_forwardConnectionProgressEvents) {
setupConnectionProgressEventListeners(m_nc, targetNode);
}
// copy the existing tables into the (meta) node (e.g. an executed file reader that's necessary
// for other nodes to execute)
exec.setMessage("Copying tables into temp flow");
NodeContainerExecutionResult origResult = m_nc.createExecutionResult(exec);
ExecutionMonitor copyExec = exec.createSubProgress(0.0);
copyExistingTablesIntoSandboxContainer(origResult, m_nc, targetNode, copyExec, m_copyDataIntoNewContext);
CopyContentIntoTempFlowNodeExecutionJobManager copyDataIntoTmpFlow = new CopyContentIntoTempFlowNodeExecutionJobManager(origResult);
NodeExecutionJobManager oldJobManager = targetNode.getJobManager();
tempWFM.setJobManager(targetNodeID, copyDataIntoTmpFlow);
tempWFM.executeAllAndWaitUntilDoneInterruptibly();
tempWFM.setJobManager(targetNodeID, oldJobManager);
// do not use the cluster executor on the cluster...
tempWFM.setJobManager(targetNodeID, NodeExecutionJobManagerPool.getDefaultJobManagerFactory().getInstance());
if (!m_copyDataIntoNewContext) {
copyFileStoreHandlerReference(targetNode, parent, false);
}
// save workflow in the local job dir
if (m_localWorkflowDir != null) {
tempWFM.save(m_localWorkflowDir, exec, true);
deepCopyFilesInWorkflowDir(m_nc, tempWFM);
}
return new SandboxedNode(tempWFM, targetNodeID);
} finally {
portObjectRepositoryIDs.stream().forEach(PortObjectRepository::remove);
}
}
use of org.knime.core.node.workflow.WorkflowContext in project knime-core by knime.
the class CreateTempDirectoryNodeModel method computeFileName.
private File computeFileName(final String id) {
File rootDir = null;
// get the flow's tmp dir from its context
NodeContext nodeContext = NodeContext.getContext();
if (nodeContext != null) {
WorkflowContext workflowContext = nodeContext.getWorkflowManager().getContext();
if (workflowContext != null) {
rootDir = workflowContext.getTempLocation();
}
}
if (rootDir == null) {
// use the standard tmp dir then.
rootDir = new File(KNIMEConstants.getKNIMETempDir());
}
String baseName = m_configuration.getBaseName();
return new File(rootDir, baseName + id);
}
Aggregations