You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by at...@apache.org on 2009/12/03 09:55:23 UTC
svn commit: r886708 - in /incubator/aries/trunk/jmx/jmx-core/src:
main/java/org/apache/aries/jmx/codec/
main/java/org/apache/aries/jmx/framework/
test/java/org/apache/aries/jmx/codec/
test/java/org/apache/aries/jmx/framework/
Author: atk
Date: Thu Dec 3 08:55:18 2009
New Revision: 886708
URL: http://svn.apache.org/viewvc?rev=886708&view=rev
Log:
ARIES-31 Implement BundleStateMBean
Added:
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java (with props)
incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java (with props)
Added: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,444 @@
+/**
+ * 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.codec;
+
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleDependencies;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleExportedPackages;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleImportedPackages;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleState;
+import static org.apache.aries.jmx.util.FrameworkUtils.getDependentBundles;
+import static org.apache.aries.jmx.util.FrameworkUtils.getFragmentIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getHostIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getRegisteredServiceIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getServicesInUseByBundle;
+import static org.apache.aries.jmx.util.FrameworkUtils.isBundlePendingRemoval;
+import static org.apache.aries.jmx.util.FrameworkUtils.isBundleRequiredByOthers;
+import static org.apache.aries.jmx.util.TypeUtils.toLong;
+import static org.apache.aries.jmx.util.TypeUtils.toPrimitive;
+import static org.osgi.jmx.framework.BundleStateMBean.BUNDLE_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.EXPORTED_PACKAGES;
+import static org.osgi.jmx.framework.BundleStateMBean.FRAGMENT;
+import static org.osgi.jmx.framework.BundleStateMBean.FRAGMENTS;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADERS;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADERS_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADER_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.HOSTS;
+import static org.osgi.jmx.framework.BundleStateMBean.IDENTIFIER;
+import static org.osgi.jmx.framework.BundleStateMBean.IMPORTED_PACKAGES;
+import static org.osgi.jmx.framework.BundleStateMBean.KEY;
+import static org.osgi.jmx.framework.BundleStateMBean.LAST_MODIFIED;
+import static org.osgi.jmx.framework.BundleStateMBean.LOCATION;
+import static org.osgi.jmx.framework.BundleStateMBean.PERSISTENTLY_STARTED;
+import static org.osgi.jmx.framework.BundleStateMBean.REGISTERED_SERVICES;
+import static org.osgi.jmx.framework.BundleStateMBean.REMOVAL_PENDING;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRED;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRED_BUNDLES;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRING_BUNDLES;
+import static org.osgi.jmx.framework.BundleStateMBean.SERVICES_IN_USE;
+import static org.osgi.jmx.framework.BundleStateMBean.START_LEVEL;
+import static org.osgi.jmx.framework.BundleStateMBean.STATE;
+import static org.osgi.jmx.framework.BundleStateMBean.SYMBOLIC_NAME;
+import static org.osgi.jmx.framework.BundleStateMBean.VALUE;
+import static org.osgi.jmx.framework.BundleStateMBean.VERSION;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.JMRuntimeException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.osgi.framework.Bundle;
+import org.osgi.jmx.framework.BundleStateMBean;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * <p>
+ * <tt>BundleData</tt> represents BundleData Type @see {@link BundleStateMBean#BUNDLE_TYPE}. It is a codec for the
+ * <code>CompositeData</code> representing an OSGi BundleData.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleData {
+
+ /**
+ * @see BundleStateMBean#EXPORTED_PACKAGES_ITEM
+ */
+ private String[] exportedPackages;
+
+ /**
+ * @see BundleStateMBean#FRAGMENT_ITEM
+ */
+ private boolean fragment;
+
+ /**
+ * @see BundleStateMBean#FRAGMENTS_ITEM
+ */
+ private long[] fragments;
+
+ /**
+ * @see BundleStateMBean#HEADER_TYPE
+ */
+ private List<Header> headers = new ArrayList<Header>();
+
+ /**
+ * @see BundleStateMBean#HOSTS_ITEM
+ */
+ private long[] hosts;
+
+ /**
+ * @see BundleStateMBean#IDENTIFIER_ITEM
+ */
+ private long identifier;
+
+ /**
+ * @see BundleStateMBean#IMPORTED_PACKAGES_ITEM
+ */
+ private String[] importedPackages;
+
+ /**
+ * @see BundleStateMBean#LAST_MODIFIED_ITEM
+ */
+ private long lastModified;
+
+ /**
+ * @see BundleStateMBean#LOCATION_ITEM
+ */
+ private String location;
+
+ /**
+ * @see BundleStateMBean#PERSISTENTLY_STARTED_ITEM
+ */
+ private boolean persistentlyStarted;
+
+ /**
+ * @see BundleStateMBean#REGISTERED_SERVICES_ITEM
+ */
+ private long[] registeredServices;
+
+ /**
+ * @see BundleStateMBean#REMOVAL_PENDING_ITEM
+ */
+ private boolean removalPending;
+
+ /**
+ * @see BundleStateMBean#REQUIRED_ITEM
+ */
+ private boolean required;
+
+ /**
+ * @see BundleStateMBean#REQUIRED_BUNDLES_ITEM
+ */
+ private long[] requiredBundles;
+
+ /**
+ * @see BundleStateMBean#REQUIRING_BUNDLES_ITEM
+ */
+ private long[] requiringBundles;
+
+ /**
+ * @see BundleStateMBean#SERVICES_IN_USE_ITEM
+ */
+ private long[] servicesInUse;
+
+ /**
+ * @see BundleStateMBean#START_LEVEL_ITEM
+ */
+ private int bundleStartLevel;
+
+ /**
+ * @see BundleStateMBean#STATE_ITEM
+ */
+ private String state;
+
+ /**
+ * @see BundleStateMBean#SYMBOLIC_NAME_ITEM
+ */
+ private String symbolicName;
+
+ /**
+ * @see BundleStateMBean#VERSION_ITEM
+ */
+ private String version;
+
+ private BundleData() {
+ super();
+ }
+
+ @SuppressWarnings("unchecked")
+ public BundleData(Bundle bundle, PackageAdmin packageAdmin, StartLevel startLevel) {
+ if (bundle == null) {
+ throw new IllegalArgumentException("Argument bundle cannot be null");
+ }
+ if (packageAdmin == null || startLevel == null) {
+ throw new IllegalArgumentException("Arguments PackageAdmin / startLevel cannot be null");
+ }
+ this.exportedPackages = getBundleExportedPackages(bundle, packageAdmin);
+ this.fragment = (PackageAdmin.BUNDLE_TYPE_FRAGMENT == packageAdmin.getBundleType(bundle));
+ this.fragments = getFragmentIds(bundle, packageAdmin);
+ Dictionary<String, String> bundleHeaders = bundle.getHeaders();
+ Enumeration<String> keys = bundleHeaders.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ headers.add(new Header(key, bundleHeaders.get(key)));
+ }
+ this.hosts = getHostIds(bundle, packageAdmin);
+ this.identifier = bundle.getBundleId();
+ this.importedPackages = getBundleImportedPackages(bundle, packageAdmin);
+ this.lastModified = bundle.getLastModified();
+ this.location = bundle.getLocation();
+ this.persistentlyStarted = startLevel.isBundlePersistentlyStarted(bundle);
+ this.registeredServices = getRegisteredServiceIds(bundle);
+ this.removalPending = isBundlePendingRemoval(bundle, packageAdmin);
+ this.required = isBundleRequiredByOthers(bundle, packageAdmin);
+ this.requiredBundles = getBundleDependencies(bundle, packageAdmin);
+ this.requiringBundles = getDependentBundles(bundle, packageAdmin);
+ this.servicesInUse = getServicesInUseByBundle(bundle);
+ this.bundleStartLevel = startLevel.getBundleStartLevel(bundle);
+ this.state = getBundleState(bundle);
+ this.symbolicName = bundle.getSymbolicName();
+ this.version = bundle.getVersion().toString();
+ }
+
+ /**
+ * Returns CompositeData representing a BundleData complete state typed by {@link BundleStateMBean#BUNDLE_TYPE}
+ *
+ * @return
+ */
+ public CompositeData toCompositeData() {
+ CompositeData result = null;
+ Map<String, Object> items = new HashMap<String, Object>();
+ items.put(EXPORTED_PACKAGES, this.exportedPackages);
+ items.put(FRAGMENT, this.fragment);
+ items.put(FRAGMENTS, toLong(this.fragments));
+ items.put(HOSTS, toLong(this.hosts));
+ items.put(IDENTIFIER, this.identifier);
+ items.put(IMPORTED_PACKAGES, this.importedPackages);
+ items.put(LAST_MODIFIED, this.lastModified);
+ items.put(LOCATION, this.location);
+ items.put(PERSISTENTLY_STARTED, this.persistentlyStarted);
+ items.put(REGISTERED_SERVICES, toLong(this.registeredServices));
+ items.put(REMOVAL_PENDING, this.removalPending);
+ items.put(REQUIRED, this.required);
+ items.put(REQUIRED_BUNDLES, toLong(this.requiredBundles));
+ items.put(REQUIRING_BUNDLES, toLong(this.requiringBundles));
+ items.put(SERVICES_IN_USE, toLong(this.servicesInUse));
+ items.put(START_LEVEL, this.bundleStartLevel);
+ items.put(STATE, this.state);
+ items.put(SYMBOLIC_NAME, this.symbolicName);
+ items.put(VERSION, this.version);
+ TabularData headerTable = new TabularDataSupport(HEADERS_TYPE);
+ for (Header header : this.headers) {
+ headerTable.put(header.toCompositeData());
+ }
+ items.put(HEADERS, headerTable);
+ try {
+ result = new CompositeDataSupport(BUNDLE_TYPE, items);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Failed to create CompositeData for BundleData [" + this.identifier
+ + "]", e);
+ }
+ return result;
+ }
+
+ /**
+ * Constructs a <code>BundleData</code> object from the given <code>CompositeData</code>
+ *
+ * @param compositeData
+ * @return
+ * @throws IlleglArgumentException
+ * if compositeData is null or not of type {@link BundleStateMBean#BUNDLE_TYPE}
+ */
+ @SuppressWarnings("unchecked")
+ public static BundleData from(CompositeData compositeData) throws IllegalArgumentException {
+ if (compositeData == null) {
+ throw new IllegalArgumentException("Argument compositeData cannot be null");
+ }
+ if (!compositeData.getCompositeType().equals(BUNDLE_TYPE)) {
+ throw new IllegalArgumentException("Invalid CompositeType [" + compositeData.getCompositeType() + "]");
+ }
+ BundleData bundleData = new BundleData();
+ bundleData.exportedPackages = (String[]) compositeData.get(EXPORTED_PACKAGES);
+ bundleData.fragment = (Boolean) compositeData.get(FRAGMENT);
+ bundleData.fragments = toPrimitive((Long[]) compositeData.get(FRAGMENTS));
+ bundleData.hosts = toPrimitive((Long[]) compositeData.get(HOSTS));
+ bundleData.identifier = (Long) compositeData.get(IDENTIFIER);
+ bundleData.importedPackages = (String[]) compositeData.get(IMPORTED_PACKAGES);
+ bundleData.lastModified = (Long) compositeData.get(LAST_MODIFIED);
+ bundleData.location = (String) compositeData.get(LOCATION);
+ bundleData.persistentlyStarted = (Boolean) compositeData.get(PERSISTENTLY_STARTED);
+ bundleData.registeredServices = toPrimitive((Long[]) compositeData.get(REGISTERED_SERVICES));
+ bundleData.removalPending = (Boolean) compositeData.get(REMOVAL_PENDING);
+ bundleData.required = (Boolean) compositeData.get(REQUIRED);
+ bundleData.requiredBundles = toPrimitive((Long[]) compositeData.get(REQUIRED_BUNDLES));
+ bundleData.requiringBundles = toPrimitive((Long[]) compositeData.get(REQUIRING_BUNDLES));
+ bundleData.servicesInUse = toPrimitive((Long[]) compositeData.get(SERVICES_IN_USE));
+ bundleData.bundleStartLevel = (Integer) compositeData.get(START_LEVEL);
+ bundleData.state = (String) compositeData.get(STATE);
+ bundleData.symbolicName = (String) compositeData.get(SYMBOLIC_NAME);
+ bundleData.version = (String) compositeData.get(VERSION);
+ TabularData headerTable = (TabularData) compositeData.get(HEADERS);
+ Collection<CompositeData> headerData = (Collection<CompositeData>) headerTable.values();
+ for (CompositeData headerRow : headerData) {
+ bundleData.headers.add(Header.from(headerRow));
+ }
+ return bundleData;
+ }
+
+ public String[] getExportedPackages() {
+ return exportedPackages;
+ }
+
+ public boolean isFragment() {
+ return fragment;
+ }
+
+ public long[] getFragments() {
+ return fragments;
+ }
+
+ public List<Header> getHeaders() {
+ return headers;
+ }
+
+ public long[] getHosts() {
+ return hosts;
+ }
+
+ public long getIdentifier() {
+ return identifier;
+ }
+
+ public String[] getImportedPackages() {
+ return importedPackages;
+ }
+
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public boolean isPersistentlyStarted() {
+ return persistentlyStarted;
+ }
+
+ public long[] getRegisteredServices() {
+ return registeredServices;
+ }
+
+ public boolean isRemovalPending() {
+ return removalPending;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public long[] getRequiredBundles() {
+ return requiredBundles;
+ }
+
+ public long[] getRequiringBundles() {
+ return requiringBundles;
+ }
+
+ public long[] getServicesInUse() {
+ return servicesInUse;
+ }
+
+ public int getBundleStartLevel() {
+ return bundleStartLevel;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ /*
+ * Represents key/value pair in BundleData headers
+ */
+ public static class Header {
+
+ private String key;
+ private String value;
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ private Header() {
+ super();
+ }
+
+ public Header(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public CompositeData toCompositeData() throws JMRuntimeException {
+ CompositeData result = null;
+ Map<String, Object> items = new HashMap<String, Object>();
+ items.put(KEY, key);
+ items.put(VALUE, value);
+ try {
+ result = new CompositeDataSupport(HEADER_TYPE, items);
+ } catch (OpenDataException e) {
+ throw new JMRuntimeException("Failed to create CompositeData for header [" + key + ":" + value + "] - "
+ + e.getMessage());
+ }
+ return result;
+ }
+
+ public static Header from(CompositeData compositeData) {
+ if (compositeData == null) {
+ throw new IllegalArgumentException("Argument compositeData cannot be null");
+ }
+ if (!compositeData.getCompositeType().equals(HEADER_TYPE)) {
+ throw new IllegalArgumentException("Invalid CompositeType [" + compositeData.getCompositeType() + "]");
+ }
+ Header header = new Header();
+ header.key = (String) compositeData.get(KEY);
+ header.value = (String) compositeData.get(VALUE);
+ return header;
+ }
+ }
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleData.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java Thu Dec 3 08:55:18 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.codec;
+
+import static org.osgi.jmx.framework.BundleStateMBean.BUNDLE_EVENT_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.EVENT;
+import static org.osgi.jmx.framework.BundleStateMBean.IDENTIFIER;
+import static org.osgi.jmx.framework.BundleStateMBean.LOCATION;
+import static org.osgi.jmx.framework.BundleStateMBean.SYMBOLIC_NAME;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.jmx.framework.BundleStateMBean;
+
+/**
+ * <p>
+ * <tt>BundleEventData</tt> represents BundleEvent Type @see {@link BundleStateMBean#BUNDLE_EVENT_TYPE}. It is a codec
+ * for the <code>CompositeData</code> representing an OSGi BundleEvent.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleEventData {
+
+ /**
+ * @see BundleStateMBean#IDENTIFIER_ITEM
+ */
+ private long bundleId;
+
+ /**
+ * @see BundleStateMBean#LOCATION_ITEM
+ */
+ private String location;
+
+ /**
+ * @see BundleStateMBean#SYMBOLIC_NAME_ITEM
+ */
+ private String bundleSymbolicName;
+
+ /**
+ * @see BundleStateMBean#EVENT_ITEM
+ */
+ private int eventType;
+
+ private BundleEventData() {
+ super();
+ }
+
+ public BundleEventData(BundleEvent bundleEvent) {
+ this.eventType = bundleEvent.getType();
+ Bundle bundle = bundleEvent.getBundle();
+ this.bundleId = bundle.getBundleId();
+ this.location = bundle.getLocation();
+ this.bundleSymbolicName = bundle.getSymbolicName();
+ }
+
+ /**
+ * Returns CompositeData representing a BundleEvent typed by {@link BundleStateMBean#BUNDLE_EVENT_TYPE}
+ *
+ * @return
+ */
+ public CompositeData toCompositeData() {
+ CompositeData result = null;
+ Map<String, Object> items = new HashMap<String, Object>();
+ items.put(IDENTIFIER, this.bundleId);
+ items.put(SYMBOLIC_NAME, this.bundleSymbolicName);
+ items.put(LOCATION, this.location);
+ items.put(EVENT, this.eventType);
+ try {
+ result = new CompositeDataSupport(BUNDLE_EVENT_TYPE, items);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Failed to create CompositeData for BundleEvent for Bundle ["
+ + this.bundleId + "]", e);
+ }
+ return result;
+ }
+
+ /**
+ * Returns a <code>BundleEventData</code> representation of the given compositeData
+ *
+ * @param compositeData
+ * @return
+ * @throws IllegalArgumentException
+ * if the compositeData is null or incorrect type
+ */
+ public static BundleEventData from(CompositeData compositeData) throws IllegalArgumentException {
+ BundleEventData eventData = new BundleEventData();
+ if (compositeData == null) {
+ throw new IllegalArgumentException("Argument compositeData cannot be null");
+ }
+ if (!compositeData.getCompositeType().equals(BUNDLE_EVENT_TYPE)) {
+ throw new IllegalArgumentException("Invalid CompositeType [" + compositeData.getCompositeType() + "]");
+ }
+ eventData.bundleId = (Long) compositeData.get(IDENTIFIER);
+ eventData.bundleSymbolicName = (String) compositeData.get(SYMBOLIC_NAME);
+ eventData.eventType = (Integer) compositeData.get(EVENT);
+ eventData.location = (String) compositeData.get(LOCATION);
+ return eventData;
+ }
+
+ public long getBundleId() {
+ return bundleId;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getBundleSymbolicName() {
+ return bundleSymbolicName;
+ }
+
+ public int getEventType() {
+ return eventType;
+ }
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/codec/BundleEventData.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,350 @@
+/**
+ * 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.framework;
+
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleDependencies;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleExportedPackages;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleImportedPackages;
+import static org.apache.aries.jmx.util.FrameworkUtils.getBundleState;
+import static org.apache.aries.jmx.util.FrameworkUtils.getDependentBundles;
+import static org.apache.aries.jmx.util.FrameworkUtils.getFragmentIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getHostIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getRegisteredServiceIds;
+import static org.apache.aries.jmx.util.FrameworkUtils.getServicesInUseByBundle;
+import static org.apache.aries.jmx.util.FrameworkUtils.isBundlePendingRemoval;
+import static org.apache.aries.jmx.util.FrameworkUtils.isBundleRequiredByOthers;
+import static org.apache.aries.jmx.util.FrameworkUtils.resolveBundle;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.aries.jmx.Logger;
+import org.apache.aries.jmx.codec.BundleData;
+import org.apache.aries.jmx.codec.BundleEventData;
+import org.apache.aries.jmx.codec.BundleData.Header;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.jmx.framework.BundleStateMBean;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * Implementation of <code>BundleStateMBean</code> which emits JMX <code>Notification</code>
+ * on <code>Bundle</code> state changes
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleState extends NotificationBroadcasterSupport implements BundleStateMBean, MBeanRegistration {
+
+ protected Logger logger;
+ protected BundleContext bundleContext;
+ protected PackageAdmin packageAdmin;
+ protected StartLevel startLevel;
+
+ protected ExecutorService eventDispatcher;
+ protected BundleListener bundleListener;
+ private AtomicInteger notificationSequenceNumber = new AtomicInteger(1);
+ private Lock lock = new ReentrantLock();
+ private AtomicInteger registrations = new AtomicInteger(0);
+
+ // notification type description
+ public static String BUNDLE_EVENT = "org.osgi.bundle.event";
+
+ public BundleState(BundleContext bundleContext, PackageAdmin packageAdmin, StartLevel startLevel, Logger logger) {
+ this.bundleContext = bundleContext;
+ this.packageAdmin = packageAdmin;
+ this.startLevel = startLevel;
+ this.logger = logger;
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getExportedPackages(long)
+ */
+ public String[] getExportedPackages(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return getBundleExportedPackages(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getFragments(long)
+ */
+ public long[] getFragments(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return getFragmentIds(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getHeaders(long)
+ */
+ @SuppressWarnings("unchecked")
+ public TabularData getHeaders(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ List<Header> headers = new ArrayList<Header>();
+ Dictionary<String, String> bundleHeaders = bundle.getHeaders();
+ Enumeration<String> keys = bundleHeaders.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ headers.add(new Header(key, bundleHeaders.get(key)));
+ }
+ TabularData headerTable = new TabularDataSupport(HEADERS_TYPE);
+ for (Header header : headers) {
+ headerTable.put(header.toCompositeData());
+ }
+ return headerTable;
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getHosts(long)
+ */
+ public long[] getHosts(long fragmentId) throws IOException, IllegalArgumentException {
+ Bundle fragment = resolveBundle(bundleContext, fragmentId);
+ return getHostIds(fragment, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getImportedPackages(long)
+ */
+ public String[] getImportedPackages(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return getBundleImportedPackages(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getLastModified(long)
+ */
+ public long getLastModified(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return bundle.getLastModified();
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getLocation(long)
+ */
+ public String getLocation(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return bundle.getLocation();
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getRegisteredServices(long)
+ */
+ public long[] getRegisteredServices(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return getRegisteredServiceIds(bundle);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getRequiredBundles(long)
+ */
+ public long[] getRequiredBundles(long bundleIdentifier) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleIdentifier);
+ return getBundleDependencies(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getRequiringBundles(long)
+ */
+ public long[] getRequiringBundles(long bundleIdentifier) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleIdentifier);
+ return getDependentBundles(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getServicesInUse(long)
+ */
+ public long[] getServicesInUse(long bundleIdentifier) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleIdentifier);
+ return getServicesInUseByBundle(bundle);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getStartLevel(long)
+ */
+ public int getStartLevel(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return startLevel.getBundleStartLevel(bundle);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getState(long)
+ */
+ public String getState(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return getBundleState(bundle);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getSymbolicName(long)
+ */
+ public String getSymbolicName(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return bundle.getSymbolicName();
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#getVersion(long)
+ */
+ public String getVersion(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return bundle.getVersion().toString();
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#isFragment(long)
+ */
+ public boolean isFragment(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return (PackageAdmin.BUNDLE_TYPE_FRAGMENT == packageAdmin.getBundleType(bundle));
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#isPersistentlyStarted(long)
+ */
+ public boolean isPersistentlyStarted(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return startLevel.isBundlePersistentlyStarted(bundle);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#isRemovalPending(long)
+ */
+ public boolean isRemovalPending(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return isBundlePendingRemoval(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#isRequired(long)
+ */
+ public boolean isRequired(long bundleId) throws IOException, IllegalArgumentException {
+ Bundle bundle = resolveBundle(bundleContext, bundleId);
+ return isBundleRequiredByOthers(bundle, packageAdmin);
+ }
+
+ /**
+ * @see org.osgi.jmx.framework.BundleStateMBean#listBundles()
+ */
+ public TabularData listBundles() throws IOException {
+ Bundle[] containerBundles = bundleContext.getBundles();
+ List<BundleData> bundleDatas = new ArrayList<BundleData>();
+ for (Bundle containerBundle : containerBundles) {
+ bundleDatas.add(new BundleData(containerBundle, packageAdmin, startLevel));
+ }
+ TabularData bundleTable = new TabularDataSupport(BUNDLES_TYPE);
+ for (BundleData bundleData : bundleDatas) {
+ bundleTable.put(bundleData.toCompositeData());
+ }
+ return bundleTable;
+ }
+
+ /**
+ * @see javax.management.NotificationBroadcasterSupport#getNotificationInfo()
+ */
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ String[] types = new String[] { BUNDLE_EVENT };
+ String name = Notification.class.getName();
+ String description = "A BundleEvent issued from the Framework describing a bundle lifecycle change";
+ MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
+ return new MBeanNotificationInfo[] { info };
+ }
+
+ /**
+ * @see javax.management.MBeanRegistration#postDeregister()
+ */
+ public void postDeregister() {
+ if (registrations.decrementAndGet() < 1) {
+ bundleContext.removeBundleListener(bundleListener);
+ eventDispatcher.shutdown();
+ }
+ }
+
+ /**
+ * @see javax.management.MBeanRegistration#postRegister(java.lang.Boolean)
+ */
+ public void postRegister(Boolean registrationDone) {
+ if (registrationDone && registrations.incrementAndGet() == 1) {
+ eventDispatcher = Executors.newSingleThreadExecutor();
+ bundleContext.addBundleListener(bundleListener);
+ }
+ }
+
+ /**
+ * @see javax.management.MBeanRegistration#preDeregister()
+ */
+ public void preDeregister() throws Exception {
+ // No action
+ }
+
+ /**
+ * @see javax.management.MBeanRegistration#preRegister(javax.management.MBeanServer, javax.management.ObjectName)
+ */
+ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+ lock.lock();
+ try {
+ if (bundleListener == null) {
+ bundleListener = new BundleListener() {
+ public void bundleChanged(BundleEvent event) {
+ final Notification notification = new Notification(EVENT, OBJECTNAME, notificationSequenceNumber
+ .getAndIncrement());
+ try {
+ notification.setUserData(new BundleEventData(event).toCompositeData());
+ eventDispatcher.submit(new Runnable() {
+ public void run() {
+ sendNotification(notification);
+ }
+ });
+ } catch (Exception e) {
+ logger.log(LogService.LOG_WARNING, "Exception occured on JMX Notification dispatch for event ["
+ + event + "]", e);
+ }
+ }
+ };
+ }
+ } finally {
+ lock.unlock();
+ }
+ return name;
+ }
+
+ /*
+ * Returns the ExecutorService used to dispatch Notifications
+ */
+ public ExecutorService getEventDispatcher() {
+ return eventDispatcher;
+ }
+
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleState.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,115 @@
+/**
+ * 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.framework;
+
+import static org.osgi.jmx.framework.BundleStateMBean.OBJECTNAME;
+
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+
+import org.apache.aries.jmx.Logger;
+import org.apache.aries.jmx.MBeanHandler;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.jmx.framework.BundleStateMBean;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * <p>
+ * Implementation of <code>MBeanHandler</code> which manages the <code>BundleState</code>
+ * MBean implementation
+ * @see MBeanHandler
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleStateMBeanHandler implements MBeanHandler {
+
+ private Logger logger;
+ private String name;
+ private StandardMBean mbean;
+ private BundleContext bundleContext;
+ private ServiceReference packageAdminRef;
+ private ServiceReference startLevelRef;
+
+
+ public BundleStateMBeanHandler(BundleContext bundleContext, Logger logger) {
+ this.bundleContext = bundleContext;
+ this.logger = logger;
+ this.name = OBJECTNAME;
+ }
+
+ /**
+ * @see org.apache.aries.jmx.MBeanHandler#open()
+ */
+ public void open() {
+ packageAdminRef = bundleContext.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(packageAdminRef);
+ startLevelRef = bundleContext.getServiceReference(StartLevel.class.getName());
+ StartLevel startLevel = (StartLevel) bundleContext.getService(startLevelRef);
+ BundleStateMBean bundleStateMBean = new BundleState(bundleContext, packageAdmin, startLevel, logger);
+ try {
+ mbean = new RegistrableStandardEmitterMBean(bundleStateMBean, BundleStateMBean.class);
+ } catch (NotCompliantMBeanException e) {
+ logger.log(LogService.LOG_ERROR, "Failed to instantiate MBean for " + BundleStateMBean.class.getName(), e);
+ }
+ }
+
+ /**
+ * @see org.apache.aries.jmx.MBeanHandler#getMbean()
+ */
+ public StandardMBean getMbean() {
+ return mbean;
+ }
+
+
+ /**
+ * @see org.apache.aries.jmx.MBeanHandler#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @see org.apache.aries.jmx.MBeanHandler#close()
+ */
+ public void close() {
+ if (packageAdminRef != null) {
+ try {
+ bundleContext.ungetService(packageAdminRef);
+ } catch (RuntimeException e) {
+ logger.log(LogService.LOG_WARNING, "Exception occured during cleanup", e);
+ }
+ packageAdminRef = null;
+ }
+ if (startLevelRef != null) {
+ try {
+ bundleContext.ungetService(startLevelRef);
+ } catch (RuntimeException e) {
+ logger.log(LogService.LOG_WARNING, "Exception occured during cleanup", e);
+ }
+ startLevelRef = null;
+ }
+ }
+
+
+
+
+
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/framework/BundleStateMBeanHandler.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,238 @@
+/**
+ * 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.codec;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.osgi.jmx.framework.BundleStateMBean.BUNDLE_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.EXPORTED_PACKAGES;
+import static org.osgi.jmx.framework.BundleStateMBean.FRAGMENT;
+import static org.osgi.jmx.framework.BundleStateMBean.FRAGMENTS;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADERS;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADERS_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.HEADER_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.HOSTS;
+import static org.osgi.jmx.framework.BundleStateMBean.IDENTIFIER;
+import static org.osgi.jmx.framework.BundleStateMBean.IMPORTED_PACKAGES;
+import static org.osgi.jmx.framework.BundleStateMBean.KEY;
+import static org.osgi.jmx.framework.BundleStateMBean.LAST_MODIFIED;
+import static org.osgi.jmx.framework.BundleStateMBean.LOCATION;
+import static org.osgi.jmx.framework.BundleStateMBean.PERSISTENTLY_STARTED;
+import static org.osgi.jmx.framework.BundleStateMBean.REGISTERED_SERVICES;
+import static org.osgi.jmx.framework.BundleStateMBean.REMOVAL_PENDING;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRED;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRED_BUNDLES;
+import static org.osgi.jmx.framework.BundleStateMBean.REQUIRING_BUNDLES;
+import static org.osgi.jmx.framework.BundleStateMBean.SERVICES_IN_USE;
+import static org.osgi.jmx.framework.BundleStateMBean.START_LEVEL;
+import static org.osgi.jmx.framework.BundleStateMBean.STATE;
+import static org.osgi.jmx.framework.BundleStateMBean.SYMBOLIC_NAME;
+import static org.osgi.jmx.framework.BundleStateMBean.VALUE;
+import static org.osgi.jmx.framework.BundleStateMBean.VERSION;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.aries.jmx.codec.BundleData;
+import org.apache.aries.jmx.codec.BundleData.Header;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.packageadmin.RequiredBundle;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleDataTest {
+
+
+ @Test
+ public void testToCompositeData() throws Exception {
+
+ Bundle bundle = mock(Bundle.class);
+ BundleContext context = mock(BundleContext.class);
+ PackageAdmin packageAdmin = mock(PackageAdmin.class);
+ StartLevel startLevel = mock(StartLevel.class);
+
+ Bundle b1 = mock(Bundle.class);
+ when(b1.getSymbolicName()).thenReturn("b1");
+ when(b1.getBundleId()).thenReturn(new Long(44));
+ Bundle b2 = mock(Bundle.class);
+ when(b2.getSymbolicName()).thenReturn("b2");
+ when(b2.getBundleId()).thenReturn(new Long(55));
+ Bundle b3 = mock(Bundle.class);
+ when(b3.getSymbolicName()).thenReturn("b3");
+ when(b3.getBundleId()).thenReturn(new Long(66));
+ when(context.getBundles()).thenReturn(new Bundle[] { bundle, b1, b2, b3 });
+
+ when(bundle.getSymbolicName()).thenReturn("test");
+ when(bundle.getVersion()).thenReturn(Version.emptyVersion);
+ when(bundle.getBundleId()).thenReturn(new Long(1));
+ when(bundle.getBundleContext()).thenReturn(context);
+ when(bundle.getLastModified()).thenReturn(new Long(12345));
+ when(bundle.getLocation()).thenReturn("location");
+
+ //headers
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+ headers.put(Constants.BUNDLE_VERSION, "0.0.0");
+ when(bundle.getHeaders()).thenReturn(headers);
+
+ //exported packages
+ ExportedPackage exported = mock(ExportedPackage.class);
+ when(exported.getName()).thenReturn("org.apache.aries.jmx");
+ when(exported.getVersion()).thenReturn(new Version("1.0.0"));
+ when(packageAdmin.getExportedPackages(bundle)).thenReturn(new ExportedPackage[] { exported });
+
+ //imported packages
+ ExportedPackage ep1 = mock(ExportedPackage.class);
+ when(ep1.getImportingBundles()).thenReturn(new Bundle[] { bundle, b2, b3 });
+ when(ep1.getName()).thenReturn("org.apache.aries.jmx.b1");
+ when(ep1.getVersion()).thenReturn(Version.emptyVersion);
+ ExportedPackage ep2 = mock(ExportedPackage.class);
+ when(ep2.getImportingBundles()).thenReturn(new Bundle[] { bundle, b3 });
+ when(ep2.getName()).thenReturn("org.apache.aries.jmx.b2");
+ when(ep2.getVersion()).thenReturn(Version.parseVersion("2.0.1"));
+
+ when(packageAdmin.getExportedPackages(b1)).thenReturn(new ExportedPackage[] { ep1 });
+ when(packageAdmin.getExportedPackages(b2)).thenReturn(new ExportedPackage[] { ep2 });
+ when(packageAdmin.getExportedPackages(b3)).thenReturn(null);
+
+ //required bundles
+ RequiredBundle rb1 = mock(RequiredBundle.class);
+ when(rb1.getBundle()).thenReturn(b1);
+ when(rb1.getRequiringBundles()).thenReturn(new Bundle[] { bundle, b2 });
+ RequiredBundle rb2 = mock(RequiredBundle.class);
+ when(rb2.getBundle()).thenReturn(b2);
+ when(rb2.getRequiringBundles()).thenReturn(new Bundle[] { b1 });
+ RequiredBundle rb3 = mock(RequiredBundle.class);
+ when(rb3.getBundle()).thenReturn(b3);
+ when(rb3.getRequiringBundles()).thenReturn(new Bundle[] { bundle, b1, b2 });
+
+ when(packageAdmin.getRequiredBundles("b1")).thenReturn(new RequiredBundle[] { rb1 });
+ when(packageAdmin.getRequiredBundles("b2")).thenReturn(new RequiredBundle[] { rb2 });
+ when(packageAdmin.getRequiredBundles("b3")).thenReturn(new RequiredBundle[] { rb3 });
+
+ //services in use
+ ServiceReference s1 = mock(ServiceReference.class);
+ when(s1.getProperty(Constants.SERVICE_ID)).thenReturn(new Long(15));
+ ServiceReference s2 = mock(ServiceReference.class);
+ when(s2.getProperty(Constants.SERVICE_ID)).thenReturn(new Long(16));
+ ServiceReference s3 = mock(ServiceReference.class);
+ when(s3.getProperty(Constants.SERVICE_ID)).thenReturn(new Long(17));
+
+ when(bundle.getServicesInUse()).thenReturn(new ServiceReference[] { s1, s2, s3 });
+
+ BundleData b = new BundleData(bundle, packageAdmin, startLevel);
+ CompositeData compositeData = b.toCompositeData();
+
+ assertEquals("test", compositeData.get(SYMBOLIC_NAME));
+ assertEquals("0.0.0", (String) compositeData.get(VERSION));
+ TabularData headerTable = (TabularData) compositeData.get(HEADERS);
+ assertEquals(2, headerTable.values().size());
+ assertArrayEquals(new String[] { "org.apache.aries.jmx;1.0.0"} , (String[]) compositeData.get(EXPORTED_PACKAGES));
+ assertArrayEquals(new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"}, (String[]) compositeData.get(IMPORTED_PACKAGES));
+ assertArrayEquals(new Long[] { new Long(44), new Long(66) }, (Long[]) compositeData.get(REQUIRED_BUNDLES));
+ assertArrayEquals(new Long[] { new Long(15), new Long(16), new Long(17) },(Long[]) compositeData.get(SERVICES_IN_USE));
+ assertEquals("UNKNOWN", compositeData.get(STATE)); //default no return stub
+ assertEquals(0,((Long[]) compositeData.get(HOSTS)).length);
+ assertEquals(0, ((Long[]) compositeData.get(FRAGMENTS)).length);
+
+ }
+
+
+ @Test
+ public void testFromCompositeData() throws Exception {
+
+ Map<String, Object> items = new HashMap<String, Object>();
+ items.put(EXPORTED_PACKAGES, new String[] { "org.apache.aries.jmx;1.0.0"});
+ items.put(FRAGMENT, false);
+ items.put(FRAGMENTS, new Long[0]);
+ items.put(HOSTS, new Long[0]);
+ items.put(IDENTIFIER, new Long(3));
+ items.put(IMPORTED_PACKAGES, new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"});
+ items.put(LAST_MODIFIED, new Long(8797));
+ items.put(LOCATION, "");
+ items.put(PERSISTENTLY_STARTED, false);
+ items.put(REGISTERED_SERVICES, new Long[0]);
+ items.put(REMOVAL_PENDING, false);
+ items.put(REQUIRED, true);
+ items.put(REQUIRED_BUNDLES, new Long[] { new Long(44), new Long(66) });
+ items.put(REQUIRING_BUNDLES, new Long[0]);
+ items.put(SERVICES_IN_USE, new Long[] { new Long(15), new Long(16), new Long(17) });
+ items.put(START_LEVEL, 1);
+ items.put(STATE, "ACTIVE");
+ items.put(SYMBOLIC_NAME, "test");
+ items.put(VERSION, "0.0.0");
+ TabularData headerTable = new TabularDataSupport(HEADERS_TYPE);
+ headerTable.put(new Header("a", "a").toCompositeData());
+ headerTable.put(new Header("b", "b").toCompositeData());
+ items.put(HEADERS, headerTable);
+ CompositeData compositeData = new CompositeDataSupport(BUNDLE_TYPE, items);
+
+ BundleData b = BundleData.from(compositeData);
+
+ assertEquals("test", b.getSymbolicName());
+ assertEquals("0.0.0", b.getVersion());
+ assertEquals(2, b.getHeaders().size());
+ assertArrayEquals(new String[] { "org.apache.aries.jmx;1.0.0"} , b.getExportedPackages());
+ assertArrayEquals(new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"}, b.getImportedPackages());
+ assertArrayEquals(new long[] { 44, 66 }, b.getRequiredBundles());
+ assertArrayEquals(new long[] { 15, 16, 17 }, b.getServicesInUse());
+ assertEquals("ACTIVE", b.getState()); //default no return stub
+ assertEquals(0, b.getHosts().length);
+ assertEquals(0, b.getFragments().length);
+ }
+
+ @Test
+ public void testHeaderToCompositeData() throws Exception{
+
+ Header h1 = new Header("a", "b");
+ CompositeData compositeData = h1.toCompositeData();
+
+ assertEquals("a", compositeData.get(KEY));
+ assertEquals("b", compositeData.get(VALUE));
+
+ }
+
+ @Test
+ public void testHeaderFromCompositeData() throws Exception {
+
+ CompositeData compositeData = new CompositeDataSupport(HEADER_TYPE, new String[] { KEY, VALUE } , new String [] { "c", "d" });
+ Header header = Header.from(compositeData);
+ assertEquals("c", header.getKey());
+ assertEquals("d", header.getValue());
+
+ }
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,86 @@
+/**
+ * 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.codec;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import static org.osgi.jmx.framework.BundleStateMBean.BUNDLE_EVENT_TYPE;
+import static org.osgi.jmx.framework.BundleStateMBean.EVENT;
+import static org.osgi.jmx.framework.BundleStateMBean.IDENTIFIER;
+import static org.osgi.jmx.framework.BundleStateMBean.LOCATION;
+import static org.osgi.jmx.framework.BundleStateMBean.SYMBOLIC_NAME;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleEventDataTest {
+
+
+ @Test
+ public void testToCompositeData() throws Exception {
+
+ BundleEvent event = mock(BundleEvent.class);
+ Bundle bundle = mock(Bundle.class);
+ when(event.getBundle()).thenReturn(bundle);
+ when(bundle.getSymbolicName()).thenReturn("test");
+ when(bundle.getBundleId()).thenReturn(new Long(4));
+ when(bundle.getLocation()).thenReturn("location");
+ when(event.getType()).thenReturn(BundleEvent.INSTALLED);
+
+ BundleEventData eventData = new BundleEventData(event);
+ CompositeData eventCompositeData = eventData.toCompositeData();
+
+ assertEquals(new Long(4), (Long) eventCompositeData.get(IDENTIFIER));
+ assertEquals("test", (String) eventCompositeData.get(SYMBOLIC_NAME));
+ assertEquals(new Integer(BundleEvent.INSTALLED), (Integer) eventCompositeData.get(EVENT));
+ assertEquals("location", (String) eventCompositeData.get(LOCATION));
+
+ }
+
+
+ @Test
+ public void testFrom() throws Exception {
+
+ Map<String, Object> items = new HashMap<String, Object>();
+ items.put(IDENTIFIER, new Long(7));
+ items.put(SYMBOLIC_NAME, "t");
+ items.put(LOCATION, "l");
+ items.put(EVENT, BundleEvent.RESOLVED);
+
+ CompositeData compositeData = new CompositeDataSupport(BUNDLE_EVENT_TYPE, items);
+ BundleEventData event = BundleEventData.from(compositeData);
+
+ assertEquals(7, event.getBundleId());
+ assertEquals("t", event.getBundleSymbolicName());
+ assertEquals("l", event.getLocation());
+ assertEquals(BundleEvent.RESOLVED, event.getEventType());
+
+ }
+
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleEventDataTest.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,64 @@
+/**
+ * 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.framework;
+
+import static org.junit.Assert.*;
+
+import org.apache.aries.jmx.Logger;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+import static org.mockito.Mockito.*;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleStateMBeanHandlerTest {
+
+
+ @Test
+ public void testOpenAndClose() throws Exception {
+
+ BundleContext context = mock(BundleContext.class);
+ Logger logger = mock(Logger.class);
+
+ ServiceReference packageAdminRef = mock(ServiceReference.class);
+ PackageAdmin packageAdmin = mock(PackageAdmin.class);
+ when(context.getServiceReference(PackageAdmin.class.getName())).thenReturn(packageAdminRef);
+ when(context.getService(packageAdminRef)).thenReturn(packageAdmin);
+ ServiceReference startLevelRef = mock(ServiceReference.class);
+ StartLevel startLevel = mock(StartLevel.class);
+ when(context.getServiceReference(StartLevel.class.getName())).thenReturn(startLevelRef);
+ when(context.getService(startLevelRef)).thenReturn(startLevel);
+
+ BundleStateMBeanHandler handler = new BundleStateMBeanHandler(context, logger);
+ handler.open();
+
+ assertNotNull(handler.getMbean());
+
+ handler.close();
+ verify(context).ungetService(packageAdminRef);
+ verify(context).ungetService(startLevelRef);
+
+ }
+
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateMBeanHandlerTest.java
------------------------------------------------------------------------------
svn:keywords = Revision Date
Added: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java?rev=886708&view=auto
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java (added)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java Thu Dec 3 08:55:18 2009
@@ -0,0 +1,188 @@
+/**
+ * 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.framework;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.osgi.jmx.framework.BundleStateMBean.OBJECTNAME;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+
+import org.apache.aries.jmx.Logger;
+import org.apache.aries.jmx.codec.BundleEventData;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+
+public class BundleStateTest {
+
+ @Test
+ public void testNotificationsForBundleEvents() throws Exception {
+
+ BundleContext context = mock(BundleContext.class);
+ PackageAdmin admin = mock(PackageAdmin.class);
+ StartLevel startLevel = mock(StartLevel.class);
+ Logger logger = mock(Logger.class);
+
+ //holder for Notifications captured
+ final List<Notification> received = new LinkedList<Notification>();
+
+ BundleState bundleState = new BundleState(context, admin, startLevel, logger);
+
+ Bundle b1 = mock(Bundle.class);
+ when(b1.getBundleId()).thenReturn(new Long(9));
+ when(b1.getSymbolicName()).thenReturn("bundle");
+ when(b1.getLocation()).thenReturn("file:/location");
+
+ BundleEvent installedEvent = mock(BundleEvent.class);
+ when(installedEvent.getBundle()).thenReturn(b1);
+ when(installedEvent.getType()).thenReturn(BundleEvent.INSTALLED);
+
+ BundleEvent resolvedEvent = mock(BundleEvent.class);
+ when(resolvedEvent.getBundle()).thenReturn(b1);
+ when(resolvedEvent.getType()).thenReturn(BundleEvent.RESOLVED);
+
+ MBeanServer server = mock(MBeanServer.class);
+
+ //setup for notification
+ ObjectName objectName = new ObjectName(OBJECTNAME);
+ bundleState.preRegister(server, objectName);
+ bundleState.postRegister(true);
+
+ //add NotificationListener to receive the events
+ bundleState.addNotificationListener(new NotificationListener() {
+ public void handleNotification(Notification notification, Object handback) {
+ received.add(notification);
+ }
+ }, null, null);
+
+ // capture the BundleListener registered with BundleContext to issue BundleEvents
+ ArgumentCaptor<BundleListener> argument = ArgumentCaptor.forClass(BundleListener.class);
+ verify(context).addBundleListener(argument.capture());
+
+ //send events
+ BundleListener listener = argument.getValue();
+ listener.bundleChanged(installedEvent);
+ listener.bundleChanged(resolvedEvent);
+
+ //shutdown dispatcher via unregister callback
+ bundleState.postDeregister();
+ //check the BundleListener is cleaned up
+ verify(context).removeBundleListener(listener);
+
+ ExecutorService dispatcher = bundleState.getEventDispatcher();
+ assertTrue(dispatcher.isShutdown());
+ dispatcher.awaitTermination(2, TimeUnit.SECONDS);
+ assertTrue(dispatcher.isTerminated());
+
+ assertEquals(2, received.size());
+ Notification installed = received.get(0);
+ assertEquals(1, installed.getSequenceNumber());
+ CompositeData installedCompositeData = (CompositeData) installed.getUserData();
+ BundleEventData installedData = BundleEventData.from(installedCompositeData);
+ assertEquals("bundle", installedData.getBundleSymbolicName());
+ assertEquals(9, installedData.getBundleId());
+ assertEquals("file:/location", installedData.getLocation());
+ assertEquals(BundleEvent.INSTALLED, installedData.getEventType());
+
+ Notification resolved = received.get(1);
+ assertEquals(2, resolved.getSequenceNumber());
+ CompositeData resolvedCompositeData = (CompositeData) resolved.getUserData();
+ BundleEventData resolvedData = BundleEventData.from(resolvedCompositeData);
+ assertEquals("bundle", resolvedData.getBundleSymbolicName());
+ assertEquals(9, resolvedData.getBundleId());
+ assertEquals("file:/location", resolvedData.getLocation());
+ assertEquals(BundleEvent.RESOLVED, resolvedData.getEventType());
+
+ }
+
+ @Test
+ public void testLifeCycleOfNotificationSupport() throws Exception {
+
+ BundleContext context = mock(BundleContext.class);
+ PackageAdmin admin = mock(PackageAdmin.class);
+ StartLevel startLevel = mock(StartLevel.class);
+ Logger logger = mock(Logger.class);
+
+ BundleState bundleState = new BundleState(context, admin, startLevel, logger);
+
+ MBeanServer server1 = mock(MBeanServer.class);
+ MBeanServer server2 = mock(MBeanServer.class);
+
+ ObjectName objectName = new ObjectName(OBJECTNAME);
+ bundleState.preRegister(server1, objectName);
+ bundleState.postRegister(true);
+
+ // capture the BundleListener registered with BundleContext
+ ArgumentCaptor<BundleListener> argument = ArgumentCaptor.forClass(BundleListener.class);
+ verify(context).addBundleListener(argument.capture());
+ assertEquals(1, argument.getAllValues().size());
+
+ BundleListener listener = argument.getValue();
+ assertNotNull(listener);
+
+ ExecutorService dispatcher = bundleState.getEventDispatcher();
+
+ //do registration with another server
+ bundleState.preRegister(server2, objectName);
+ bundleState.postRegister(true);
+
+ // check no more actions on BundleContext
+ argument = ArgumentCaptor.forClass(BundleListener.class);
+ verify(context, atMost(1)).addBundleListener(argument.capture());
+ assertEquals(1, argument.getAllValues().size());
+
+ //do one unregister
+ bundleState.postDeregister();
+
+ //verify bundleListener not invoked
+ verify(context, never()).removeBundleListener(listener);
+ assertFalse(dispatcher.isShutdown());
+
+ //do second unregister and check cleanup
+ bundleState.postDeregister();
+ verify(context).removeBundleListener(listener);
+ assertTrue(dispatcher.isShutdown());
+ dispatcher.awaitTermination(2, TimeUnit.SECONDS);
+ assertTrue(dispatcher.isTerminated());
+
+
+
+ }
+}
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/framework/BundleStateTest.java
------------------------------------------------------------------------------
svn:keywords = Revision Date