Repository: karaf-cellar Updated Branches: refs/heads/master faa015365 -> 529c16083
[KARAF-3051] Refactore Cellar bundle module (commands and MBean) to use "look'n feel" from Karaf 3.x Project: http://git-wip-us.apache.org/repos/asf/karaf-cellar/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf-cellar/commit/529c1608 Tree: http://git-wip-us.apache.org/repos/asf/karaf-cellar/tree/529c1608 Diff: http://git-wip-us.apache.org/repos/asf/karaf-cellar/diff/529c1608 Branch: refs/heads/master Commit: 529c16083e8fbdccc019e451d8434b3120ebf346 Parents: faa0153 Author: Jean-Baptiste Onofré <[email protected]> Authored: Tue Jun 17 16:33:47 2014 +0200 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Tue Jun 17 16:33:47 2014 +0200 ---------------------------------------------------------------------- bundle/pom.xml | 6 + .../bundle/management/CellarBundleMBean.java | 25 +- .../internal/CellarBundleMBeanImpl.java | 334 ++++++++++--------- .../bundle/shell/BundleCommandSupport.java | 161 +++++---- .../bundle/shell/InstallBundleCommand.java | 5 + .../cellar/bundle/shell/ListBundleCommand.java | 26 +- .../cellar/bundle/shell/StartBundleCommand.java | 62 ++-- .../cellar/bundle/shell/StopBundleCommand.java | 61 ++-- .../bundle/shell/UninstallBundleCommand.java | 59 ++-- config/pom.xml | 1 + pom.xml | 5 + 11 files changed, 409 insertions(+), 336 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/pom.xml ---------------------------------------------------------------------- diff --git a/bundle/pom.xml b/bundle/pom.xml index 0420dc8..4125073 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -75,6 +75,12 @@ <artifactId>org.apache.karaf.features.core</artifactId> </dependency> + <!-- Shell table --> + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.table</artifactId> + </dependency> + <!-- Logging Dependencies --> <dependency> <groupId>org.slf4j</groupId> http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/CellarBundleMBean.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/CellarBundleMBean.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/CellarBundleMBean.java index 558df61..996aa72 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/CellarBundleMBean.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/CellarBundleMBean.java @@ -30,34 +30,41 @@ public interface CellarBundleMBean { void install(String group, String location) throws Exception; /** + * Install and eventually start a bundle in a cluster group. + * + * @param group the cluster group name. + * @param location the bundle location. + * @param start true to start the bundle, false else. + * @throws Exception + */ + void install(String group, String location, boolean start) throws Exception; + + /** * Uninstall a bundle from a cluster group. * * @param group the cluster group name. - * @param symbolicName the bundle symbolic name. - * @param version the bundle version. + * @param id the bundle id. * @throws Exception in case of uninstall failure. */ - void uninstall(String group, String symbolicName, String version) throws Exception; + void uninstall(String group, String id) throws Exception; /** * Start a bundle in a cluster group. * * @param group the cluster group name. - * @param symbolicName the bundle symbolic name. - * @param version the bundle version. + * @param id the bundle id. * @throws Exception in case of start failure. */ - void start(String group, String symbolicName, String version) throws Exception; + void start(String group, String id) throws Exception; /** * Stop a bundle in a cluster group. * * @param group the cluster group name. - * @param symbolicName the bundle symbolic name. - * @param version the bundle version. + * @param id the bundle id. * @throws Exception in case of stop failure. */ - void stop(String group, String symbolicName, String version) throws Exception; + void stop(String group, String id) throws Exception; /** * Get the bundles in a cluster group. http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java index f6b5d8a..d01b045 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java @@ -28,6 +28,8 @@ import javax.management.NotCompliantMBeanException; import javax.management.StandardMBean; import javax.management.openmbean.*; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.jar.JarInputStream; import java.util.jar.Manifest; @@ -82,6 +84,11 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle @Override public void install(String groupName, String location) throws Exception { + this.install(groupName, location, false); + } + + @Override + public void install(String groupName, String location, boolean start) throws Exception { // check if cluster group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -123,7 +130,11 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle BundleState state = new BundleState(); state.setName(name); state.setLocation(location); - state.setStatus(BundleEvent.INSTALLED); + if (start) { + state.setStatus(BundleEvent.STARTED); + } else { + state.setStatus(BundleEvent.INSTALLED); + } clusterBundles.put(name + "/" + version, state); } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); @@ -133,10 +144,15 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle ClusterBundleEvent event = new ClusterBundleEvent(name, version, location, BundleEvent.INSTALLED); event.setSourceGroup(group); eventProducer.produce(event); + if (start) { + event = new ClusterBundleEvent(name, version, location, BundleEvent.STARTED); + event.setSourceGroup(group); + eventProducer.produce(event); + } } @Override - public void uninstall(String groupName, String symbolicName, String version) throws Exception { + public void uninstall(String groupName, String id) throws Exception { // check if the cluster group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -152,46 +168,45 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String key = null; - String location = null; try { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(symbolicName, version, clusterBundles); + List<String> bundles = selector(id, clusterBundles); - if (key == null) { - throw new IllegalArgumentException("Bundle " + key + " is not found in cluster group " + groupName); - } + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + continue; + } + String location = state.getLocation(); + + // check if the bundle location is allowed outbound + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + continue; + } - BundleState state = clusterBundles.get(key); - if (state == null) { - throw new IllegalArgumentException("Bundle " + key + " is not found in cluster group " + groupName); - } - location = state.getLocation(); - - // check if the bundle location is allowed outbound - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - throw new IllegalArgumentException("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - } + // update the cluster state + clusterBundles.remove(bundle); - clusterBundles.remove(key); + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.UNINSTALLED); + event.setSourceGroup(group); + eventProducer.produce(event); + } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - // broadcast the event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.UNINSTALLED); - event.setSourceGroup(group); - eventProducer.produce(event); + } @Override - public void start(String groupName, String symbolicName, String version) throws Exception { + public void start(String groupName, String id) throws Exception { // check if the cluster group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -206,47 +221,45 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle // update the cluster group ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String key = null; - String location = null; try { + Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(symbolicName, version, clusterBundles); + List<String> bundles = selector(id, clusterBundles); - if (key == null) { - throw new IllegalStateException("Bundle " + key + " not found in cluster group " + groupName); - } + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + continue; + } + String location = state.getLocation(); + + // check if the bundle location is allowed + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + continue; + } - BundleState state = clusterBundles.get(key); - if (state == null) { - throw new IllegalStateException("Bundle " + key + " not found in cluster group " + groupName); - } - location = state.getLocation(); - - // check if the bundle location is allowed - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - throw new IllegalArgumentException("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - } + // update the cluster state + state.setStatus(BundleEvent.STARTED); + clusterBundles.put(bundle, state); - state.setStatus(BundleEvent.STARTED); - clusterBundles.put(key, state); + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STARTED); + event.setSourceGroup(group); + eventProducer.produce(event); + } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - - // broadcast the cluster event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STARTED); - event.setSourceGroup(group); - eventProducer.produce(event); } @Override - public void stop(String groupName, String symbolicName, String version) throws Exception { + public void stop(String groupName, String id) throws Exception { // check if the cluster group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -261,43 +274,40 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle // update the cluster group ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String key = null; - String location = null; try { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(symbolicName, version, clusterBundles); + List<String> bundles = selector(id, clusterBundles); - if (key == null) { - throw new IllegalStateException("Bundle " + key + " not found in cluster group " + groupName); - } + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + continue; + } + String location = state.getLocation(); + + // check if the bundle location is allowed outbound + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + continue; + } - BundleState state = clusterBundles.get(key); - if (state == null) { - throw new IllegalStateException("Bundle " + key + " not found in cluster group " + groupName); - } - location = state.getLocation(); - - // check if the bundle location is allowed outbound - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - throw new IllegalArgumentException("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - } + // update the cluster state + state.setStatus(BundleEvent.STOPPED); + clusterBundles.put(bundle, state); - state.setStatus(BundleEvent.STOPPED); - clusterBundles.put(key, state); + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STOPPED); + event.setSourceGroup(group); + eventProducer.produce(event); + } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - - // broadcast the cluster event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STOPPED); - event.setSourceGroup(group); - eventProducer.produce(event); } @Override @@ -306,7 +316,7 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle new String[]{"id", "name", "version", "status", "location"}, new String[]{"ID of the bundle", "Name of the bundle", "Version of the bundle", "Current status of the bundle", "Location of the bundle"}, new OpenType[]{SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING}); - TabularType tableType = new TabularType("Bundles", "Table of all KarafCellar bundles", compositeType, + TabularType tableType = new TabularType("Bundles", "Table of all Karaf Cellar bundles", compositeType, new String[]{"name", "version"}); TabularData table = new TabularDataSupport(tableType); @@ -366,101 +376,117 @@ public class CellarBundleMBeanImpl extends StandardMBean implements CellarBundle } /** - * Bundle selector. + * Bundle selector on the cluster. * - * @param name the bundle name, regex, or ID. - * @param version the bundle version. - * @param clusterBundles the cluster bundles map. * @return the bundle key is the distributed bundle map. */ - private String selector(String name, String version, Map<String, BundleState> clusterBundles) { - String key = null; - if (version == null || version.trim().isEmpty()) { - // looking for bundle using ID - int id = -1; - try { - id = Integer.parseInt(name); - int index = 0; - for (String clusterBundle : clusterBundles.keySet()) { - if (index == id) { - key = clusterBundle; - break; - } - index++; + protected List<String> selector(String id, Map<String, BundleState> clusterBundles) { + List<String> bundles = new ArrayList<String>(); + + addMatchingBundles(id, bundles, clusterBundles); + + return bundles; + } + + protected void addMatchingBundles(String id, List<String> bundles, Map<String, BundleState> clusterBundles) { + + // id is a number + Pattern pattern = Pattern.compile("^\\d+$"); + Matcher matcher = pattern.matcher(id); + if (matcher.find()) { + int idInt = Integer.parseInt(id); + int index = 0; + for (String bundle : clusterBundles.keySet()) { + if (index == idInt) { + bundles.add(bundle); + break; } - } catch (NumberFormatException nfe) { - // ignore + index++; } - if (id == -1) { - - // add regex support - Pattern namePattern = Pattern.compile(name); + return; + } - // looking for bundle using only the name + // id as a number range + pattern = Pattern.compile("^(\\d+)-(\\d+)$"); + matcher = pattern.matcher(id); + if (matcher.find()) { + int index = id.indexOf('-'); + long startId = Long.parseLong(id.substring(0, index)); + long endId = Long.parseLong(id.substring(index + 1)); + if (startId < endId) { + int bundleIndex = 0; for (String bundle : clusterBundles.keySet()) { - BundleState state = clusterBundles.get(bundle); - if (state.getName() != null) { - // bundle name is populated, check if it matches the regex - Matcher matcher = namePattern.matcher(state.getName()); - if (matcher.find()) { - key = bundle; - break; - } else { - // no match on bundle name, fall back to symbolic name and check if it matches the regex - String[] split = bundle.split("/"); - matcher = namePattern.matcher(split[0]); - if (matcher.find()) { - key = bundle; - break; - } - } - } else { - // no bundle name, fall back to symbolic name and check if it matches the regex - String[] split = bundle.split("/"); - Matcher matcher = namePattern.matcher(split[0]); - if (matcher.find()) { - key = bundle; - break; - } + if (bundleIndex >= startId && bundleIndex <= endId) { + bundles.add(bundle); } + bundleIndex++; } } - } else { - // looking for the bundle using name and version - - // add regex support of the name - Pattern namePattern = Pattern.compile(name); + return; + } + int index = id.indexOf('/'); + if (index != -1) { + // id is name/version + String[] idSplit = id.split("/"); + String name = idSplit[0]; + String version = idSplit[1]; for (String bundle : clusterBundles.keySet()) { - String[] split = bundle.split("/"); - BundleState state = clusterBundles.get(bundle); - if (split[1].equals(version)) { + String[] bundleSplit = bundle.split("/"); + if (bundleSplit[1].equals(version)) { + // regex on the name + Pattern namePattern = Pattern.compile(name); + BundleState state = clusterBundles.get(bundle); if (state.getName() != null) { // bundle name is populated, check if it matches the regex - Matcher matcher = namePattern.matcher(state.getName()); + matcher = namePattern.matcher(state.getName()); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } else { // no match on bundle name, fall back to symbolic name and check if it matches the regex - matcher = namePattern.matcher(split[0]); + matcher = namePattern.matcher(name); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } } } else { // no bundle name, fall back to symbolic name and check if it matches the regex - Matcher matcher = namePattern.matcher(split[0]); + matcher = namePattern.matcher(name); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } } } } + return; + } + + // id is just name + // regex support on the name + Pattern namePattern = Pattern.compile(id); + // looking for bundle using only the name + for (String bundle : clusterBundles.keySet()) { + BundleState state = clusterBundles.get(bundle); + if (state.getName() != null) { + // bundle name is populated, check if it matches the regex + matcher = namePattern.matcher(state.getName()); + if (matcher.find()) { + bundles.add(bundle); + } else { + // no match on bundle name, fall back to symbolic name and check if it matches the regex + matcher = namePattern.matcher(bundle); + if (matcher.find()) { + bundles.add(bundle); + } + } + } else { + // no bundle name, fall back to symbolic name and check if it matches the regex + matcher = namePattern.matcher(bundle); + if (matcher.find()) { + bundles.add(bundle); + } + } } - return key; } } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java index 97cc59b..6295743 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java @@ -17,6 +17,8 @@ import org.apache.karaf.cellar.bundle.BundleState; import org.apache.karaf.cellar.core.shell.CellarCommandSupport; import org.apache.karaf.shell.commands.Argument; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,11 +28,8 @@ public abstract class BundleCommandSupport extends CellarCommandSupport { @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false) String groupName; - @Argument(index = 1, name = "id", description = "The bundle ID or name", required = true, multiValued = false) - String name; - - @Argument(index = 2, name = "version", description = "The bundle version", required = false, multiValued = false) - String version; + @Argument(index = 1, name = "ids", description = "The list of bundle (identified by IDs or name or name/version) separated by whitespaces", required = true, multiValued = true) + List<String> ids; protected abstract Object doExecute() throws Exception; @@ -39,95 +38,121 @@ public abstract class BundleCommandSupport extends CellarCommandSupport { * * @return the bundle key is the distributed bundle map. */ - protected String selector(Map<String, BundleState> clusterBundles) { - String key = null; - if (version == null) { - // looking for bundle using ID - int id = -1; - try { - id = Integer.parseInt(name); - int index = 0; - for (String bundle : clusterBundles.keySet()) { - if (index == id) { - key = bundle; - break; - } - index++; + protected List<String> selector(Map<String, BundleState> clusterBundles) { + List<String> bundles = new ArrayList<String>(); + + if (ids != null && !ids.isEmpty()) { + for (String id : ids) { + if (id == null) { + continue; } - } catch (NumberFormatException nfe) { - // ignore + + addMatchingBundles(id, bundles, clusterBundles); + } - if (id == -1) { + } + return bundles; + } - // add regex support - Pattern namePattern = Pattern.compile(name); + protected void addMatchingBundles(String id, List<String> bundles, Map<String, BundleState> clusterBundles) { - // looking for bundle using only the name + // id is a number + Pattern pattern = Pattern.compile("^\\d+$"); + Matcher matcher = pattern.matcher(id); + if (matcher.find()) { + int idInt = Integer.parseInt(id); + int index = 0; + for (String bundle : clusterBundles.keySet()) { + if (index == idInt) { + bundles.add(bundle); + break; + } + index++; + } + return; + } + + // id as a number range + pattern = Pattern.compile("^(\\d+)-(\\d+)$"); + matcher = pattern.matcher(id); + if (matcher.find()) { + int index = id.indexOf('-'); + long startId = Long.parseLong(id.substring(0, index)); + long endId = Long.parseLong(id.substring(index + 1)); + if (startId < endId) { + int bundleIndex = 0; for (String bundle : clusterBundles.keySet()) { - BundleState state = clusterBundles.get(bundle); - if (state.getName() != null) { - // bundle name is populated, check if it matches the regex - Matcher matcher = namePattern.matcher(state.getName()); - if (matcher.find()) { - key = bundle; - break; - } else { - // not matched on bundle name, fall back to symbolic name and check if it matches the regex - String split[] = bundle.split("/"); - matcher = namePattern.matcher(split[0]); - if (matcher.find()) { - key = bundle; - break; - } - } - } else { - // no bundle name, fall back to symbolic name and check if it matches the regex - String split[] = bundle.split("/"); - System.out.println("Bundle-SymbolicName: " + split[0]); - Matcher matcher = namePattern.matcher(split[0]); - if (matcher.find()) { - key = bundle; - break; - } + if (bundleIndex >= startId && bundleIndex <= endId) { + bundles.add(bundle); } + bundleIndex++; } } - } else { - // looking for the bundle using name and version - - // add regex support of the name - Pattern namePattern = Pattern.compile(name); + return; + } + int index = id.indexOf('/'); + if (index != -1) { + // id is name/version + String[] idSplit = id.split("/"); + String name = idSplit[0]; + String version = idSplit[1]; for (String bundle : clusterBundles.keySet()) { - String[] split = bundle.split("/"); - BundleState state = clusterBundles.get(bundle); - if (split[1].equals(version)) { + String[] bundleSplit = bundle.split("/"); + if (bundleSplit[1].equals(version)) { + // regex on the name + Pattern namePattern = Pattern.compile(name); + BundleState state = clusterBundles.get(bundle); if (state.getName() != null) { // bundle name is populated, check if it matches the regex - Matcher matcher = namePattern.matcher(state.getName()); + matcher = namePattern.matcher(state.getName()); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } else { // no match on bundle name, fall back to symbolic name and check if it matches the regex - matcher = namePattern.matcher(split[0]); + matcher = namePattern.matcher(name); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } } } else { // no bundle name, fall back to symbolic name and check if it matches the regex - Matcher matcher = namePattern.matcher(split[0]); + matcher = namePattern.matcher(name); if (matcher.find()) { - key = bundle; - break; + bundles.add(bundle); } } } } + return; + } + + // id is just name + // regex support on the name + Pattern namePattern = Pattern.compile(id); + // looking for bundle using only the name + for (String bundle : clusterBundles.keySet()) { + BundleState state = clusterBundles.get(bundle); + if (state.getName() != null) { + // bundle name is populated, check if it matches the regex + matcher = namePattern.matcher(state.getName()); + if (matcher.find()) { + bundles.add(bundle); + } else { + // no match on bundle name, fall back to symbolic name and check if it matches the regex + matcher = namePattern.matcher(bundle); + if (matcher.find()) { + bundles.add(bundle); + } + } + } else { + // no bundle name, fall back to symbolic name and check if it matches the regex + matcher = namePattern.matcher(bundle); + if (matcher.find()) { + bundles.add(bundle); + } + } } - return key; } } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java index e6712fc..390197d 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/InstallBundleCommand.java @@ -109,6 +109,11 @@ public class InstallBundleCommand extends CellarCommandSupport { ClusterBundleEvent event = new ClusterBundleEvent(symbolicName, version, url, BundleEvent.INSTALLED); event.setSourceGroup(group); eventProducer.produce(event); + if (start) { + event = new ClusterBundleEvent(symbolicName, version, url, BundleEvent.STARTED); + event.setSourceGroup(group); + eventProducer.produce(event); + } } else { System.err.println("Bundle location " + url + " is blocked outbound for cluster group " + groupName); } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java index 6af87ec..e4b5a76 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/ListBundleCommand.java @@ -21,6 +21,7 @@ import org.apache.karaf.cellar.core.shell.CellarCommandSupport; import org.apache.karaf.shell.commands.Argument; import org.apache.karaf.shell.commands.Command; import org.apache.karaf.shell.commands.Option; +import org.apache.karaf.shell.table.ShellTable; import org.osgi.framework.BundleEvent; import java.util.Map; @@ -28,9 +29,6 @@ import java.util.Map; @Command(scope = "cluster", name = "bundle-list", description = "List the bundles in a cluster group") public class ListBundleCommand extends CellarCommandSupport { - protected static final String HEADER_FORMAT = " %-4s %-11s %s"; - protected static final String OUTPUT_FORMAT = "[%-4s] [%-11s] %s"; - @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false) String groupName; @@ -56,7 +54,19 @@ public class ListBundleCommand extends CellarCommandSupport { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); if (clusterBundles != null && !clusterBundles.isEmpty()) { System.out.println(String.format("Bundles in cluster group " + groupName)); - System.out.println(String.format(HEADER_FORMAT, "ID", "State", "Name")); + + ShellTable table = new ShellTable(); + table.column("ID").alignRight(); + table.column("State"); + table.column("Version"); + if (showLocation) { + table.column("Location"); + } else if (showSymbolicName) { + table.column("Symbolic Name"); + } else { + table.column("Name"); + } + int id = 0; for (String bundle : clusterBundles.keySet()) { String[] tokens = bundle.split("/"); @@ -99,16 +109,18 @@ public class ListBundleCommand extends CellarCommandSupport { break; } if (showLocation) { - System.out.println(String.format(OUTPUT_FORMAT, id, status, state.getLocation())); + table.addRow().addContent(id, status, version, state.getLocation()); } else { if (showSymbolicName) { - System.out.println(String.format(OUTPUT_FORMAT, id, status, symbolicName + " (" + version + ")")); + table.addRow().addContent(id, status, version, symbolicName); } else { - System.out.println(String.format(OUTPUT_FORMAT, id, status, state.getName() + " (" + version + ")")); + table.addRow().addContent(id, status, version, state.getName()); } } id++; } + + table.print(System.out); } else { System.err.println("No bundle found in cluster group " + groupName); } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java index beee496..23cd418 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StartBundleCommand.java @@ -25,9 +25,10 @@ import org.apache.karaf.cellar.core.event.EventType; import org.apache.karaf.shell.commands.Command; import org.osgi.framework.BundleEvent; +import java.util.List; import java.util.Map; -@Command(scope = "cluster", name = "bundle-start", description = "Start a bundle in a cluster group") +@Command(scope = "cluster", name = "bundle-start", description = "Start bundles in a cluster group") public class StartBundleCommand extends BundleCommandSupport { private EventProducer eventProducer; @@ -51,46 +52,41 @@ public class StartBundleCommand extends BundleCommandSupport { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String location; - String key = null; try { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(clusterBundles); - - if (key == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - } - - BundleState state = clusterBundles.get(key); - if (state == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - return null; + List<String> bundles = selector(clusterBundles); + + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + System.err.println("Bundle " + state + " not found in cluster group " + groupName); + } + String location = state.getLocation(); + + // check if the bundle is allowed + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); + } + + // update the cluster state + state.setStatus(BundleEvent.STARTED); + clusterBundles.put(bundle, state); + + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STARTED); + event.setSourceGroup(group); + eventProducer.produce(event); } - location = state.getLocation(); - - // check if the bundle is allowed - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - return null; - } - - state.setStatus(BundleEvent.STARTED); - clusterBundles.put(key, state); } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - // broadcast the cluster event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STARTED); - event.setSourceGroup(group); - eventProducer.produce(event); - return null; } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java index 2f94b07..ed94092 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/StopBundleCommand.java @@ -25,6 +25,7 @@ import org.apache.karaf.cellar.core.event.EventType; import org.apache.karaf.shell.commands.Command; import org.osgi.framework.BundleEvent; +import java.util.List; import java.util.Map; @Command(scope = "cluster", name = "bundle-stop", description = "Stop a bundle in a cluster group") @@ -50,47 +51,41 @@ public class StopBundleCommand extends BundleCommandSupport { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String location; - String key = null; try { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(clusterBundles); - - if (key == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - return null; - } - - BundleState state = clusterBundles.get(key); - if (state == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - return null; + List<String> bundles = selector(clusterBundles); + + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + System.err.println("Bundle " + bundle + " not found in cluster group " + groupName); + } + String location = state.getLocation(); + + // check if the bundle is allowed + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); + } + + // update the cluster state + state.setStatus(BundleEvent.STOPPED); + clusterBundles.put(bundle, state); + + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STOPPED); + event.setSourceGroup(group); + eventProducer.produce(event); } - state.setStatus(BundleEvent.STOPPED); - location = state.getLocation(); - - // check if the bundle is allowed - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - return null; - } - - clusterBundles.put(key, state); } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - // broadcast the cluster event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.STOPPED); - event.setSourceGroup(group); - eventProducer.produce(event); - return null; } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java ---------------------------------------------------------------------- diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java index d48a360..47cfe8c 100644 --- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java +++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/UninstallBundleCommand.java @@ -25,6 +25,7 @@ import org.apache.karaf.cellar.core.event.EventType; import org.apache.karaf.shell.commands.Command; import org.osgi.framework.BundleEvent; +import java.util.List; import java.util.Map; @Command(scope = "cluster", name = "bundle-uninstall", description = "Uninstall a bundle from a cluster group") @@ -51,46 +52,40 @@ public class UninstallBundleCommand extends BundleCommandSupport { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String location; - String key = null; try { Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName); - key = selector(clusterBundles); - - if (key == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - return null; - } - - BundleState state = clusterBundles.get(key); - if (state == null) { - System.err.println("Bundle " + key + " not found in cluster group " + groupName); - return null; + List<String> bundles = selector(clusterBundles); + + for (String bundle : bundles) { + BundleState state = clusterBundles.get(bundle); + if (state == null) { + System.err.println("Bundle " + bundle + " not found in cluster group " + groupName); + } + String location = state.getLocation(); + + // check if the bundle is allowed + CellarSupport support = new CellarSupport(); + support.setClusterManager(this.clusterManager); + support.setGroupManager(this.groupManager); + support.setConfigurationAdmin(this.configurationAdmin); + if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { + System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); + return null; + } + + clusterBundles.remove(bundle); + + // broadcast the cluster event + String[] split = bundle.split("/"); + ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.UNINSTALLED); + event.setSourceGroup(group); + eventProducer.produce(event); } - location = state.getLocation(); - - // check if the bundle is allowed - CellarSupport support = new CellarSupport(); - support.setClusterManager(this.clusterManager); - support.setGroupManager(this.groupManager); - support.setConfigurationAdmin(this.configurationAdmin); - if (!support.isAllowed(group, Constants.CATEGORY, location, EventType.OUTBOUND)) { - System.err.println("Bundle location " + location + " is blocked outbound for cluster group " + groupName); - return null; - } - - clusterBundles.remove(key); } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } - // broadcast the cluster event - String[] split = key.split("/"); - ClusterBundleEvent event = new ClusterBundleEvent(split[0], split[1], location, BundleEvent.UNINSTALLED); - event.setSourceGroup(group); - eventProducer.produce(event); - return null; } http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/config/pom.xml ---------------------------------------------------------------------- diff --git a/config/pom.xml b/config/pom.xml index 0aa35c8..29a9ea8 100644 --- a/config/pom.xml +++ b/config/pom.xml @@ -74,6 +74,7 @@ <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.configadmin</artifactId> </dependency> + <!-- Logging Dependencies --> <dependency> <groupId>org.slf4j</groupId> http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/529c1608/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index e4a7a90..dd239f9 100644 --- a/pom.xml +++ b/pom.xml @@ -233,6 +233,11 @@ <artifactId>org.apache.karaf.shell.console</artifactId> <version>${karaf.version}</version> </dependency> + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.table</artifactId> + <version>${karaf.version}</version> + </dependency> <dependency> <groupId>org.apache.karaf.tooling</groupId>
