Author: atk
Date: Thu Dec 3 09:24:33 2009
New Revision: 886717
URL: http://svn.apache.org/viewvc?rev=886717&view=rev
Log:
ARIES-36 ARIES-34 abstract MBeanHandler for tracking optional services
Added:
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
(with props)
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
(with props)
Added:
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java?rev=886717&view=auto
==============================================================================
---
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
(added)
+++
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
Thu Dec 3 09:24:33 2009
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.aries.jmx;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.management.StandardMBean;
+
+import org.apache.aries.jmx.agent.JMXAgentContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * <p>
+ * Abstract implementation of {...@link MBeanHandler} that provides a template
with basic tracking of an optional
+ * compendium service. MBeanHandler implementations that manage a {...@link
StandardMBean} that is backed by a single OSGi
+ * compendium service should extend this class and implement the
{...@linkplain #constructInjectMBean(Object)} and
+ * {...@linkplain #getName()} methods
+ * </p>
+ *
+ * @see MBeanHandler
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractCompendiumHandler extends ServiceTracker
implements MBeanHandler {
+
+ protected final JMXAgentContext agentContext;
+ protected StandardMBean mbean;
+ protected Long trackedId;
+
+ /**
+ *
+ * @param agentContext
+ * @param filter
+ */
+ protected AbstractCompendiumHandler(JMXAgentContext agentContext, Filter
filter) {
+ super(agentContext.getBundleContext(), filter, null);
+ this.agentContext = agentContext;
+ }
+
+ /**
+ *
+ * @param agentContext
+ * @param clazz
+ */
+ protected AbstractCompendiumHandler(JMXAgentContext agentContext, String
clazz) {
+ super(agentContext.getBundleContext(), clazz, null);
+ this.agentContext = agentContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
+ */
+ public Object addingService(ServiceReference reference) {
+ Logger logger = agentContext.getLogger();
+ Object trackedService = null;
+ Long serviceId = (Long) reference.getProperty(Constants.SERVICE_ID);
+ //API stipulates versions for compendium services with static
ObjectName
+ //This shouldn't happen but added as a consistency check
+ if (getTrackingCount() > 0) {
+ String serviceDescription = (String)
((reference.getProperty(Constants.SERVICE_DESCRIPTION) != null) ?
+ reference.getProperty(Constants.SERVICE_DESCRIPTION) :
reference.getProperty(Constants.OBJECTCLASS));
+ logger.log(LogService.LOG_WARNING, "Detected secondary
ServiceReference for [" + serviceDescription
+ + "] with " + Constants.SERVICE_ID + " [" + serviceId + "]
Only 1 instance will be JMX managed");
+ } else {
+ logger.log(LogService.LOG_INFO, "Registering MBean with ObjectName
[" + getName() + "] for service with "
+ + Constants.SERVICE_ID + " [" + serviceId + "]");
+ trackedService = context.getService(reference);
+ mbean = constructInjectMBean(trackedService);
+ ExecutorService executor = agentContext.getRegistrationExecutor();
+ executor.submit(new Runnable() {
+ public void run() {
+ agentContext.registerMBean(AbstractCompendiumHandler.this);
+ }
+ });
+ trackedId = serviceId;
+ }
+ return trackedService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
java.lang.Object)
+ */
+ public void removedService(ServiceReference reference, Object service) {
+ Logger logger = agentContext.getLogger();
+ Long serviceID = (Long) reference.getProperty(Constants.SERVICE_ID);
+ if (trackedId != null && !trackedId.equals(serviceID)) {
+ String serviceDescription = (String)
((reference.getProperty(Constants.SERVICE_DESCRIPTION) != null) ?
+ reference.getProperty(Constants.SERVICE_DESCRIPTION) :
reference.getProperty(Constants.OBJECTCLASS));
+ logger.log(LogService.LOG_WARNING, "ServiceReference for [" +
serviceDescription + "] with "
+ + Constants.SERVICE_ID + " [" + serviceID + "] is not
currently JMX managed");
+ } else {
+ logger.log(LogService.LOG_INFO, "Unregistering MBean with
ObjectName [" + getName() + "] for service with "
+ + Constants.SERVICE_ID + " [" + serviceID + "]");
+ ExecutorService executor = agentContext.getRegistrationExecutor();
+ executor.submit(new Runnable() {
+ public void run() {
+ agentContext.unregisterMBean(getName());
+ }
+ });
+ trackedId = null;
+ context.ungetService(reference);
+ }
+ }
+
+ /**
+ * Gets the <code>StandardMBean</code> managed by this handler when the
backing service is available or null
+ *
+ * @see org.apache.aries.jmx.MBeanHandler#getMbean()
+ */
+ public StandardMBean getMbean() {
+ return mbean;
+ }
+
+ /**
+ * Implement this method to construct an appropriate {...@link
StandardMBean} instance which is backed by the supplied
+ * service tracked by this handler
+ *
+ * @param targetService
+ * the compendium service tracked by this handler
+ * @return The <code>StandardMBean</code> instance whose registration
lifecycle will be managed by this handler
+ */
+ protected abstract StandardMBean constructInjectMBean(Object
targetService);
+
+}
Propchange:
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/AbstractCompendiumHandler.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added:
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
URL:
http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java?rev=886717&view=auto
==============================================================================
---
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
(added)
+++
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
Thu Dec 3 09:24:33 2009
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.aries.jmx;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.StandardMBean;
+
+import org.apache.aries.jmx.agent.JMXAgentContext;
+import org.junit.After;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+public class CompendiumHandlerTest {
+
+ protected AbstractCompendiumHandler target;
+
+ @After
+ public void tearDown(){
+ target = null;
+ }
+
+
+ @Test
+ public void testAddingServiceWillInitiateMBeanRegistration() throws
Exception {
+
+ Object service = new Object();
+
+ ServiceReference reference = mock(ServiceReference.class);
+ BundleContext bundleContext = mock(BundleContext.class);
+ when(bundleContext.getService(reference)).thenReturn(service);
+
+ Logger agentLogger = mock(Logger.class);
+ JMXAgentContext agentContext = mock(JMXAgentContext.class);
+ when(agentContext.getBundleContext()).thenReturn(bundleContext);
+ when(agentContext.getLogger()).thenReturn(agentLogger);
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ when(agentContext.getRegistrationExecutor()).thenReturn(executor);
+
+ AbstractCompendiumHandler concreteHandler = new
CompendiumHandler(agentContext, "org.osgi.service.Xxx");
+ target = spy(concreteHandler);
+
+ target.addingService(reference);
+
+ executor.shutdown();
+ executor.awaitTermination(2, TimeUnit.SECONDS);
+
+ //service only got once
+ verify(bundleContext).getService(reference);
+ //template method is invoked
+ verify(target).constructInjectMBean(service);
+ //registration is invoked on context
+ verify(agentContext).registerMBean(target);
+
+ }
+
+ @Test
+ public void testRemovedServiceWillUnregisterMBean() throws Exception{
+
+ Object service = new Object();
+ ServiceReference reference = mock(ServiceReference.class);
+
+ BundleContext bundleContext = mock(BundleContext.class);
+ Logger agentLogger = mock(Logger.class);
+ JMXAgentContext agentContext = mock(JMXAgentContext.class);
+ when(agentContext.getBundleContext()).thenReturn(bundleContext);
+ when(agentContext.getLogger()).thenReturn(agentLogger);
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ when(agentContext.getRegistrationExecutor()).thenReturn(executor);
+
+ AbstractCompendiumHandler concreteHandler = new
CompendiumHandler(agentContext, "org.osgi.service.Xxx");
+ target = spy(concreteHandler);
+
+ String name = "osgi.compendium:service=xxx,version=1.0";
+ doReturn(name).when(target).getName();
+
+ target.removedService(reference, service);
+
+ executor.shutdown();
+ executor.awaitTermination(2, TimeUnit.SECONDS);
+
+ //service unget
+ verify(bundleContext).ungetService(reference);
+ //unregister is invoked on context
+ verify(agentContext).unregisterMBean(name);
+
+ }
+
+
+
+ /*
+ * Concrete implementation used for test
+ */
+ class CompendiumHandler extends AbstractCompendiumHandler {
+
+ protected CompendiumHandler(JMXAgentContext agentContext, Filter
filter) {
+ super(agentContext, filter);
+ }
+
+ protected CompendiumHandler(JMXAgentContext agentContext, String
clazz) {
+ super(agentContext, clazz);
+ }
+
+ protected StandardMBean constructInjectMBean(Object targetService) {
+ return null;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ }
+}
Propchange:
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/CompendiumHandlerTest.java
------------------------------------------------------------------------------
svn:keywords = Revision Date