Repository: karaf-cellar Updated Branches: refs/heads/cellar-3.0.x 812d1a621 -> 6984f7d4e
[KARAF-3988] Add support of features repo name Project: http://git-wip-us.apache.org/repos/asf/karaf-cellar/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf-cellar/commit/855f7d91 Tree: http://git-wip-us.apache.org/repos/asf/karaf-cellar/tree/855f7d91 Diff: http://git-wip-us.apache.org/repos/asf/karaf-cellar/diff/855f7d91 Branch: refs/heads/cellar-3.0.x Commit: 855f7d914d720c411fce2da4f0fc1d8b74434bfe Parents: 812d1a6 Author: Jean-Baptiste Onofré <[email protected]> Authored: Mon Sep 14 21:10:16 2015 +0200 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Tue Sep 15 06:32:18 2015 +0200 ---------------------------------------------------------------------- .../management/CellarFeaturesMBean.java | 27 +++- .../internal/CellarFeaturesMBeanImpl.java | 151 ++++++++++++------- .../cellar/features/shell/RepoAddCommand.java | 115 +++++++------- .../features/shell/RepoRemoveCommand.java | 35 ++++- 4 files changed, 206 insertions(+), 122 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/855f7d91/features/src/main/java/org/apache/karaf/cellar/features/management/CellarFeaturesMBean.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/cellar/features/management/CellarFeaturesMBean.java b/features/src/main/java/org/apache/karaf/cellar/features/management/CellarFeaturesMBean.java index 54f6482..faa6db1 100644 --- a/features/src/main/java/org/apache/karaf/cellar/features/management/CellarFeaturesMBean.java +++ b/features/src/main/java/org/apache/karaf/cellar/features/management/CellarFeaturesMBean.java @@ -25,39 +25,50 @@ public interface CellarFeaturesMBean { * Add a features repository in a cluster group. * * @param group the cluster group name. - * @param url the features repository URL. + * @param nameOrUrl the features repository name or URL. * @throws Exception in case of add failure. */ - void addRepository(String group, String url) throws Exception; + void addRepository(String group, String nameOrUrl) throws Exception; /** * Add a features repository in a cluster group. * * @param group the cluster group name. - * @param url the features repository URL. + * @param nameOrUrl the features repository name or URL. + * @param version the features repository version (when name is provided). + * @throws Exception in case of add failure. + */ + void addRepository(String group, String nameOrUrl, String version) throws Exception; + + /** + * Add a features repository in a cluster group. + * + * @param group the cluster group name. + * @param nameOrUrl the features repository URL. + * @param version the features repository version (when name is provided). * @param install true to install all features contained in the repository, false else. * @throws Exception in case of add failure. */ - void addRepository(String group, String url, boolean install) throws Exception; + void addRepository(String group, String nameOrUrl, String version, boolean install) throws Exception; /** * Remove a features repository from a cluster group. * * @param group the cluster group name. - * @param url the features repository URL. + * @param repository the features repository name or URL. * @throws Exception in case of remove failure. */ - void removeRepository(String group, String url) throws Exception; + void removeRepository(String group, String repository) throws Exception; /** * Remove a features repository from a cluster group, eventually uninstalling all features described in the repository. * * @param group the cluster group name. - * @param url the features repository URL. + * @param repository the features repository name or URL. * @param uninstall true to uninstall all features described in the repository URL. * @throws Exception */ - void removeRepository(String group, String url, boolean uninstall) throws Exception; + void removeRepository(String group, String repository, boolean uninstall) throws Exception; /** * Install a feature in a cluster group. http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/855f7d91/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java index 4ff1cc3..7af4e04 100644 --- a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java +++ b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java @@ -14,6 +14,7 @@ package org.apache.karaf.cellar.features.management.internal; // import org.apache.karaf.cellar.bundle.BundleState; + import org.apache.karaf.cellar.core.*; import org.apache.karaf.cellar.core.control.SwitchStatus; import org.apache.karaf.cellar.core.event.EventProducer; @@ -35,6 +36,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Implementation of the Cellar Features MBean. @@ -128,7 +131,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat // check if the feature exist FeatureState feature = null; String key = null; - for (String k: clusterFeatures.keySet()) { + for (String k : clusterFeatures.keySet()) { FeatureState state = clusterFeatures.get(k); key = k; if (version == null) { @@ -391,12 +394,17 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat } @Override - public void addRepository(String groupName, String url) throws Exception { - this.addRepository(groupName, url, false); + public void addRepository(String groupName, String nameOrUrl) throws Exception { + this.addRepository(groupName, nameOrUrl, null, false); + } + + @Override + public void addRepository(String groupName, String nameOrUrl, String version) throws Exception { + this.addRepository(groupName, nameOrUrl, version, false); } @Override - public void addRepository(String groupName, String url, boolean install) throws Exception { + public void addRepository(String groupName, String nameOrUrl, String version, boolean install) throws Exception { // check if the group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -416,10 +424,15 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat // get the features in the cluster group Map<String, FeatureState> clusterFeatures = clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName); + URI uri = featuresService.getRepositoryUriFor(nameOrUrl, version); + if (uri == null) { + uri = new URI(nameOrUrl); + } + // check if the URL is already registered String name = null; for (String repository : clusterRepositories.keySet()) { - if (repository.equals(url)) { + if (repository.equals(uri)) { name = clusterRepositories.get(repository); break; } @@ -430,7 +443,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat boolean localRegistered = false; // local lookup for (Repository registeredRepository : featuresService.listRepositories()) { - if (registeredRepository.getURI().equals(new URI(url))) { + if (registeredRepository.getURI().equals(uri)) { repository = registeredRepository; break; } @@ -438,13 +451,13 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat if (repository == null) { // registered locally try { - featuresService.addRepository(new URI(url)); + featuresService.addRepository(uri); } catch (Exception e) { - throw new IllegalArgumentException("Features repository URL " + url + " is not valid: " + e.getMessage()); + throw new IllegalArgumentException("Features repository URL " + uri + " is not valid: " + e.getMessage()); } // get the repository for (Repository registeredRepository : featuresService.listRepositories()) { - if (registeredRepository.getURI().equals(new URI(url))) { + if (registeredRepository.getURI().equals(uri)) { repository = registeredRepository; break; } @@ -455,7 +468,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat } // update the cluster group - clusterRepositories.put(url, name); + clusterRepositories.put(uri.toString(), name); for (Feature feature : repository.getFeatures()) { FeatureState state = new FeatureState(); @@ -467,15 +480,15 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat // un-register the repository if it's not local registered if (!localRegistered) - featuresService.removeRepository(new URI(url)); + featuresService.removeRepository(uri); // broadcast the cluster event - ClusterRepositoryEvent event = new ClusterRepositoryEvent(url, RepositoryEvent.EventType.RepositoryAdded); + ClusterRepositoryEvent event = new ClusterRepositoryEvent(uri.toString(), RepositoryEvent.EventType.RepositoryAdded); event.setInstall(install); event.setSourceGroup(group); eventProducer.produce(event); } else { - throw new IllegalArgumentException("Features repository URL " + url + " already registered"); + throw new IllegalArgumentException("Features repository URL " + uri + " already registered"); } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); @@ -483,12 +496,12 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat } @Override - public void removeRepository(String groupName, String url) throws Exception { - this.removeRepository(groupName, url, false); + public void removeRepository(String groupName, String repository) throws Exception { + this.removeRepository(groupName, repository, false); } @Override - public void removeRepository(String groupName, String url, boolean uninstall) throws Exception { + public void removeRepository(String groupName, String repo, boolean uninstall) throws Exception { // check if the group exists Group group = groupManager.findGroupByName(groupName); if (group == null) { @@ -508,61 +521,87 @@ public class CellarFeaturesMBeanImpl extends StandardMBean implements CellarFeat ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - // looking for the URL in the list - String name = null; - for (String clusterRepository : clusterRepositories.keySet()) { - if (clusterRepository.equals(url)) { - name = clusterRepositories.get(clusterRepository); - break; + + List<String> urls = new ArrayList<String>(); + Pattern pattern = Pattern.compile(repo); + for (String repositoryUrl : clusterRepositories.keySet()) { + String repositoryName = clusterRepositories.get(repositoryUrl); + if (repositoryName != null && !repositoryName.isEmpty()) { + // repository has name, try regex on the name + Matcher nameMatcher = pattern.matcher(repositoryName); + if (nameMatcher.matches()) { + urls.add(repositoryUrl); + } else { + // the name regex doesn't match, fallback to repository URI regex + Matcher uriMatcher = pattern.matcher(repositoryUrl); + if (uriMatcher.matches()) { + urls.add(repositoryUrl); + } + } + } else { + // the repository name is not defined, use repository URI regex + Matcher uriMatcher = pattern.matcher(repositoryUrl); + if (uriMatcher.matches()) { + urls.add(repositoryUrl); + } } } - if (name == null) { - // update the repository temporary locally - Repository repository = null; - boolean localRegistered = false; - // local lookup - for (Repository registeredRepository : featuresService.listRepositories()) { - if (registeredRepository.getURI().equals(new URI(url))) { - repository = registeredRepository; + + for (String url : urls) { + // looking for the URL in the list + String name = null; + for (String clusterRepository : clusterRepositories.keySet()) { + if (clusterRepository.equals(url)) { + name = clusterRepositories.get(clusterRepository); break; } } - if (repository == null) { - // registered locally - try { - featuresService.addRepository(new URI(url)); - } catch (Exception e) { - throw new IllegalArgumentException("Features repository URL " + url + " is not valid: " + e.getMessage()); - } - // get the repository + if (name == null) { + // update the repository temporary locally + Repository repository = null; + boolean localRegistered = false; + // local lookup for (Repository registeredRepository : featuresService.listRepositories()) { if (registeredRepository.getURI().equals(new URI(url))) { repository = registeredRepository; break; } } - } else { - localRegistered = true; - } + if (repository == null) { + // registered locally + try { + featuresService.addRepository(new URI(url)); + } catch (Exception e) { + throw new IllegalArgumentException("Features repository URL " + url + " is not valid: " + e.getMessage()); + } + // get the repository + for (Repository registeredRepository : featuresService.listRepositories()) { + if (registeredRepository.getURI().equals(new URI(url))) { + repository = registeredRepository; + break; + } + } + } else { + localRegistered = true; + } - // update the cluster group - clusterRepositories.remove(url); + // update the cluster group + clusterRepositories.remove(url); - for (Feature feature : repository.getFeatures()) { - clusterFeatures.remove(feature.getName() + "/" + feature.getVersion()); - } + for (Feature feature : repository.getFeatures()) { + clusterFeatures.remove(feature.getName() + "/" + feature.getVersion()); + } - // un-register the repository if it's not local registered - if (!localRegistered) - featuresService.removeRepository(new URI(url)); + // un-register the repository if it's not local registered + if (!localRegistered) + featuresService.removeRepository(new URI(url)); - // broadcast a cluster event - ClusterRepositoryEvent event = new ClusterRepositoryEvent(url, RepositoryEvent.EventType.RepositoryRemoved); - event.setUninstall(uninstall); - event.setSourceGroup(group); - eventProducer.produce(event); - } else { - throw new IllegalArgumentException("Features repository URL " + url + " not found in cluster group " + groupName); + // broadcast a cluster event + ClusterRepositoryEvent event = new ClusterRepositoryEvent(repo, RepositoryEvent.EventType.RepositoryRemoved); + event.setUninstall(uninstall); + event.setSourceGroup(group); + eventProducer.produce(event); + } } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/855f7d91/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java index 0788087..d705e86 100644 --- a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java +++ b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java @@ -39,10 +39,13 @@ public class RepoAddCommand extends CellarCommandSupport { @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false) String groupName; - @Argument(index = 1, name = "urls", description = "URLs of the feature repositories separated by whitespaces", required = true, multiValued = true) - List<String> urls; + @Argument(index = 1, name = "name/url", description = "Shortcut name of the features repository or the full URL", required = true, multiValued = false) + String nameOrUrl; - @Option(name = "-i", aliases = { "--install" }, description = "Install all features contained in the features repository", required = false, multiValued = false) + @Argument(index = 2, name = "version", description = "The version of the features repository if using features repository name as first argument. It should be empty if using the URL.", required = false, multiValued = false) + String version; + + @Option(name = "-i", aliases = {"--install"}, description = "Install all features contained in the features repository", required = false, multiValued = false) boolean install; private EventProducer eventProducer; @@ -71,69 +74,71 @@ public class RepoAddCommand extends CellarCommandSupport { // get the features in the cluster group Map<String, FeatureState> clusterFeatures = clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName); - for (String url : urls) { - // check if the URL is already registered - String name = null; - for (String repository : clusterRepositories.keySet()) { - if (repository.equals(url)) { - name = clusterRepositories.get(url); + URI uri = featuresService.getRepositoryUriFor(nameOrUrl, version); + if (uri == null) { + uri = new URI(nameOrUrl); + } + // check if the URL is already registered + String name = null; + for (String repository : clusterRepositories.keySet()) { + if (repository.equals(uri)) { + name = clusterRepositories.get(uri); + break; + } + } + if (name == null) { + // update the repository temporary locally + Repository repository = null; + boolean localRegistered = false; + // local lookup + for (Repository registeredRepository : featuresService.listRepositories()) { + if (registeredRepository.getURI().equals(uri)) { + repository = registeredRepository; break; } } - if (name == null) { - // update the repository temporary locally - Repository repository = null; - boolean localRegistered = false; - // local lookup + if (repository == null) { + // registered locally + try { + featuresService.addRepository(uri); + } catch (Exception e) { + System.err.println("Repository URL " + uri + " is not valid: " + e.getMessage()); + return null; + } + // get the repository for (Repository registeredRepository : featuresService.listRepositories()) { - if (registeredRepository.getURI().equals(new URI(url))) { + if (registeredRepository.getURI().equals(uri)) { repository = registeredRepository; break; } } - if (repository == null) { - // registered locally - try { - featuresService.addRepository(new URI(url)); - } catch (Exception e) { - System.err.println("Repository URL " + url + " is not valid: " + e.getMessage()); - continue; - } - // get the repository - for (Repository registeredRepository : featuresService.listRepositories()) { - if (registeredRepository.getURI().equals(new URI(url))) { - repository = registeredRepository; - break; - } - } - } else { - localRegistered = true; - } - - // update the features repositories in the cluster group - clusterRepositories.put(url, repository.getName()); - - // update the features in the cluster group - for (Feature feature : repository.getFeatures()) { - FeatureState featureState = new FeatureState(); - featureState.setName(feature.getName()); - featureState.setVersion(feature.getVersion()); - featureState.setInstalled(featuresService.isInstalled(feature)); - clusterFeatures.put(feature.getName() + "/" + feature.getVersion(), featureState); - } + } else { + localRegistered = true; + } - // un-register the repository if it's not local registered - if (!localRegistered) - featuresService.removeRepository(new URI(url)); + // update the features repositories in the cluster group + clusterRepositories.put(uri.toString(), repository.getName()); - // broadcast the cluster event - ClusterRepositoryEvent event = new ClusterRepositoryEvent(url, RepositoryEvent.EventType.RepositoryAdded); - event.setInstall(install); - event.setSourceGroup(group); - eventProducer.produce(event); - } else { - System.err.println("Features repository URL " + url + " already registered"); + // update the features in the cluster group + for (Feature feature : repository.getFeatures()) { + FeatureState featureState = new FeatureState(); + featureState.setName(feature.getName()); + featureState.setVersion(feature.getVersion()); + featureState.setInstalled(featuresService.isInstalled(feature)); + clusterFeatures.put(feature.getName() + "/" + feature.getVersion(), featureState); } + + // un-register the repository if it's not local registered + if (!localRegistered) + featuresService.removeRepository(uri); + + // broadcast the cluster event + ClusterRepositoryEvent event = new ClusterRepositoryEvent(uri.toString(), RepositoryEvent.EventType.RepositoryAdded); + event.setInstall(install); + event.setSourceGroup(group); + eventProducer.produce(event); + } else { + System.err.println("Features repository URL " + uri + " already registered"); } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/855f7d91/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java index 0d3c582..d577ad1 100644 --- a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java +++ b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java @@ -30,8 +30,11 @@ import org.apache.karaf.shell.commands.Command; import org.apache.karaf.shell.commands.Option; import java.net.URI; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Command(scope = "cluster", name = "feature-repo-remove", description = "Remove features repository URLs from a cluster group") public class RepoRemoveCommand extends CellarCommandSupport { @@ -39,10 +42,10 @@ public class RepoRemoveCommand extends CellarCommandSupport { @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false) String groupName; - @Argument(index = 1, name = "urls", description = "The features repository URLs separated by whitespaces", required = true, multiValued = true) - List<String> urls; + @Argument(index = 1, name = "repository", description = "Name or url of the repository to remove", required = true, multiValued = false) + String repository; - @Option(name = "-u", aliases = { "--uninstall-all" }, description = "Uninstall all features contained in the features repositories", required = false, multiValued = false) + @Option(name = "-u", aliases = {"--uninstall-all"}, description = "Uninstall all features contained in the features repositories", required = false, multiValued = false) boolean uninstall; private EventProducer eventProducer; @@ -71,6 +74,32 @@ public class RepoRemoveCommand extends CellarCommandSupport { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + + List<String> urls = new ArrayList<String>(); + Pattern pattern = Pattern.compile(repository); + for (String repositoryUrl : clusterRepositories.keySet()) { + String repositoryName = clusterRepositories.get(repositoryUrl); + if (repositoryName != null && !repositoryName.isEmpty()) { + // repository has name, try regex on the name + Matcher nameMatcher = pattern.matcher(repositoryName); + if (nameMatcher.matches()) { + urls.add(repositoryUrl); + } else { + // the name regex doesn't match, fallback to repository URI regex + Matcher uriMatcher = pattern.matcher(repositoryUrl); + if (uriMatcher.matches()) { + urls.add(repositoryUrl); + } + } + } else { + // the repository name is not defined, use repository URI regex + Matcher uriMatcher = pattern.matcher(repositoryUrl); + if (uriMatcher.matches()) { + urls.add(repositoryUrl); + } + } + } + for (String url : urls) { // looking for the URL in the list boolean found = false;
