From eb163a8e90ce3247322d63e151c9324d90796dab Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 14 Nov 2011 13:00:40 +0200 Subject: Add support for introspection of a single service to ServiceStateMBean. Fix for bug 363458. --- .gitignore | 3 +- gemini.mgmt.releng/pom.xml | 14 +- org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF | 2 - .../src/org/eclipse/gemini/mgmt/Monitor.java | 11 - .../gemini/mgmt/framework/ServiceState.java | 224 +++++++++++++++------ .../gemini/mgmt/framework/codec/OSGiService.java | 31 ++- 6 files changed, 186 insertions(+), 99 deletions(-) diff --git a/.gitignore b/.gitignore index da92513..66772f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -*/target \ No newline at end of file +*/target +*/bin diff --git a/gemini.mgmt.releng/pom.xml b/gemini.mgmt.releng/pom.xml index fbdf7a5..34e85f7 100644 --- a/gemini.mgmt.releng/pom.xml +++ b/gemini.mgmt.releng/pom.xml @@ -38,13 +38,13 @@ p2 - - org.eclipse.gemini.mgmt - target-platform - 1.0.0-SNAPSHOT - gemini-management - - + + org.eclipse.gemini.mgmt + target-platform + 1.0.0-SNAPSHOT + gemini-management + + diff --git a/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF b/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF index acc55d6..74af427 100644 --- a/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF +++ b/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF @@ -3,7 +3,6 @@ Bundle-ManifestVersion: 2 Bundle-Name: Gemini Management Bundle-SymbolicName: org.eclipse.gemini.mgmt Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Oracle Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: org.osgi.framework;version="1.3.0", org.osgi.jmx, @@ -22,4 +21,3 @@ Import-Package: org.osgi.framework;version="1.3.0", javax.management, javax.management.openmbean Bundle-Activator: org.eclipse.gemini.mgmt.Activator -Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Monitor.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Monitor.java index 01bbfaf..8da3874 100644 --- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Monitor.java +++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Monitor.java @@ -23,27 +23,16 @@ import javax.management.ObjectName; /** * */ - abstract public class Monitor extends NotificationBroadcasterSupport implements MBeanRegistration { public void postDeregister() { } - /* - * (non-Javadoc) - * - * @see javax.management.MBeanRegistration#postRegister(java.lang.Boolean) - */ public void postRegister(Boolean registrationDone) { addListener(); } - /* - * (non-Javadoc) - * - * @see javax.management.MBeanRegistration#preDeregister() - */ public void preDeregister() throws Exception { removeListener(); } diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/ServiceState.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/ServiceState.java index e40e727..cf2c569 100644 --- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/ServiceState.java +++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/ServiceState.java @@ -11,18 +11,28 @@ * * Contributors: * Hal Hildebrand - Initial JMX support + * Christopher Frost - Updates for RFC 169 ******************************************************************************/ package org.eclipse.gemini.mgmt.framework; import static org.osgi.framework.Constants.OBJECTCLASS; +import static org.osgi.framework.Constants.SERVICE_ID; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import javax.management.Notification; +import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; +import org.eclipse.gemini.mgmt.Monitor; +import org.eclipse.gemini.mgmt.codec.OSGiProperties; +import org.eclipse.gemini.mgmt.codec.Util; +import org.eclipse.gemini.mgmt.framework.codec.OSGiService; +import org.eclipse.gemini.mgmt.framework.codec.OSGiServiceEvent; import org.osgi.framework.AllServiceListener; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -32,53 +42,57 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; - import org.osgi.jmx.framework.ServiceStateMBean; import org.osgi.util.tracker.ServiceTracker; -import org.eclipse.gemini.mgmt.Monitor; -import org.eclipse.gemini.mgmt.codec.OSGiProperties; -import org.eclipse.gemini.mgmt.framework.codec.OSGiService; -import org.eclipse.gemini.mgmt.framework.codec.OSGiServiceEvent; - /** * */ public class ServiceState extends Monitor implements ServiceStateMBean { + + protected ServiceListener serviceListener; + + protected BundleContext bundleContext; + + /** + * Constructor + * + * @param bundleContext + */ public ServiceState(BundleContext bc) { - this.bc = bc; + this.bundleContext = bc; } + /** + * {@inheritDoc} + */ public long getBundleIdentifier(long serviceId) throws IOException { return ref(serviceId).getBundle().getBundleId(); } + /** + * {@inheritDoc} + */ public TabularData getProperties(long serviceId) throws IOException { return OSGiProperties.tableFrom(ref(serviceId)); } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.core.ServiceStateMBean#getBundle(long) + /** + * {@inheritDoc} */ - public String[] getObjectClass(long serviceId) throws IOException { return (String[]) ref(serviceId).getProperty(OBJECTCLASS); } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.core.ServiceStateMBean#listServices() + /** + * {@inheritDoc} */ - public TabularData listServices() { ArrayList services = new ArrayList(); - for (Bundle bundle : bc.getBundles()) { - ServiceReference[] refs = bundle.getRegisteredServices(); + for (Bundle bundle : bundleContext.getBundles()) { + ServiceReference[] refs = bundle.getRegisteredServices(); if (refs != null) { - for (ServiceReference ref : refs) { + for (ServiceReference ref : refs) { services.add(new OSGiService(ref)); } } @@ -86,12 +100,9 @@ public class ServiceState extends Monitor implements ServiceStateMBean { return OSGiService.tableFrom(services); } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.core.ServiceStateMBean#getServiceInterfaces(long) + /** + * {@inheritDoc} */ - public long[] getUsingBundles(long serviceId) throws IOException { Bundle[] bundles = ref(serviceId).getUsingBundles(); long[] ids = new long[bundles.length]; @@ -101,28 +112,137 @@ public class ServiceState extends Monitor implements ServiceStateMBean { return ids; } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.core.ServiceStateMBean#getServices() + /** + * {@inheritDoc} */ + public CompositeData getService(long serviceId) throws IOException { + for (Bundle bundle : bundleContext.getBundles()) { + ServiceReference[] refs = bundle.getRegisteredServices(); + if (refs != null) { + for (ServiceReference ref : refs) { + if(serviceId == (Long) ref.getProperty(Constants.SERVICE_ID)){ + return new OSGiService(ref).asCompositeData(); + } + } + } + } + return null; + } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.Monitor#addListener() + /** + * {@inheritDoc} + * @param + */ + public CompositeData getProperty(long serviceId, String key) throws IOException { + for (Bundle bundle : bundleContext.getBundles()) { + ServiceReference[] refs = bundle.getRegisteredServices(); + if (refs != null) { + for (ServiceReference ref : refs) { + if(serviceId == (Long) ref.getProperty(Constants.SERVICE_ID)){ + return OSGiProperties.encode(key, ref.getProperty(key)); + } + } + } + } + return null; + } + + /** + * {@inheritDoc} + */ + public TabularData listServices(String clazz, String filter) throws IOException { + ArrayList services = new ArrayList(); + try { + ServiceReference[] allServiceReferences = bundleContext.getAllServiceReferences(clazz, filter); + for (ServiceReference ref : allServiceReferences) { + services.add(new OSGiService(ref)); + } + return OSGiService.tableFrom(services); + } catch (InvalidSyntaxException e) { + throw new IOException(e); + } + } + + /** + * {@inheritDoc} + */ + public TabularData listServices(String clazz, String filter, String... serviceTypeItems) throws IOException { + ArrayList services = new ArrayList(); + List serviceTypeNames = Arrays.asList(serviceTypeItems); + try { + ServiceReference[] allServiceReferences = bundleContext.getAllServiceReferences(clazz, filter); + for (ServiceReference reference : allServiceReferences) { + Long identifier; + if(serviceTypeNames.contains(ServiceStateMBean.IDENTIFIER)){ + identifier = (Long) reference.getProperty(SERVICE_ID); + } else { + identifier = null; + } + String[] interfaces; + if(serviceTypeNames.contains(ServiceStateMBean.OBJECT_CLASS)){ + interfaces = (String[]) reference.getProperty(OBJECTCLASS); + } else { + interfaces = null; + } + Long bundle; + if(serviceTypeNames.contains(ServiceStateMBean.BUNDLE_IDENTIFIER)){ + bundle = reference.getBundle().getBundleId(); + } else { + bundle = null; + } + long[] usingBundles; + if(serviceTypeNames.contains(ServiceStateMBean.USING_BUNDLES)){ + usingBundles = Util.bundleIds(reference.getUsingBundles()); + } else { + usingBundles = null; + } + services.add(new OSGiService(identifier, interfaces, bundle, usingBundles)); + } + return OSGiService.tableFrom(services); + } catch (InvalidSyntaxException e) { + throw new IOException(e); + } + } + + /** + * {@inheritDoc} + */ + public long[] getServiceIds() throws IOException { + ServiceReference[] allServiceReferences; + try { + allServiceReferences = bundleContext.getAllServiceReferences(null, null); + long[] serviceIds = new long[allServiceReferences.length]; + for (int i = 0; i < allServiceReferences.length; i++) { + serviceIds[i] = (Long) allServiceReferences[i].getProperty(Constants.SERVICE_ID); + } + return serviceIds; + } catch (InvalidSyntaxException e) { + //passing in null so should never happen + throw new IOException(e); + } + } + + //End methods for the MBean + + + /** + * {@inheritDoc} */ @Override protected void addListener() { - serviceListener = getServiceListener(); - bc.addServiceListener(serviceListener); + serviceListener = this.getServiceListener(); + bundleContext.addServiceListener(serviceListener); } - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.core.ServiceStateMBean#getUsingBundles(long) + /** + * {@inheritDoc} */ + @Override + protected void removeListener() { + if (serviceListener != null) { + bundleContext.removeServiceListener(serviceListener); + } + } protected ServiceListener getServiceListener() { return new AllServiceListener() { @@ -135,30 +255,17 @@ public class ServiceState extends Monitor implements ServiceStateMBean { } }; } - - /* - * (non-Javadoc) - * - * @see org.osgi.jmx.Monitor#removeListener() - */ - @Override - protected void removeListener() { - if (serviceListener != null) { - bc.removeServiceListener(serviceListener); - } - } - - protected ServiceReference ref(long serviceId) throws IOException { + + protected ServiceReference ref(long serviceId) throws IOException { Filter filter; try { - filter = bc.createFilter("(" + Constants.SERVICE_ID + "=" - + serviceId + ")"); + filter = bundleContext.createFilter("(" + Constants.SERVICE_ID + "=" + serviceId + ")"); } catch (InvalidSyntaxException e) { throw new IOException("Invalid filter syntax: " + e); } - ServiceTracker tracker = new ServiceTracker(bc, filter, null); + ServiceTracker tracker = new ServiceTracker(bundleContext, filter, null); tracker.open(); - ServiceReference serviceReference = tracker.getServiceReference(); + ServiceReference serviceReference = tracker.getServiceReference(); if (serviceReference == null) { throw new IOException("Service <" + serviceId + "> does not exist"); } @@ -166,7 +273,4 @@ public class ServiceState extends Monitor implements ServiceStateMBean { return serviceReference; } - protected ServiceListener serviceListener; - protected BundleContext bc; - } diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiService.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiService.java index e608794..dcb4a57 100644 --- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiService.java +++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiService.java @@ -20,8 +20,8 @@ import static org.osgi.framework.Constants.SERVICE_ID; import static org.eclipse.gemini.mgmt.codec.Util.LongArrayFrom; import static org.eclipse.gemini.mgmt.codec.Util.longArrayFrom; -import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.management.openmbean.CompositeData; @@ -70,13 +70,11 @@ public class OSGiService { * @param data * - the CompositeData encoding the OSGiService */ - @SuppressWarnings("boxing") public OSGiService(CompositeData data) { - this((Long) data.get(ServiceStateMBean.IDENTIFIER), (String[]) data - .get(ServiceStateMBean.OBJECT_CLASS), (Long) data - .get(ServiceStateMBean.BUNDLE_IDENTIFIER), - longArrayFrom((Long[]) data - .get(ServiceStateMBean.USING_BUNDLES))); + this((Long) data.get(ServiceStateMBean.IDENTIFIER), + (String[]) data.get(ServiceStateMBean.OBJECT_CLASS), + (Long) data.get(ServiceStateMBean.BUNDLE_IDENTIFIER), + longArrayFrom((Long[]) data.get(ServiceStateMBean.USING_BUNDLES))); } /** @@ -88,8 +86,7 @@ public class OSGiService { * @param bundle * @param usingBundles */ - public OSGiService(long identifier, String[] interfaces, long bundle, - long[] usingBundles) { + public OSGiService(long identifier, String[] interfaces, long bundle, long[] usingBundles) { this.identifier = identifier; this.interfaces = interfaces; this.bundle = bundle; @@ -104,9 +101,10 @@ public class OSGiService { * - the reference of the service */ @SuppressWarnings("boxing") - public OSGiService(ServiceReference reference) { - this((Long) reference.getProperty(SERVICE_ID), (String[]) reference - .getProperty(OBJECTCLASS), reference.getBundle().getBundleId(), + public OSGiService(ServiceReference reference) { + this((Long) reference.getProperty(SERVICE_ID), + (String[]) reference.getProperty(OBJECTCLASS), + reference.getBundle().getBundleId(), Util.bundleIds(reference.getUsingBundles())); } @@ -118,9 +116,8 @@ public class OSGiService { * * @return the TabularData representing the list of OSGiServices */ - public static TabularData tableFrom(ArrayList services) { - TabularDataSupport table = new TabularDataSupport( - ServiceStateMBean.SERVICES_TYPE); + public static TabularData tableFrom(List services) { + TabularDataSupport table = new TabularDataSupport(ServiceStateMBean.SERVICES_TYPE); for (OSGiService service : services) { table.put(service.asCompositeData()); } @@ -132,7 +129,6 @@ public class OSGiService { * * @return the CompositeData encoding of the receiver. */ - @SuppressWarnings("boxing") public CompositeData asCompositeData() { Map items = new HashMap(); items.put(ServiceStateMBean.IDENTIFIER, identifier); @@ -141,8 +137,7 @@ public class OSGiService { items.put(ServiceStateMBean.USING_BUNDLES, LongArrayFrom(usingBundles)); try { - return new CompositeDataSupport(ServiceStateMBean.SERVICE_TYPE, - items); + return new CompositeDataSupport(ServiceStateMBean.SERVICE_TYPE, items); } catch (OpenDataException e) { throw new IllegalStateException("Cannot form service open data", e); } -- cgit v1.2.3