You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2012/02/01 08:22:20 UTC
svn commit: r1238955 - in /karaf/cellar/trunk:
bundle/src/main/java/org/apache/karaf/cellar/bundle/
bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/
bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/
bundle/src/main/resourc...
Author: jbonofre
Date: Wed Feb 1 07:22:19 2012
New Revision: 1238955
URL: http://svn.apache.org/viewvc?rev=1238955&view=rev
Log:
[KARAF-861] Add cluster group support for bundle
Added:
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesNameCompleter.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesVersionCompleter.java
karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/shell-bundle.xml
karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarBundleTest.java
Modified:
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java
karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java
karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
Modified: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java?rev=1238955&r1=1238954&r2=1238955&view=diff
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java (original)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java Wed Feb 1 07:22:19 2012
@@ -43,38 +43,20 @@ public class BundleEventHandler extends
*/
public void handle(RemoteBundleEvent event) {
- if (event == null || event.getSourceGroup() == null || node == null || node.equals(event.getSourceNode()))
- return;
-
- Group group = event.getSourceGroup();
- String groupName = group.getName();
- String bundleLocation = event.getLocation();
-
- Map<String, BundleState> bundleTable = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
-
try {
//Check if the pid is marked as local.
- if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, bundleLocation, EventType.INBOUND)) {
- BundleState state = new BundleState();
- state.setLocation(event.getLocation());
- state.setStatus(event.getType());
-
+ if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, event.getLocation(), EventType.INBOUND)) {
if (event.getType() == BundleEvent.INSTALLED) {
installBundleFromLocation(event.getLocation());
- bundleTable.put(event.getId(), state);
LOGGER.debug("CELLAR BUNDLE: installing {}/{}", event.getSymbolicName(), event.getVersion());
} else if (event.getType() == BundleEvent.UNINSTALLED) {
uninstallBundle(event.getSymbolicName(), event.getVersion());
- bundleTable.remove(event.getId());
LOGGER.debug("CELLAR BUNDLE: uninstalling {}/{}", event.getSymbolicName(), event.getVersion());
} else if (event.getType() == BundleEvent.STARTED) {
startBundle(event.getSymbolicName(), event.getVersion());
- bundleTable.put(event.getId(), state);
LOGGER.debug("CELLAR BUNDLE: starting {}/{}", event.getSymbolicName(), event.getVersion());
} else if (event.getType() == BundleEvent.STOPPED) {
stopBundle(event.getSymbolicName(), event.getVersion());
- state.setStatus(BundleEvent.INSTALLED);
- bundleTable.put(event.getId(), state);
LOGGER.debug("CELLAR BUNDLE: stopping {}/{}", event.getSymbolicName(), event.getVersion());
} else if (event.getType() == BundleEvent.UPDATED) {
updateBundle(event.getSymbolicName(), event.getVersion());
Modified: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java?rev=1238955&r1=1238954&r2=1238955&view=diff
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java (original)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java Wed Feb 1 07:22:19 2012
@@ -84,9 +84,9 @@ public class BundleSynchronizer extends
try {
if (state.getStatus() == BundleEvent.INSTALLED) {
installBundleFromLocation(state.getLocation());
- startBundle(symbolicName, version);
} else if (state.getStatus() == BundleEvent.STARTED) {
installBundleFromLocation(state.getLocation());
+ startBundle(symbolicName, version);
}
} catch (BundleException e) {
LOGGER.error("CELLAR BUNDLE: error while pulling bundle", e);
@@ -99,7 +99,7 @@ public class BundleSynchronizer extends
}
/**
- * Publishses local configuration to the cluster.
+ * Publishes local configuration to the cluster.
*/
public void push(Group group) {
@@ -128,9 +128,11 @@ public class BundleSynchronizer extends
RemoteBundleEvent event = null;
if (existingState == null) {
event = new RemoteBundleEvent(symbolicName, version, bundleLocation, status);
- } else if (bundleState.getStatus() == BundleEvent.STARTED) {
- event = new RemoteBundleEvent(symbolicName, version, bundleLocation, status);
+ // update the cluster map
+ bundleTable.put(id, bundleState);
}
+
+ // broadcast the event
if (producerList != null && !producerList.isEmpty() && event != null) {
for (EventProducer producer : producerList) {
producer.produce(event);
Modified: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java?rev=1238955&r1=1238954&r2=1238955&view=diff
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java (original)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java Wed Feb 1 07:22:19 2012
@@ -18,7 +18,4 @@ public class Constants {
public static final String CATEGORY = "bundle";
public static final String BUNDLE_MAP = "org.apache.karaf.cellar.bundle.map";
- private Constants() {
- }
-
}
Modified: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java?rev=1238955&r1=1238954&r2=1238955&view=diff
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java (original)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java Wed Feb 1 07:22:19 2012
@@ -13,6 +13,7 @@
*/
package org.apache.karaf.cellar.bundle;
+import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.Group;
import org.apache.karaf.cellar.core.Node;
import org.apache.karaf.cellar.core.event.EventProducer;
@@ -23,6 +24,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
+import java.util.Map;
import java.util.Set;
public class LocalBundleListener extends BundleSupport implements BundleListener {
@@ -45,29 +47,39 @@ public class LocalBundleListener extends
try {
groups = groupManager.listLocalGroups();
} catch (Exception ex) {
- LOGGER.warn("Failed to list local groups. Is Cellar uninstalling?");
+ LOGGER.warn("Failed to list local groups. Is Cellar uninstalling ?");
}
if (groups != null && !groups.isEmpty()) {
for (Group group : groups) {
String symbolicName = event.getBundle().getSymbolicName();
-
- if (symbolicName != null) {
- String version = event.getBundle().getVersion().toString();
- String bundleLocation = event.getBundle().getLocation();
- int type = event.getType();
- if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.OUTBOUND)) {
- RemoteBundleEvent remoteBundleEvent = new RemoteBundleEvent(symbolicName, version, bundleLocation, type);
- remoteBundleEvent.setSourceGroup(group);
- remoteBundleEvent.setSourceNode(node);
- if (producerList != null && !producerList.isEmpty()) {
- for (EventProducer producer : producerList) {
- producer.produce(remoteBundleEvent);
- }
+ String version = event.getBundle().getVersion().toString();
+ String bundleLocation = event.getBundle().getLocation();
+ int type = event.getType();
+
+ if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.OUTBOUND)) {
+ RemoteBundleEvent remoteBundleEvent = new RemoteBundleEvent(symbolicName, version, bundleLocation, type);
+ remoteBundleEvent.setSourceGroup(group);
+ remoteBundleEvent.setSourceNode(node);
+
+ // update the cluster map
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + group.getName());
+ BundleState state = bundles.get(symbolicName + "/" + version);
+ if (state == null) {
+ state = new BundleState();
+ }
+ state.setStatus(type);
+ state.setLocation(event.getBundle().getLocation());
+ bundles.put(symbolicName + "/" + version, state);
+
+ // broadcast the cluster event
+ if (producerList != null && !producerList.isEmpty()) {
+ for (EventProducer producer : producerList) {
+ producer.produce(remoteBundleEvent);
}
- } else LOGGER.debug("CELLAR BUNDLE: bundle {} is marked as BLOCKED OUTBOUND", symbolicName);
- } else LOGGER.debug("CELLAR BUNDLE: artifact is not a bundle");
+ }
+ } else LOGGER.debug("CELLAR BUNDLE: bundle {} is marked as BLOCKED OUTBOUND", symbolicName);
}
}
}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,74 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.bundle.BundleState;
+import org.apache.karaf.cellar.bundle.Constants;
+import org.apache.karaf.cellar.bundle.RemoteBundleEvent;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.osgi.framework.BundleEvent;
+
+import java.net.URL;
+import java.util.Map;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+@Command(scope = "cluster", name = "bundle-install", description = "Install a bundle assigned to a cluster group.")
+public class InstallBundleCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name.", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "location", description = "The bundle location.", required = true, multiValued = false)
+ String location;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Group group = groupManager.findGroupByName(groupName);
+
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " does't exist");
+ return null;
+ }
+
+ // get the name and version in the location MANIFEST
+ JarInputStream jarInputStream = new JarInputStream(new URL(location).openStream());
+ Manifest manifest = jarInputStream.getManifest();
+ String name = manifest.getMainAttributes().getValue("Bundle-SymbolicName");
+ String version = manifest.getMainAttributes().getValue("Bundle-Version");
+ jarInputStream.close();
+
+ // populate the cluster map
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+ BundleState state = new BundleState();
+ state.setLocation(location);
+ state.setStatus(BundleEvent.INSTALLED);
+ bundles.put(name + "/" + version, state);
+
+ // broadcast the event
+ EventProducer producer = eventTransportFactory.getEventProducer(groupName, true);
+ RemoteBundleEvent event = new RemoteBundleEvent(name, version, location, BundleEvent.INSTALLED);
+ event.setForce(true);
+ event.setSourceGroup(group);
+ producer.produce(event);
+
+ return null;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,94 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.bundle.BundleState;
+import org.apache.karaf.cellar.bundle.Constants;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.osgi.framework.BundleEvent;
+
+import java.util.Map;
+
+@Command(scope = "cluster", name = "bundle-list", description = "List the bundles assigned to a cluster group.")
+public class ListBundleCommand extends CellarCommandSupport {
+
+ protected static final String OUTPUT_FORMAT = "%-50s %-20s %-15s %-20s";
+
+ @Argument(index = 0, name = "group", description = "The cluster group name.", required = true, multiValued = false)
+ String groupName;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Group group = groupManager.findGroupByName(groupName);
+
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+ if (bundles != null && !bundles.isEmpty()) {
+ System.out.println(String.format("Bundles for cluster group: " + groupName));
+ System.out.println(String.format(OUTPUT_FORMAT, "Name", "Version", "Status", "Location"));
+ for (String bundle : bundles.keySet()) {
+ String[] tokens = bundle.split("/");
+ String name = tokens[0];
+ String version = tokens[1];
+ BundleState state = bundles.get(bundle);
+ String status;
+ switch (state.getStatus()) {
+ case BundleEvent.INSTALLED:
+ status = "Installed";
+ break;
+ case BundleEvent.RESOLVED:
+ status = "Resolved";
+ break;
+ case BundleEvent.STARTED:
+ status = "Started";
+ break;
+ case BundleEvent.STARTING:
+ status = "Starting";
+ break;
+ case BundleEvent.STOPPED:
+ status = "Stopped";
+ break;
+ case BundleEvent.STOPPING:
+ status = "Stopping";
+ break;
+ case BundleEvent.UNINSTALLED:
+ status = "Uninstalled";
+ break;
+ default:
+ status = "";
+ break;
+ }
+ System.out.println(String.format(OUTPUT_FORMAT, name, version, status, state.getLocation()));
+ }
+ } else {
+ System.err.println("No bundles found for cluster group: " + groupName);
+ }
+ } finally {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+ return null;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,76 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.bundle.BundleState;
+import org.apache.karaf.cellar.bundle.Constants;
+import org.apache.karaf.cellar.bundle.RemoteBundleEvent;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.osgi.framework.BundleEvent;
+
+import java.util.Map;
+
+@Command(scope = "cluster", name = "bundle-start", description = "Start a bundle assigned to a cluster group.")
+public class StartBundleCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name.", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "name", description = "The bundle symbolic name.", required = true, multiValued = false)
+ String name;
+
+ @Argument(index = 2, name = "version", description = "The bundle version.", required = true, multiValued = false)
+ String version;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Group group = groupManager.findGroupByName(groupName);
+
+ if (group == null) {
+ System.err.println("Group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ // update the distributed map
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+ BundleState state = bundles.get(name + "/" + version);
+ if (state == null) {
+ System.err.println("Bundle " + name + "/" + version + " not found in cluster group " + groupName);
+ return null;
+ }
+ state.setStatus(BundleEvent.STARTED);
+ bundles.put(name + "/" + version, state);
+ } finally {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+
+ // broadcast the event
+ EventProducer producer = eventTransportFactory.getEventProducer(groupName, true);
+ RemoteBundleEvent event = new RemoteBundleEvent(name, version, null, BundleEvent.STARTED);
+ event.setForce(true);
+ event.setSourceGroup(group);
+ producer.produce(event);
+
+ return null;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,76 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.bundle.BundleState;
+import org.apache.karaf.cellar.bundle.Constants;
+import org.apache.karaf.cellar.bundle.RemoteBundleEvent;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.osgi.framework.BundleEvent;
+
+import java.util.Map;
+
+@Command(scope = "cluster", name = "bundle-stop", description = "Stop a bundle assigned to a cluster group.")
+public class StopBundleCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name.", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "name", description = "The bundle symbolic name.", required = true, multiValued = false)
+ String name;
+
+ @Argument(index = 2, name = "version", description = "The bundle version.", required = true, multiValued = false)
+ String version;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Group group = groupManager.findGroupByName(groupName);
+
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ // update the cluster map
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+ BundleState state = bundles.get(name + "/" + version);
+ if (state == null) {
+ System.err.println("Bundle " + name + "/" + version + " not found in cluster group " + groupName);
+ return null;
+ }
+ state.setStatus(BundleEvent.STOPPED);
+ bundles.put(name + "/" + version, state);
+ } finally {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+
+ // broadcast the event
+ EventProducer producer = eventTransportFactory.getEventProducer(groupName, true);
+ RemoteBundleEvent event = new RemoteBundleEvent(name, version, null, BundleEvent.STOPPED);
+ event.setForce(true);
+ event.setSourceGroup(group);
+ producer.produce(event);
+
+ return null;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.bundle.BundleState;
+import org.apache.karaf.cellar.bundle.Constants;
+import org.apache.karaf.cellar.bundle.RemoteBundleEvent;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.osgi.framework.BundleEvent;
+
+import java.util.Map;
+
+@Command(scope = "cluster", name = "bundle-uninstall", description = "Uninstall a bundle assigned to a cluster group.")
+public class UninstallBundleCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name.", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "name", description = "The bundle symbolic name.", required = true, multiValued = false)
+ String name;
+
+ @Argument(index = 2, name = "version", description = "The bundle version.", required = true, multiValued = false)
+ String version;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Group group = groupManager.findGroupByName(groupName);
+
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ // update the cluster map
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Map<String, BundleState> bundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+ BundleState state = bundles.get(name + "/" + version);
+ if (state == null) {
+ System.err.println("Bundle " + name + "/" + version + " not found in cluster group " + groupName);
+ return null;
+ }
+ bundles.remove(name + "/" + version);
+ } finally {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+
+ // broadcast the event
+ EventProducer producer = eventTransportFactory.getEventProducer(groupName, true);
+ RemoteBundleEvent event = new RemoteBundleEvent(name, version, null, BundleEvent.UNINSTALLED);
+ event.setForce(true);
+ event.setSourceGroup(group);
+ producer.produce(event);
+
+ return null;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesNameCompleter.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesNameCompleter.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesNameCompleter.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesNameCompleter.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell.completers;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import java.util.List;
+
+/**
+ * Completer on all bundle symbolic name.
+ */
+public class AllBundlesNameCompleter implements Completer {
+
+ private BundleContext bundleContext;
+
+ public int complete(String buffer, int cursor, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ for (Bundle bundle : bundleContext.getBundles()) {
+ delegate.getStrings().add(bundle.getSymbolicName());
+ }
+ return delegate.complete(buffer, cursor, candidates);
+ }
+
+ public BundleContext getBundleContext() {
+ return this.bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+}
Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesVersionCompleter.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesVersionCompleter.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesVersionCompleter.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/completers/AllBundlesVersionCompleter.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.bundle.shell.completers;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import java.util.List;
+
+/**
+ * Completer on all bundle version..
+ */
+public class AllBundlesVersionCompleter implements Completer {
+
+ private BundleContext bundleContext;
+
+ public int complete(String buffer, int cursor, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ for (Bundle bundle : bundleContext.getBundles()) {
+ delegate.getStrings().add(bundle.getVersion().toString());
+ }
+ return delegate.complete(buffer, cursor, candidates);
+ }
+
+ public BundleContext getBundleContext() {
+ return this.bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+}
Modified: karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml?rev=1238955&r1=1238954&r2=1238955&view=diff
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml (original)
+++ karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml Wed Feb 1 07:22:19 2012
@@ -48,10 +48,13 @@
<entry key="managed" value="true"/>
</service-properties>
</service>
+ <service ref="synchronizer" interface="org.apache.karaf.cellar.core.Synchronizer"/>
<reference id="clusterManager" interface="org.apache.karaf.cellar.core.ClusterManager"/>
<reference id="groupManager" interface="org.apache.karaf.cellar.core.GroupManager"/>
<reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>
+ <reference id="eventTransportFactory" interface="org.apache.karaf.cellar.core.event.EventTransportFactory"/>
+ <reference id="eventProducer" interface="org.apache.karaf.cellar.core.event.EventProducer"/>
<reference-list id="groupEventProducers" member-type="service-object"
interface="org.apache.karaf.cellar.core.event.EventProducer" filter="(type=group)"/>
Added: karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/shell-bundle.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/shell-bundle.xml?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/shell-bundle.xml (added)
+++ karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/shell-bundle.xml Wed Feb 1 07:22:19 2012
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
+
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
+ <command name="cluster/bundle-list">
+ <action class="org.apache.karaf.cellar.bundle.shell.ListBundleCommand">
+ <property name="clusterManager" ref="clusterManager"/>
+ <property name="groupManager" ref="groupManager"/>
+ <property name="eventTransportFactory" ref="eventTransportFactory"/>
+ </action>
+ <completers>
+ <ref component-id="allGroupCompleter"/>
+ </completers>
+ </command>
+ <command name="cluster/bundle-install">
+ <action class="org.apache.karaf.cellar.bundle.shell.InstallBundleCommand">
+ <property name="clusterManager" ref="clusterManager"/>
+ <property name="groupManager" ref="groupManager"/>
+ <property name="eventTransportFactory" ref="eventTransportFactory"/>
+ </action>
+ <completers>
+ <ref component-id="allGroupCompleter"/>
+ </completers>
+ </command>
+ <command name="cluster/bundle-uninstall">
+ <action class="org.apache.karaf.cellar.bundle.shell.UninstallBundleCommand">
+ <property name="clusterManager" ref="clusterManager"/>
+ <property name="groupManager" ref="groupManager"/>
+ <property name="eventTransportFactory" ref="eventTransportFactory"/>
+ </action>
+ <completers>
+ <ref component-id="allGroupCompleter"/>
+ <ref component-id="allBundlesNameCompleter"/>
+ <ref component-id="allBundlesVersionCompleter"/>
+ </completers>
+ </command>
+ <command name="cluster/bundle-start">
+ <action class="org.apache.karaf.cellar.bundle.shell.StartBundleCommand">
+ <property name="clusterManager" ref="clusterManager"/>
+ <property name="groupManager" ref="groupManager"/>
+ <property name="eventTransportFactory" ref="eventTransportFactory"/>
+ </action>
+ <completers>
+ <ref component-id="allGroupCompleter"/>
+ <ref component-id="allBundlesNameCompleter"/>
+ <ref component-id="allBundlesVersionCompleter"/>
+ </completers>
+ </command>
+ <command name="cluster/bundle-stop">
+ <action class="org.apache.karaf.cellar.bundle.shell.StopBundleCommand">
+ <property name="clusterManager" ref="clusterManager"/>
+ <property name="groupManager" ref="groupManager"/>
+ <property name="eventTransportFactory" ref="eventTransportFactory"/>
+ </action>
+ <completers>
+ <ref component-id="allGroupCompleter"/>
+ <ref component-id="allBundlesNameCompleter"/>
+ <ref component-id="allBundlesVersionCompleter"/>
+ </completers>
+ </command>
+ </command-bundle>
+
+ <bean id="allGroupCompleter" class="org.apache.karaf.cellar.core.shell.completer.AllGroupsCompleter">
+ <property name="groupManager" ref="groupManager"/>
+ </bean>
+
+ <bean id="allBundlesNameCompleter" class="org.apache.karaf.cellar.bundle.shell.completers.AllBundlesNameCompleter">
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ </bean>
+
+ <bean id="allBundlesVersionCompleter" class="org.apache.karaf.cellar.bundle.shell.completers.AllBundlesVersionCompleter">
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ </bean>
+
+</blueprint>
\ No newline at end of file
Added: karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarBundleTest.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarBundleTest.java?rev=1238955&view=auto
==============================================================================
--- karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarBundleTest.java (added)
+++ karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarBundleTest.java Wed Feb 1 07:22:19 2012
@@ -0,0 +1,60 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.itests;
+
+import org.apache.karaf.cellar.core.ClusterManager;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openengsb.labs.paxexam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
+
+import static org.junit.Assert.assertNotNull;
+import static org.openengsb.labs.paxexam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.openengsb.labs.paxexam.karaf.options.KarafDistributionOption.logLevel;
+
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class CellarBundleTest extends CellarTestSupport {
+
+ @Test
+ public void testCellarBundleModule() throws Exception {
+ installCellar();
+ Thread.sleep(DEFAULT_TIMEOUT);
+ ClusterManager clusterManager = getOsgiService(ClusterManager.class);
+ assertNotNull(clusterManager);
+
+ System.err.println(executeCommand("cluster:bundle-list default"));
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ unInstallCellar();
+ } catch (Exception ex) {
+ //Ignore
+ }
+ }
+
+ @Configuration
+ public Option[] config() {
+ return new Option[]{
+ cellarDistributionConfiguration(), keepRuntimeFolder(), logLevel(LogLevelOption.LogLevel.ERROR)};
+ }
+
+}