From: Mathieu Baudier Date: Mon, 18 Apr 2011 12:47:26 +0000 (+0000) Subject: Improve JCR integration X-Git-Tag: argeo-slc-2.1.7~980 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=827cc6fa4bff1994f89cb8d925808def5600b5dc;p=gpl%2Fargeo-slc.git Improve JCR integration Move JMX NEW - 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@4447 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java b/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java new file mode 100644 index 000000000..a06509c21 --- /dev/null +++ b/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java @@ -0,0 +1,225 @@ +package org.argeo.slc.client.ui.views; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.oxm.OxmInterface; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.controllers.ProcessController; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider.FlowNode; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +public class JcrExecutionModulesView extends ViewPart { + private final static Log log = LogFactory + .getLog(JcrExecutionModulesView.class); + + public static final String ID = "org.argeo.slc.client.ui.executionModulesView"; + + private TreeViewer viewer; + + // Ioc + private IContentProvider contentProvider; + private OxmInterface oxmBean; + private ProcessController processController; + + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(contentProvider); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + viewer.addDragSupport(operations, tt, new ViewDragListener()); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + public void refreshView() { + viewer.setInput(getViewSite()); + } + + class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) { + ExecutionModuleDescriptor emd = ((ExecutionModulesContentProvider.ExecutionModuleNode) obj) + .getDescriptor(); + if (emd.getLabel() != null) { + return emd.getLabel(); + } else { + return getText(emd); + } + } else + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return getImage(obj); + } + + public Image getImage(Object obj) { + if (obj instanceof ExecutionModulesContentProvider.AgentNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("agent"); + else if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("executionModule"); + else if (obj instanceof ExecutionModulesContentProvider.FolderNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("folder"); + else if (obj instanceof ExecutionModulesContentProvider.FlowNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("flow"); + else + return PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + } + + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof ExecutionModulesContentProvider.FlowNode) { + ExecutionModulesContentProvider.FlowNode fn = (ExecutionModulesContentProvider.FlowNode) obj; + + List realizedFlows = new ArrayList(); + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionModuleNode() + .getFlowDescriptors().get(fn.getFlowName())); + realizedFlows.add(realizedFlow); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.setRealizedFlows(realizedFlows); + slcExecution.setHost(fn.getExecutionModuleNode().getAgentNode() + .getAgent().toString()); + processController.execute(fn.getExecutionModuleNode() + .getAgentNode().getAgent(), slcExecution); + } + } + + } + + class ViewDragListener implements DragSourceListener { + + public void dragStart(DragSourceEvent event) { + System.out.println("Start Drag"); + } + + public void dragSetData(DragSourceEvent event) { + + // System.out.println("dragSetData: " + event); + + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + if (selection.getFirstElement() instanceof ExecutionModulesContentProvider.FlowNode) { + + if (TextTransfer.getInstance().isSupportedType(event.dataType)) { + ExecutionModulesContentProvider.FlowNode flowNode = (ExecutionModulesContentProvider.FlowNode) selection + .getFirstElement(); + + Properties props = new Properties(); + flowNodeAsProperties(props, flowNode); + props.setProperty("agentId", flowNode + .getExecutionModuleNode().getAgentNode().getAgent() + .getAgentUuid()); + props.setProperty("host", flowNode.getExecutionModuleNode() + .getAgentNode().getAgent().toString()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + props.store(out, ""); + event.data = new String(out.toByteArray()); + } catch (IOException e) { + throw new SlcException( + "Cannot transform realized flow", e); + } finally { + IOUtils.closeQuietly(out); + } + } + } + } + + public void dragFinished(DragSourceEvent event) { + System.out.println("Finished Drag"); + } + + protected void flowNodeAsProperties(Properties props, FlowNode fn) { + + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionFlowDescriptor()); + + // As we want to have the effective ExecutionSpec and not a + // reference; we store it at the RealizeFlow level : thus the + // marshaller will store the object and not only a reference. + realizedFlow.setExecutionSpec(fn.getExecutionFlowDescriptor() + .getExecutionSpec()); + + props.setProperty("RealizedFlowAsXml", + oxmBean.marshal(realizedFlow)); + System.out + .println(oxmBean.marshal(fn.getExecutionFlowDescriptor())); + + } + + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setProcessController(ProcessController processController) { + this.processController = processController; + } + + public void setOxmBean(OxmInterface oxmBean) { + this.oxmBean = oxmBean; + } + +} \ No newline at end of file diff --git a/modules/agent/org.argeo.slc.agent.jmx/.project b/modules/agent/org.argeo.slc.agent.jmx/.project deleted file mode 100644 index 1c83f49cc..000000000 --- a/modules/agent/org.argeo.slc.agent.jmx/.project +++ /dev/null @@ -1,22 +0,0 @@ - - - org.argeo.slc.agent.jmx - - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - - diff --git a/modules/agent/org.argeo.slc.agent.jmx/META-INF/MANIFEST.MF b/modules/agent/org.argeo.slc.agent.jmx/META-INF/MANIFEST.MF deleted file mode 100644 index ba9e36c47..000000000 --- a/modules/agent/org.argeo.slc.agent.jmx/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Manifest-Version: 1.0 -Bundle-Version: 0.13.1.SNAPSHOT -Bundle-Name: SLC Agent JMX -Bundle-SymbolicName: org.argeo.slc.agent.jmx -Import-Package: org.argeo.slc.core.execution, - org.argeo.slc.execution diff --git a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/common.xml b/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/common.xml deleted file mode 100644 index de606a16b..000000000 --- a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/common.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - \ No newline at end of file diff --git a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/jmx.xml b/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/jmx.xml deleted file mode 100644 index 31ebe1174..000000000 --- a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/jmx.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/osgi.xml b/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/osgi.xml deleted file mode 100644 index 8c81b159c..000000000 --- a/modules/agent/org.argeo.slc.agent.jmx/META-INF/spring/osgi.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java index 7860feea6..277e4df0c 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java @@ -143,55 +143,8 @@ public class DefaultExecutionFlowDescriptorConverter implements for (String name : executionFlows.keySet()) { ExecutionFlow executionFlow = executionFlows.get(name); - Assert.notNull(executionFlow.getName()); - Assert.state(name.equals(executionFlow.getName())); - - ExecutionSpec executionSpec = executionFlow.getExecutionSpec(); - Assert.notNull(executionSpec); - Assert.notNull(executionSpec.getName()); - - Map values = new TreeMap(); - for (String key : executionSpec.getAttributes().keySet()) { - ExecutionSpecAttribute attribute = executionSpec - .getAttributes().get(key); - - if (attribute instanceof PrimitiveSpecAttribute) { - if (executionFlow.isSetAsParameter(key)) { - Object value = executionFlow.getParameter(key); - PrimitiveValue primitiveValue = new PrimitiveValue(); - primitiveValue - .setType(((PrimitiveSpecAttribute) attribute) - .getType()); - primitiveValue.setValue(value); - values.put(key, primitiveValue); - } else { - // no need to add a primitive value if it is not set, - // all necessary information is in the spec - } - } else if (attribute instanceof RefSpecAttribute) { - if (attribute.getIsFrozen()) { - values.put(key, new RefValue(REF_VALUE_INTERNAL)); - } else - values.put(key, buildRefValue( - (RefSpecAttribute) attribute, executionFlow, - key)); - } else { - throw new SlcException("Unkown spec attribute type " - + attribute.getClass()); - } - - } - - ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, - values, executionSpec); - if (executionFlow.getPath() != null) - efd.setPath(executionFlow.getPath()); - else - efd.setPath(""); - - // Takes description from spring - BeanDefinition bd = getBeanFactory().getBeanDefinition(name); - efd.setDescription(bd.getDescription()); + ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow); + ExecutionSpec executionSpec = efd.getExecutionSpec(); // Add execution spec if necessary if (!md.getExecutionSpecs().contains(executionSpec)) @@ -204,6 +157,60 @@ public class DefaultExecutionFlowDescriptorConverter implements md.getExecutionFlows().addAll(set); } + public ExecutionFlowDescriptor getExecutionFlowDescriptor( + ExecutionFlow executionFlow) { + Assert.notNull(executionFlow.getName()); + String name = executionFlow.getName(); + + ExecutionSpec executionSpec = executionFlow.getExecutionSpec(); + Assert.notNull(executionSpec); + Assert.notNull(executionSpec.getName()); + + Map values = new TreeMap(); + for (String key : executionSpec.getAttributes().keySet()) { + ExecutionSpecAttribute attribute = executionSpec.getAttributes() + .get(key); + + if (attribute instanceof PrimitiveSpecAttribute) { + if (executionFlow.isSetAsParameter(key)) { + Object value = executionFlow.getParameter(key); + PrimitiveValue primitiveValue = new PrimitiveValue(); + primitiveValue.setType(((PrimitiveSpecAttribute) attribute) + .getType()); + primitiveValue.setValue(value); + values.put(key, primitiveValue); + } else { + // no need to add a primitive value if it is not set, + // all necessary information is in the spec + } + } else if (attribute instanceof RefSpecAttribute) { + if (attribute.getIsFrozen()) { + values.put(key, new RefValue(REF_VALUE_INTERNAL)); + } else + values.put( + key, + buildRefValue((RefSpecAttribute) attribute, + executionFlow, key)); + } else { + throw new SlcException("Unkown spec attribute type " + + attribute.getClass()); + } + + } + + ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, values, + executionSpec); + if (executionFlow.getPath() != null) + efd.setPath(executionFlow.getPath()); + else + efd.setPath(""); + + // Takes description from spring + BeanDefinition bd = getBeanFactory().getBeanDefinition(name); + efd.setDescription(bd.getDescription()); + return efd; + } + @SuppressWarnings(value = { "unchecked" }) protected RefValue buildRefValue(RefSpecAttribute rsa, ExecutionFlow executionFlow, String key) { @@ -225,8 +232,7 @@ public class DefaultExecutionFlowDescriptorConverter implements String ref = null; Object value = executionFlow.getParameter(key); if (applicationContext == null) { - log - .warn("No application context declared, cannot scan ref value."); + log.warn("No application context declared, cannot scan ref value."); ref = value.toString(); } else { @@ -252,15 +258,9 @@ public class DefaultExecutionFlowDescriptorConverter implements } } if (ref == null) { - log - .warn("Cannot define reference for ref spec attribute " - + key - + " in " - + executionFlow - + " (" - + rsa - + ")." - + " If it is an inner bean consider put it frozen."); + log.warn("Cannot define reference for ref spec attribute " + + key + " in " + executionFlow + " (" + rsa + ")." + + " If it is an inner bean consider put it frozen."); ref = REF_VALUE_INTERNAL; } else { if (log.isTraceEnabled()) @@ -300,7 +300,7 @@ public class DefaultExecutionFlowDescriptorConverter implements // Check whether name include path int lastIndex1 = name1.lastIndexOf('/'); - //log.debug(name1+", "+lastIndex1); + // log.debug(name1+", "+lastIndex1); if (!StringUtils.hasText(path1) && lastIndex1 >= 0) { path1 = name1.substring(0, lastIndex1); name1 = name1.substring(lastIndex1 + 1); diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/JmxExecutionModulesListeners.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/JmxExecutionModulesListeners.java deleted file mode 100644 index 215fdd2b8..000000000 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/JmxExecutionModulesListeners.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2010 Mathieu Baudier - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.argeo.slc.core.execution; - -import java.lang.management.ManagementFactory; - -import javax.management.MBeanServer; -import javax.management.ObjectName; -import javax.management.StandardMBean; - -import org.argeo.slc.SlcException; -import org.argeo.slc.deploy.Module; -import org.argeo.slc.execution.ExecutionContext; -import org.argeo.slc.execution.ExecutionFlow; -import org.argeo.slc.execution.ExecutionModulesListener; - -public class JmxExecutionModulesListeners implements ExecutionModulesListener { - private String executionModulesPrefix = "SLCExecutionModules"; - private MBeanServer mBeanServer = ManagementFactory - .getPlatformMBeanServer(); - - public void executionModuleAdded(Module module, - ExecutionContext executionContext) { - } - - public void executionModuleRemoved(Module module, - ExecutionContext executionContext) { - } - - public void executionFlowAdded(Module module, ExecutionFlow executionFlow) { - try { - StandardMBean mbean = new StandardMBean(executionFlow, - ExecutionFlow.class); - mBeanServer.registerMBean(mbean, flowName(module, executionFlow)); - } catch (Exception e) { - String msg = "Cannot register execution flow " + executionFlow - + " as mbean"; - throw new SlcException(msg, e); - } - } - - public void executionFlowRemoved(Module module, ExecutionFlow executionFlow) { - try { - mBeanServer.unregisterMBean(flowName(module, executionFlow)); - } catch (Exception e) { - String msg = "Cannot unregister execution flow " + executionFlow - + " as mbean"; - throw new SlcException(msg, e); - } - } - - protected ObjectName flowName(Module module, ExecutionFlow executionFlow) { - String path = executionFlow.getPath(); - String name = executionModulesPrefix + ":" + "module=" - + module.getName() + "[" + module.getVersion() + "]," - + (path != null ? "path=" + path + "," : "") + "name=" - + executionFlow.getName(); - try { - return new ObjectName(name); - } catch (Exception e) { - throw new SlcException("Cannot generate object name based on " - + name, e); - } - } -} diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/msg/build/ModularDistributionDescriptor.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/msg/build/ModularDistributionDescriptor.java index 8e8510ce5..3f3400fc5 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/msg/build/ModularDistributionDescriptor.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/msg/build/ModularDistributionDescriptor.java @@ -22,10 +22,10 @@ import java.util.Map; import org.argeo.slc.BasicNameVersion; +/** Describes a distribution of modules. */ public class ModularDistributionDescriptor extends BasicNameVersion implements Serializable { - private static final long serialVersionUID = 1L; - + private static final long serialVersionUID = 6076494586594591185L; /** key is type, value the URL */ private Map modulesDescriptors = new HashMap(); diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/Module.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/Module.java index 4b1d3b125..062243c37 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/Module.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/Module.java @@ -18,5 +18,11 @@ package org.argeo.slc.deploy; import org.argeo.slc.NameVersion; +/** + * Represents a deployed module of a broader deployed system. A module is + * uniquely identifiable via a name / version. + */ public interface Module extends DeployedSystem, NameVersion { + /** A serializable stateless description of the module */ + public ModuleDescriptor getModuleDescriptor(); } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java index 0a36002fb..3dca36d3f 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java @@ -16,10 +16,12 @@ package org.argeo.slc.deploy; +import java.io.Serializable; + import org.argeo.slc.BasicNameVersion; /** The description of a versioned module. */ -public class ModuleDescriptor extends BasicNameVersion { +public class ModuleDescriptor extends BasicNameVersion implements Serializable { private static final long serialVersionUID = 4310820315478645419L; private String title; private String description; diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java index 0910c1734..9574d88ea 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java @@ -20,14 +20,14 @@ import java.util.List; import org.argeo.slc.NameVersion; -/** Provides access to modules */ +/** Provides access to deployed modules */ public interface ModulesManager { /** @return a full fledged module descriptor. */ public ModuleDescriptor getModuleDescriptor(String moduleName, String version); /** - * @return a list of minimal module descriptors + * @return a list of minimal module descriptors of the deployed modules */ public List listModules(); diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java index ba3c7fb70..68ac646e0 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java @@ -18,10 +18,17 @@ package org.argeo.slc.execution; import java.util.Map; +/** + * Maps back and forth between {@link ExecutionFlowDescriptor} and + * {@link ExecutionFlow} + */ public interface ExecutionFlowDescriptorConverter { public Map convertValues( ExecutionFlowDescriptor executionFlowDescriptor); public void addFlowsToDescriptor(ExecutionModuleDescriptor md, Map executionFlows); + + public ExecutionFlowDescriptor getExecutionFlowDescriptor( + ExecutionFlow executionFlow); } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesListener.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesListener.java index 54f5cb3e6..c5ef83c91 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesListener.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesListener.java @@ -16,17 +16,17 @@ package org.argeo.slc.execution; -import org.argeo.slc.deploy.Module; +import org.argeo.slc.deploy.ModuleDescriptor; /** Listen to events on execution modules. */ public interface ExecutionModulesListener { - public void executionModuleAdded(Module module, - ExecutionContext executionContext); + public void executionModuleAdded(ModuleDescriptor moduleDescriptor); - public void executionModuleRemoved(Module module, - ExecutionContext executionContext); + public void executionModuleRemoved(ModuleDescriptor moduleDescriptor); - public void executionFlowAdded(Module module, ExecutionFlow executionFlow); + public void executionFlowAdded(ModuleDescriptor moduleDescriptor, + ExecutionFlowDescriptor executionFlowDescriptor); - public void executionFlowRemoved(Module module, ExecutionFlow executionFlow); + public void executionFlowRemoved(ModuleDescriptor moduleDescriptor, + ExecutionFlowDescriptor executionFlowDescriptor); } diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java index c68272dc4..1dc79046c 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java @@ -4,16 +4,17 @@ import java.util.Arrays; import java.util.Iterator; import javax.jcr.Node; +import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; -import org.argeo.slc.deploy.Module; -import org.argeo.slc.execution.ExecutionContext; -import org.argeo.slc.execution.ExecutionFlow; +import org.argeo.slc.deploy.ModuleDescriptor; +import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionModulesListener; import org.argeo.slc.jcr.SlcJcrConstants; import org.argeo.slc.jcr.SlcNames; @@ -61,42 +62,48 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener { } } - public void executionModuleAdded(Module module, - ExecutionContext executionContext) { + public void executionModuleAdded(ModuleDescriptor moduleDescriptor) { try { Node base = session.getNode(getExecutionModulesPath()); - Node moduleName = base.hasNode(module.getName()) ? base - .getNode(module.getName()) : base.addNode(module.getName()); - Node moduleVersion = moduleName.hasNode(module.getVersion()) ? moduleName - .getNode(module.getVersion()) : moduleName.addNode(module + Node moduleName = base.hasNode(moduleDescriptor.getName()) ? base + .getNode(moduleDescriptor.getName()) : base + .addNode(moduleDescriptor.getName()); + Node moduleVersion = moduleName.hasNode(moduleDescriptor + .getVersion()) ? moduleName.getNode(moduleDescriptor + .getVersion()) : moduleName.addNode(moduleDescriptor .getVersion()); + moduleVersion.addMixin(NodeType.MIX_TITLE); + moduleVersion.setProperty(Property.JCR_TITLE, + moduleDescriptor.getTitle()); + moduleVersion.setProperty(Property.JCR_DESCRIPTION, + moduleDescriptor.getDescription()); session.save(); } catch (RepositoryException e) { - throw new SlcException("Cannot add module " + module, e); + throw new SlcException("Cannot add module " + moduleDescriptor, e); } } - public void executionModuleRemoved(Module module, - ExecutionContext executionContext) { + public void executionModuleRemoved(ModuleDescriptor moduleDescriptor) { try { Node base = session.getNode(getExecutionModulesPath()); - if (base.hasNode(module.getName())) { - Node moduleName = base.getNode(module.getName()); - if (moduleName.hasNode(module.getVersion())) - moduleName.getNode(module.getVersion()).remove(); + if (base.hasNode(moduleDescriptor.getName())) { + Node moduleName = base.getNode(moduleDescriptor.getName()); + if (moduleName.hasNode(moduleDescriptor.getVersion())) + moduleName.getNode(moduleDescriptor.getVersion()).remove(); if (!moduleName.hasNodes()) moduleName.remove(); session.save(); } } catch (RepositoryException e) { - throw new SlcException("Cannot remove module " + module, e); + throw new SlcException("Cannot remove module " + moduleDescriptor, + e); } } - public void executionFlowAdded(Module module, ExecutionFlow executionFlow) { + public void executionFlowAdded(ModuleDescriptor module, + ExecutionFlowDescriptor executionFlow) { String path = getExecutionFlowPath(module, executionFlow); - log.debug("path=" + path); try { Node flowNode; if (!session.nodeExists(path)) { @@ -104,7 +111,6 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener { Node moduleNode = base.getNode(module.getName() + '/' + module.getVersion()); String relativePath = getExecutionFlowRelativePath(executionFlow); - log.debug("relativePath='" + relativePath + "'"); Iterator names = Arrays.asList(relativePath.split("/")) .iterator(); Node currNode = moduleNode; @@ -130,7 +136,8 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener { } - public void executionFlowRemoved(Module module, ExecutionFlow executionFlow) { + public void executionFlowRemoved(ModuleDescriptor module, + ExecutionFlowDescriptor executionFlow) { String path = getExecutionFlowPath(module, executionFlow); try { if (session.nodeExists(path)) { @@ -144,8 +151,8 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener { } } - protected String getExecutionFlowPath(Module module, - ExecutionFlow executionFlow) { + protected String getExecutionFlowPath(ModuleDescriptor module, + ExecutionFlowDescriptor executionFlow) { String relativePath = getExecutionFlowRelativePath(executionFlow); return getExecutionModulesPath() + '/' + module.getName() + '/' + module.getVersion() + '/' + relativePath; @@ -153,7 +160,8 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener { /** @return the relative path, never starts with '/' */ @SuppressWarnings("deprecation") - protected String getExecutionFlowRelativePath(ExecutionFlow executionFlow) { + protected String getExecutionFlowRelativePath( + ExecutionFlowDescriptor executionFlow) { String relativePath = executionFlow.getPath() == null ? executionFlow .getName() : executionFlow.getPath() + '/' + executionFlow.getName(); diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiBundle.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiBundle.java index 0be7d02e9..0296a13d2 100644 --- a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiBundle.java +++ b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiBundle.java @@ -22,6 +22,7 @@ import org.argeo.slc.build.Distribution; import org.argeo.slc.core.build.ResourceDistribution; import org.argeo.slc.deploy.DeploymentData; import org.argeo.slc.deploy.Module; +import org.argeo.slc.deploy.ModuleDescriptor; import org.argeo.slc.deploy.TargetData; import org.argeo.slc.process.RealizedFlow; import org.osgi.framework.Bundle; @@ -30,13 +31,13 @@ import org.springframework.core.io.Resource; /** A deployed OSGi bundle. */ public class OsgiBundle extends BasicNameVersion implements Module { - private static final long serialVersionUID = -1970854723780452072L; + private static final long serialVersionUID = 35073826504550477L; private ResourceDistribution distribution; private Long internalBundleId; - private String label; + private String title; private String description; public OsgiBundle() { @@ -126,12 +127,12 @@ public class OsgiBundle extends BasicNameVersion implements Module { } /** Value of the Bundle-Name directive. */ - public String getLabel() { - return label; + public String getTitle() { + return title; } - public void setLabel(String label) { - this.label = label; + public void setTitle(String label) { + this.title = label; } /** Value of the Bundle-Description directive. */ @@ -143,4 +144,12 @@ public class OsgiBundle extends BasicNameVersion implements Module { this.description = description; } + public ModuleDescriptor getModuleDescriptor() { + ModuleDescriptor moduleDescriptor = new ModuleDescriptor(); + moduleDescriptor.setName(getName()); + moduleDescriptor.setVersion(getVersion()); + moduleDescriptor.setDescription(description); + moduleDescriptor.setTitle(title); + return moduleDescriptor; + } } diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java index 45a65eae2..ed4b7faea 100644 --- a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java +++ b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java @@ -16,6 +16,7 @@ package org.argeo.slc.osgi; +import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -24,6 +25,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.StandardMBean; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.BasicNameVersion; @@ -31,6 +36,7 @@ import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; import org.argeo.slc.core.execution.AbstractExecutionModulesManager; import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter; +import org.argeo.slc.deploy.Module; import org.argeo.slc.deploy.ModuleDescriptor; import org.argeo.slc.execution.ExecutionContext; import org.argeo.slc.execution.ExecutionFlow; @@ -58,6 +64,8 @@ public class OsgiExecutionModulesManager extends private List executionModulesListeners = new ArrayList(); + private Boolean registerFlowsToJmx = true; + public synchronized ExecutionModuleDescriptor getExecutionModuleDescriptor( String moduleName, String version) { ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); @@ -76,7 +84,7 @@ public class OsgiExecutionModulesManager extends + nameVersion); md.setName(osgiBundle.getName()); md.setVersion(osgiBundle.getVersion()); - md.setLabel(osgiBundle.getLabel()); + md.setTitle(osgiBundle.getTitle()); md.setDescription(osgiBundle.getDescription()); ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = getExecutionFlowDescriptorConverter( @@ -189,6 +197,11 @@ public class OsgiExecutionModulesManager extends protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter( String moduleName, String moduleVersion) { OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion); + return getExecutionFlowDescriptorConverter(osgiBundle); + } + + protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter( + OsgiBundle osgiBundle) { if (executionFlowDescriptorConverters.containsKey(osgiBundle)) return executionFlowDescriptorConverters.get(osgiBundle); else @@ -234,7 +247,7 @@ public class OsgiExecutionModulesManager extends md.setName(bdl.getSymbolicName()); md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION)); - md.setLabel(getHeaderSafe(bdl, Constants.BUNDLE_NAME)); + md.setTitle(getHeaderSafe(bdl, Constants.BUNDLE_NAME)); md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION)); } @@ -255,7 +268,7 @@ public class OsgiExecutionModulesManager extends Map properties) { OsgiBundle osgiBundle = asOsgiBundle(properties); Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle); - osgiBundle.setLabel(getHeaderSafe(bundle, Constants.BUNDLE_NAME)); + osgiBundle.setTitle(getHeaderSafe(bundle, Constants.BUNDLE_NAME)); osgiBundle.setDescription(getHeaderSafe(bundle, Constants.BUNDLE_DESCRIPTION)); executionContexts.put(osgiBundle, executionContext); @@ -263,7 +276,7 @@ public class OsgiExecutionModulesManager extends log.trace("Registered execution context from " + osgiBundle); // Notify for (ExecutionModulesListener listener : executionModulesListeners) - listener.executionModuleAdded(osgiBundle, executionContext); + listener.executionModuleAdded(osgiBundle.getModuleDescriptor()); } /** Unregisters an execution context. */ @@ -276,7 +289,8 @@ public class OsgiExecutionModulesManager extends log.trace("Removed execution context from " + osgiBundle); // Notify for (ExecutionModulesListener listener : executionModulesListeners) - listener.executionModuleRemoved(osgiBundle, executionContext); + listener.executionModuleRemoved(osgiBundle + .getModuleDescriptor()); } } @@ -291,8 +305,13 @@ public class OsgiExecutionModulesManager extends if (log.isTraceEnabled()) log.trace("Registered " + executionFlow + " from " + osgiBundle); + // notifications + if (registerFlowsToJmx) + registerMBean(osgiBundle, executionFlow); + ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle); for (ExecutionModulesListener listener : executionModulesListeners) - listener.executionFlowAdded(osgiBundle, executionFlow); + listener.executionFlowAdded(osgiBundle.getModuleDescriptor(), + efdc.getExecutionFlowDescriptor(executionFlow)); } /** Unregisters an execution flow. */ @@ -309,8 +328,14 @@ public class OsgiExecutionModulesManager extends if (log.isTraceEnabled()) log.trace("Removed flows set from " + osgiBundle); } + + // notifications + if (registerFlowsToJmx) + unregisterMBean(osgiBundle, executionFlow); + ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle); for (ExecutionModulesListener listener : executionModulesListeners) - listener.executionFlowRemoved(osgiBundle, executionFlow); + listener.executionFlowRemoved(osgiBundle.getModuleDescriptor(), + efdc.getExecutionFlowDescriptor(executionFlow)); } } @@ -320,13 +345,15 @@ public class OsgiExecutionModulesManager extends Map properties) { // sync with current state for (OsgiBundle osgiBundle : executionContexts.keySet()) { - executionModulesListener.executionModuleAdded(osgiBundle, - executionContexts.get(osgiBundle)); + executionModulesListener.executionModuleAdded(osgiBundle + .getModuleDescriptor()); } for (OsgiBundle osgiBundle : executionFlows.keySet()) { + ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle); for (ExecutionFlow executionFlow : executionFlows.get(osgiBundle)) - executionModulesListener.executionFlowAdded(osgiBundle, - executionFlow); + executionModulesListener.executionFlowAdded( + osgiBundle.getModuleDescriptor(), + efdc.getExecutionFlowDescriptor(executionFlow)); } executionModulesListeners.add(executionModulesListener); } @@ -370,6 +397,76 @@ public class OsgiExecutionModulesManager extends } } + /* + * JMX + */ + protected MBeanServer getMBeanServer() { + return ManagementFactory.getPlatformMBeanServer(); + } + + public void registerMBean(Module module, ExecutionFlow executionFlow) { + try { + StandardMBean mbean = new StandardMBean(executionFlow, + ExecutionFlow.class); + getMBeanServer().registerMBean(mbean, + flowMBeanName(module, executionFlow)); + } catch (Exception e) { + String msg = "Cannot register execution flow " + executionFlow + + " as mbean"; + throw new SlcException(msg, e); + } + } + + public void unregisterMBean(Module module, ExecutionFlow executionFlow) { + try { + getMBeanServer().unregisterMBean( + flowMBeanName(module, executionFlow)); + } catch (Exception e) { + String msg = "Cannot unregister execution flow " + executionFlow + + " as mbean"; + throw new SlcException(msg, e); + } + } + + @SuppressWarnings("deprecation") + protected ObjectName flowMBeanName(Module module, + ExecutionFlow executionFlow) { + String executionModulesPrefix = "SLCExecutionModules"; + String path = executionFlow.getPath(); + String name = executionFlow.getName(); + if (path == null && name.indexOf('/') >= 0) { + path = name.substring(0, name.lastIndexOf('/') - 1); + name = name.substring(name.lastIndexOf('/')); + } + + StringBuffer buf = new StringBuffer(executionModulesPrefix + ":" + + "module=" + module.getName() + " [" + module.getVersion() + + "],"); + + if (path != null && !path.equals("")) { + int depth = 0; + for (String token : path.split("/")) { + if (!token.equals("")) { + buf.append("path").append(depth).append('='); + // in order to have directories first + buf.append('/'); + buf.append(token).append(','); + depth++; + } + } + } + buf.append("name=").append(name); + try { + return new ObjectName(buf.toString()); + } catch (Exception e) { + throw new SlcException("Cannot generate object name based on " + + buf, e); + } + } + + /* + * UTILITIES + */ @SuppressWarnings("rawtypes") private OsgiBundle asOsgiBundle(Map properties) { String bundleSymbolicName = checkAndGet(Constants.BUNDLE_SYMBOLICNAME, @@ -395,4 +492,8 @@ public class OsgiExecutionModulesManager extends this.defaultDescriptorConverter = defaultDescriptorConverter; } + public void setRegisterFlowsToJmx(Boolean registerFlowsToJmx) { + this.registerFlowsToJmx = registerFlowsToJmx; + } + }