From a0e8f9b4d92028975baaba0317899536045804c8 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 28 Apr 2011 14:44:10 +0000 Subject: [PATCH] Manages results in JCR ASSIGNED - bug 17: Generalize agent management and registration beyond JMS https://bugzilla.argeo.org/show_bug.cgi?id=17 git-svn-id: https://svn.argeo.org/slc/trunk@4487 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../META-INF/spring/jcr.xml | 5 + .../org.argeo.slc.client.ui/plugin.xml | 7 + .../client/ui/SlcExecutionPerspective.java | 2 +- .../client/ui/views/JcrProcessListView.java | 5 +- .../client/ui/views/JcrResultListView.java | 210 ++++++++++++++++++ .../META-INF/MANIFEST.MF | 1 + .../META-INF/spring/jcr-osgi.xml | 5 + .../META-INF/spring/jcr.xml | 8 +- .../org/argeo/slc/jcr/SlcJcrConstants.java | 1 + .../java/org/argeo/slc/jcr/SlcJcrUtils.java | 6 + .../main/java/org/argeo/slc/jcr/SlcNames.java | 9 + .../main/java/org/argeo/slc/jcr/SlcTypes.java | 3 + .../slc/jcr/execution/JcrResultListener.java | 154 +++++++++++++ .../main/resources/org/argeo/slc/jcr/slc.cnd | 15 +- 14 files changed, 422 insertions(+), 9 deletions(-) create mode 100644 eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultListView.java create mode 100644 runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrResultListener.java diff --git a/eclipse/plugins/org.argeo.slc.client.ui/META-INF/spring/jcr.xml b/eclipse/plugins/org.argeo.slc.client.ui/META-INF/spring/jcr.xml index 340ae1c78..dccaea56f 100644 --- a/eclipse/plugins/org.argeo.slc.client.ui/META-INF/spring/jcr.xml +++ b/eclipse/plugins/org.argeo.slc.client.ui/META-INF/spring/jcr.xml @@ -15,6 +15,11 @@ + + + + diff --git a/eclipse/plugins/org.argeo.slc.client.ui/plugin.xml b/eclipse/plugins/org.argeo.slc.client.ui/plugin.xml index 96f9fe1f9..0b7d2f012 100644 --- a/eclipse/plugins/org.argeo.slc.client.ui/plugin.xml +++ b/eclipse/plugins/org.argeo.slc.client.ui/plugin.xml @@ -26,6 +26,13 @@ name="Results" restorable="true"> + + nodes = new ArrayList(); + for (NodeIterator nit = query.execute().getNodes(); nit + .hasNext();) { + nodes.add(nit.nextNode()); + } + return nodes.toArray(); + } catch (RepositoryException e) { + throw new SlcException("Cannot retrieve processes", e); + } + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + + class LabelProvider extends ColumnLabelProvider implements + ITableLabelProvider { + + public Image getColumnImage(Object obj, int columnIndex) { + if (columnIndex != 0) + return null; + try { + Node node = (Node) obj; + if(node.hasProperty(SLC_COMPLETED)){ + // TODO + } + return null; + } catch (RepositoryException e) { + throw new SlcException("Cannot get column text", e); + } + } + + public String getColumnText(Object obj, int index) { + try { + Node node = (Node) obj; + switch (index) { + + case 0: + return dateFormat.format(node + .getProperty(Property.JCR_LAST_MODIFIED).getDate() + .getTime()); + case 1: + return node.getProperty(SlcNames.SLC_UUID).getString(); + } + return getText(obj); + } catch (RepositoryException e) { + throw new SlcException("Cannot get column text", e); + } + } + + } + + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + try { + if (obj instanceof Node) { + Node node = (Node) obj; + if (node.isNodeType(SlcTypes.SLC_PROCESS)) { + IWorkbenchPage activePage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + activePage.openEditor( + new ProcessEditorInput(node.getPath()), + ProcessEditor.ID); + } + } + } catch (Exception e) { + throw new SlcException("Cannot open " + obj, e); + } + } + + } + + public void setSession(Session session) { + this.session = session; + } + +} \ No newline at end of file diff --git a/modules/agent/org.argeo.slc.agent.jcr/META-INF/MANIFEST.MF b/modules/agent/org.argeo.slc.agent.jcr/META-INF/MANIFEST.MF index 15f683298..19a0f4f8f 100644 --- a/modules/agent/org.argeo.slc.agent.jcr/META-INF/MANIFEST.MF +++ b/modules/agent/org.argeo.slc.agent.jcr/META-INF/MANIFEST.MF @@ -7,6 +7,7 @@ Import-Package: javax.jcr, org.argeo.security, org.argeo.security.core, org.argeo.security.jcr, + org.argeo.slc.core.test.tree, org.argeo.slc.execution, org.argeo.slc.jcr, org.argeo.slc.jcr.execution, diff --git a/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr-osgi.xml b/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr-osgi.xml index a6f779f37..525c16437 100644 --- a/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr-osgi.xml +++ b/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr-osgi.xml @@ -19,6 +19,11 @@ interface="org.springframework.security.AuthenticationManager" /> + + + + diff --git a/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr.xml b/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr.xml index c07f293e6..6c1f43c42 100644 --- a/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr.xml +++ b/modules/agent/org.argeo.slc.agent.jcr/META-INF/spring/jcr.xml @@ -12,11 +12,15 @@ - + + - + + + + diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrConstants.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrConstants.java index eb1cf46e0..3775afadf 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrConstants.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrConstants.java @@ -4,5 +4,6 @@ public interface SlcJcrConstants { public final static String PROPERTY_PATH = "argeo.slc.jcr.path"; public final static String PROCESSES_BASE_PATH = "/slc/processes"; public final static String AGENTS_BASE_PATH = "/slc/agents"; + public final static String RESULTS_BASE_PATH = "/slc/results"; public final static String VM_AGENT_FACTORY_PATH = AGENTS_BASE_PATH + "/vm"; } diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrUtils.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrUtils.java index fcd850aaa..c4a14ff29 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrUtils.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrUtils.java @@ -64,7 +64,13 @@ public class SlcJcrUtils { Calendar now = new GregorianCalendar(); return SlcJcrConstants.PROCESSES_BASE_PATH + '/' + JcrUtils.dateAsPath(now, true) + uuid; + } + /** Create a new execution result path based on the current time */ + public static String createResultPath(String uuid) { + Calendar now = new GregorianCalendar(); + return SlcJcrConstants.RESULTS_BASE_PATH + '/' + + JcrUtils.dateAsPath(now, true) + uuid; } /** diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java index fa2704150..d41f80cf0 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java @@ -11,12 +11,21 @@ public interface SlcNames { public final static String SLC_VALUE = "slc:value"; public final static String SLC_ADDRESS = "slc:address"; + public final static String SLC_STARTED = "slc:started"; + public final static String SLC_COMPLETED = "slc:completed"; + public final static String SLC_SPEC = "slc:spec"; public final static String SLC_EXECUTION_SPECS = "slc:executionSpecs"; public final static String SLC_FLOW = "slc:flow"; + // spec attribute public final static String SLC_IS_IMMUTABLE = "slc:isImmutable"; public final static String SLC_IS_CONSTANT = "slc:isConstant"; public final static String SLC_IS_HIDDEN = "slc:isHidden"; + // result + public final static String SLC_SUCCESS = "slc:success"; + public final static String SLC_MESSAGE = "slc:message"; + public final static String SLC_ERROR_MESSAGE = "slc:errorMessage"; + } diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java index 6ac10e3b0..9afbb73c2 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java @@ -16,4 +16,7 @@ public interface SlcTypes { public final static String SLC_PRIMITIVE_SPEC_ATTRIBUTE = "slc:primitiveSpecAttribute"; public final static String SLC_REF_SPEC_ATTRIBUTE = "slc:refSpecAttribute"; + public final static String SLC_RESULT = "slc:result"; + public final static String SLC_CHECK = "slc:check"; + } diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrResultListener.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrResultListener.java new file mode 100644 index 000000000..8cd72efc7 --- /dev/null +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrResultListener.java @@ -0,0 +1,154 @@ +package org.argeo.slc.jcr.execution; + +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.Query; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.core.test.tree.TreeTestResultListener; +import org.argeo.slc.jcr.SlcJcrUtils; +import org.argeo.slc.jcr.SlcNames; +import org.argeo.slc.jcr.SlcTypes; +import org.argeo.slc.test.TestResultPart; +import org.argeo.slc.test.TestStatus; + +/** Persists results in JCR */ +public class JcrResultListener implements TreeTestResultListener, SlcNames { + private final static Log log = LogFactory.getLog(JcrResultListener.class); + + private Session session; + + /** Caches the mapping between SLC uuids and internal JCR identifiers */ + private Map uuidToIdentifier = Collections + .synchronizedMap(new HashMap()); + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + try { + String uuid = testResult.getUuid(); + Node resultNode = getResultNode(uuid); + if (resultNode == null) { + resultNode = createResultNode(testResult); + // session.save(); + } + String partParentPath; + TreeSPath currentPath = testResult.getCurrentPath(); + if (currentPath != null) { + String subPath = currentPath.getAsUniqueString(); + partParentPath = resultNode.getPath() + subPath; + } else { + partParentPath = resultNode.getPath(); + // TODO create some depth? + } + + Node partParentNode; + if (session.itemExists(partParentPath)) { + partParentNode = session.getNode(partParentPath); + } else { + partParentNode = JcrUtils.mkdirs(session, partParentPath); + // session.save(); + } + // create part node + // TODO find a better name + String partNodeName = Long.toString(System.currentTimeMillis()); + Node resultPartNode = partParentNode.addNode(partNodeName, + SlcTypes.SLC_CHECK); + resultPartNode.setProperty(SLC_SUCCESS, + testResultPart.getStatus() == TestStatus.PASSED); + if (testResultPart.getMessage() != null) + resultPartNode.setProperty(SLC_MESSAGE, + testResultPart.getMessage()); + if (testResultPart.getExceptionMessage() != null) + resultPartNode.setProperty(SLC_ERROR_MESSAGE, + testResultPart.getExceptionMessage()); + // JcrUtils.debug(resultPartNode); + + JcrUtils.updateLastModified(resultNode); + + session.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(session); + log.error("Cannot add result part " + testResultPart + " to " + + testResult, e); + // throw new SlcException("Cannot add result part " + testResultPart + // + " to " + testResult, e); + } + + } + + /** @return null if does not exist */ + protected Node getResultNode(String uuid) throws RepositoryException { + Node resultNode; + if (uuidToIdentifier.containsKey(uuid)) { + return session.getNodeByIdentifier(uuidToIdentifier.get(uuid)); + } else { + Query q = session + .getWorkspace() + .getQueryManager() + .createQuery( + "select * from [slc:result] where [slc:uuid]='" + + uuid + "'", Query.JCR_SQL2); + resultNode = JcrUtils.querySingleNode(q); + if (resultNode != null) + uuidToIdentifier.put(uuid, resultNode.getIdentifier()); + } + return resultNode; + } + + protected Node createResultNode(TreeTestResult testResult) + throws RepositoryException { + String uuid = testResult.getUuid(); + String path = SlcJcrUtils.createResultPath(uuid); + Node resultNode = JcrUtils.mkdirs(session, path, SlcTypes.SLC_RESULT); + resultNode.setProperty(SLC_UUID, uuid); + for (Map.Entry entry : testResult.getAttributes() + .entrySet()) { + resultNode.setProperty(entry.getKey(), entry.getValue()); + } + + uuidToIdentifier.put(uuid, resultNode.getIdentifier()); + return resultNode; + } + + public void close(TreeTestResult testResult) { + try { + String uuid = testResult.getUuid(); + Node resultNode = getResultNode(uuid); + if (resultNode == null) + resultNode = createResultNode(testResult); + JcrUtils.updateLastModified(resultNode); + GregorianCalendar closeDate = new GregorianCalendar(); + closeDate.setTime(testResult.getCloseDate()); + resultNode.setProperty(SLC_COMPLETED, closeDate); + + uuidToIdentifier.remove(uuid); + session.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(session); + log.error("Cannot close result " + testResult, e); + // throw new SlcException("Cannot close result " + testResult, e); + } + + } + + public void addAttachment(TreeTestResult testResult, Attachment attachment) { + + } + + public void setSession(Session session) { + this.session = session; + } + +} diff --git a/runtime/org.argeo.slc.support.jcr/src/main/resources/org/argeo/slc/jcr/slc.cnd b/runtime/org.argeo.slc.support.jcr/src/main/resources/org/argeo/slc/jcr/slc.cnd index 126b16f72..cb88e5504 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/resources/org/argeo/slc/jcr/slc.cnd +++ b/runtime/org.argeo.slc.support.jcr/src/main/resources/org/argeo/slc/jcr/slc.cnd @@ -45,7 +45,7 @@ mixin + * (mix:title) [slc:executionFlow] > nt:unstructured, mix:title -- slc:name (STRING) m +- slc:name (STRING) ! m // if the execution spec is a referenceable node - slc:spec (REFERENCE) // if the execution spec is internal (without name) @@ -53,7 +53,7 @@ mixin // PROCESS [slc:process] > nt:unstructured, mix:created, mix:lastModified -- slc:uuid (STRING) m +- slc:uuid (STRING) ! m - slc:status (STRING) m + slc:flow (slc:realizedFlow) @@ -70,4 +70,15 @@ mixin // the realized execution spec attributes + * (slc:executionSpecAttribute) * +// RESULT +[slc:result] > nt:unstructured, mix:created, mix:lastModified +- slc:uuid (STRING) ! m +- slc:completed (DATE) + +[slc:check] > nt:unstructured, mix:created +// true for PASSED, false for FAILED or ERROR +- slc:success (BOOLEAN) ! m +- slc:message (STRING) +// ERROR if set, the check could not be performed because of an unexpected exception +- slc:errorMessage (STRING) -- 2.39.2