Repository: brooklyn-server
Updated Branches:
  refs/heads/master 1aeb0f57e -> 660ebbb4e


CLI args: support catalogAdd with multiple URIs


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/6df6c765
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/6df6c765
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/6df6c765

Branch: refs/heads/master
Commit: 6df6c7658258f50b375dcdbdc413be8edae792ef
Parents: 0c03691
Author: Aled Sage <aled.s...@gmail.com>
Authored: Sat Mar 26 21:24:35 2016 +0000
Committer: Aled Sage <aled.s...@gmail.com>
Committed: Sat Mar 26 21:48:07 2016 +0000

----------------------------------------------------------------------
 .../catalog/internal/CatalogInitialization.java | 31 ++++---
 .../LocalManagementContextRegistry.java         | 32 ++++++++
 .../main/java/org/apache/brooklyn/cli/Main.java | 22 +++--
 .../java/org/apache/brooklyn/cli/CliTest.java   | 86 +++++++++++++++++++-
 4 files changed, 145 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6df6c765/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 37783cd..b8fdb9f 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -22,8 +22,6 @@ import java.io.File;
 import java.util.Collection;
 import java.util.List;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
@@ -41,12 +39,15 @@ import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
 import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 
 @Beta
 public class CatalogInitialization implements ManagementContextInjectable {
@@ -75,7 +76,7 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
     
     private String initialUri;
     private boolean reset;
-    private String additionsUri;
+    private List<String> additionsUris;
     private boolean force;
 
     private boolean disallowLocal = false;
@@ -96,17 +97,17 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
     
     private Object populatingCatalogMutex = new Object();
     
-    public CatalogInitialization(String initialUri, boolean reset, String 
additionUri, boolean force) {
+    public CatalogInitialization() {
+        this(null, false, ImmutableList.<String>of(), false);
+    }
+
+    public CatalogInitialization(String initialUri, boolean reset, 
Iterable<String> additionUris, boolean force) {
         this.initialUri = initialUri;
         this.reset = reset;
-        this.additionsUri = additionUri;
+        this.additionsUris = (additionUris != null) ? 
ImmutableList.copyOf(additionUris) : ImmutableList.<String>of();
         this.force = force;
     }
     
-    public CatalogInitialization() {
-        this(null, false, null, false);
-    }
-
     @Override
     public void setManagementContext(ManagementContext managementContext) {
         Preconditions.checkNotNull(managementContext, "management context");
@@ -350,7 +351,7 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
 
     boolean hasRunAdditions = false;
     protected void populateAdditions(BasicBrooklynCatalog catalog) {
-        if (Strings.isNonBlank(additionsUri)) {
+        if (!additionsUris.isEmpty()) {
             if (disallowLocal) {
                 if (!hasRunAdditions) {
                     log.warn("CLI additions supplied but not supported when 
catalog load mode disallows local loads; ignoring.");
@@ -358,11 +359,15 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
                 return;
             }   
             if (!hasRunAdditions) {
-                log.debug("Adding to catalog from CLI: "+additionsUri+" 
(force: "+force+")");
+                log.debug("Adding to catalog from CLI: "+additionsUris+" 
(force: "+force+")");
             }
-            Iterable<? extends CatalogItem<?, ?>> items = catalog.addItems(
-                new ResourceUtils(this).getResourceAsString(additionsUri), 
force);
             
+            List<CatalogItem<?,?>> items = Lists.newArrayList();
+            for (String additionsUri : additionsUris) {
+                List<? extends CatalogItem<?, ?>> addedItems = 
catalog.addItems(
+                    new ResourceUtils(this).getResourceAsString(additionsUri), 
force);
+                items.addAll(addedItems);
+            }            
             if (!hasRunAdditions)
                 log.debug("Added to catalog from CLI: "+items);
             else

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6df6c765/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextRegistry.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextRegistry.java
 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextRegistry.java
new file mode 100644
index 0000000..2ff4305
--- /dev/null
+++ 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextRegistry.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.mgmt.internal;
+
+import java.util.Set;
+
+import com.google.common.annotations.VisibleForTesting;
+
+@VisibleForTesting
+public class LocalManagementContextRegistry {
+
+    @VisibleForTesting
+    public static Set<LocalManagementContext> getInstances() {
+        return LocalManagementContext.getInstances();
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6df6c765/server-cli/src/main/java/org/apache/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --git a/server-cli/src/main/java/org/apache/brooklyn/cli/Main.java 
b/server-cli/src/main/java/org/apache/brooklyn/cli/Main.java
index 03be76e..3c3fa16 100644
--- a/server-cli/src/main/java/org/apache/brooklyn/cli/Main.java
+++ b/server-cli/src/main/java/org/apache/brooklyn/cli/Main.java
@@ -19,12 +19,6 @@
 package org.apache.brooklyn.cli;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyShell;
-import io.airlift.command.Cli;
-import io.airlift.command.Cli.CliBuilder;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
 
 import java.io.Console;
 import java.io.IOException;
@@ -33,6 +27,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -98,6 +93,13 @@ import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyShell;
+import io.airlift.command.Cli;
+import io.airlift.command.Cli.CliBuilder;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
 /**
  * This class is the primary CLI for brooklyn.
  * Run with the `help` argument for help.
@@ -230,8 +232,9 @@ public class Main extends AbstractMain {
             description = "Specifies that any catalog items which have been 
persisted should be cleared")
         public boolean catalogReset;
 
-        @Option(name = { "--catalogAdd" }, title = "catalog bom URI to add",
-            description = "Specifies a catalog.bom to be added to the catalog")
+        // Unfortunately does not support arity of 1 or more; only exactly n
+        @Option(name = { "--catalogAdd" }, title = "catalog bom URIs to add",
+            description = "Specifies one or more catalog.bom URIs (or files) 
to be added to the catalog, as a comma-separated list")
         public String catalogAdd;
 
         @Option(name = { "--catalogForce" }, 
@@ -415,7 +418,8 @@ public class Main extends AbstractMain {
     
                 launcher = createLauncher();
 
-                CatalogInitialization catInit = new 
CatalogInitialization(catalogInitial, catalogReset, catalogAdd, catalogForce);
+                List<String> catalogsAdd = Strings.isBlank(catalogAdd) ? 
ImmutableList.<String>of() : 
JavaStringEscapes.unwrapJsonishListIfPossible(catalogAdd);
+                CatalogInitialization catInit = new 
CatalogInitialization(catalogInitial, catalogReset, catalogsAdd, catalogForce);
                 catInit.addPopulationCallback(new 
Function<CatalogInitialization,Void>() {
                     @Override
                     public Void apply(CatalogInitialization catInit) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6df6c765/server-cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/server-cli/src/test/java/org/apache/brooklyn/cli/CliTest.java 
b/server-cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
index 5e38a3e..947c541 100644
--- a/server-cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
+++ b/server-cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
@@ -20,12 +20,9 @@ package org.apache.brooklyn.cli;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
-import groovy.lang.GroovyClassLoader;
-import io.airlift.command.Cli;
-import io.airlift.command.Command;
-import io.airlift.command.ParseException;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -34,6 +31,7 @@ import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -42,9 +40,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
 
+import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ImplementedBy;
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
 import org.apache.brooklyn.cli.AbstractMain.DefaultInfoCommand;
@@ -52,6 +52,7 @@ import org.apache.brooklyn.cli.AbstractMain.HelpCommand;
 import org.apache.brooklyn.cli.Main.AppShutdownHandler;
 import org.apache.brooklyn.cli.Main.GeneratePasswordCommand;
 import org.apache.brooklyn.cli.Main.LaunchCommand;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.entity.AbstractApplication;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.entity.Entities;
@@ -59,6 +60,8 @@ import org.apache.brooklyn.core.entity.StartableApplication;
 import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContextRegistry;
 import org.apache.brooklyn.core.objs.proxy.EntityProxy;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.Asserts;
@@ -67,6 +70,8 @@ import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.FatalConfigurationRuntimeException;
 import org.apache.brooklyn.util.exceptions.UserFacingException;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -75,11 +80,19 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 
+import groovy.lang.GroovyClassLoader;
+import io.airlift.command.Cli;
+import io.airlift.command.Command;
+import io.airlift.command.ParseException;
+
 public class CliTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(CliTest.class);
@@ -89,6 +102,8 @@ public class CliTest {
 
     private ExecutorService executor;
     private StartableApplication app;
+    private List<File> filesToDelete;
+    
     private static volatile ExampleEntity exampleEntity;
 
     // static so that they can be set from the static classes ExampleApp and 
ExampleEntity
@@ -98,6 +113,7 @@ public class CliTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
+        filesToDelete = Lists.newArrayList();
         executor = Executors.newCachedThreadPool();
         exampleAppConstructed = false;
         exampleAppRunning = false;
@@ -109,6 +125,11 @@ public class CliTest {
         if (executor != null) executor.shutdownNow();
         if (app != null) Entities.destroyAll(app.getManagementContext());
         if (exampleEntity != null && exampleEntity.getApplication() != null) 
Entities.destroyAll(exampleEntity.getApplication().getManagementContext());
+        if (filesToDelete != null) {
+            for (File file : filesToDelete) {
+                file.delete();
+            }
+        }
     }
     
     @Test
@@ -396,6 +417,63 @@ public class CliTest {
     }
 
     @Test
+    public void testAddBomToCatalog() throws Exception {
+        runAddBomToCatalog(1);
+    }
+
+    @Test
+    public void testAddMultipleBomsToCatalog() throws Exception {
+        runAddBomToCatalog(3);
+    }
+
+    protected void runAddBomToCatalog(int numBoms) throws Exception {
+        final List<String> bomFiles = Lists.newArrayList();
+        final List<String> itemSymbolicNames = Lists.newArrayList();
+        for (int i = 0; i < numBoms; i++) {
+            String itemName = 
"testAddToCatalog."+i+"."+Identifiers.makeRandomId(8);
+            String itemVersion = "1.2."+i;
+            File bomFile = generateSimpleBomFile(itemName, itemVersion);
+            bomFiles.add(bomFile.getAbsolutePath());
+            itemSymbolicNames.add(itemName+":"+itemVersion);
+        }
+
+        final Set<LocalManagementContext> origMgmts = 
LocalManagementContextRegistry.getInstances();
+        
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", 
"--catalogAdd", Joiner.on(",").join(bomFiles));
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    ManagementContext mgmt = assertMgmtStartedEventually();
+                    for (String itemName : itemSymbolicNames) {
+                        CatalogItem<?, ?> item = 
mgmt.getCatalog().getCatalogItem(CatalogUtils.getSymbolicNameFromVersionedId(itemName),
 CatalogUtils.getVersionFromVersionedId(itemName));
+                        assertNotNull(item);
+                    }
+                }
+                private ManagementContext assertMgmtStartedEventually() {
+                    return Asserts.succeedsEventually(new 
Callable<ManagementContext>() {
+                        public ManagementContext call() {
+                            ManagementContext mgmt = 
Iterables.getOnlyElement(Sets.difference(LocalManagementContextRegistry.getInstances(),
 origMgmts));
+                            assertTrue(mgmt.isStartupComplete());
+                            return mgmt;
+                        }});
+                }
+            });
+    }
+    
+    private File generateSimpleBomFile(String itemName, String itemVersion) {
+        String catalogContents = Joiner.on("\n").join(
+                "brooklyn.catalog:",
+                "  id: "+itemName,
+                "  version: "+itemVersion,
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.entity.stock.BasicApplication");
+        File bomFile = Os.writeToTempFile(new 
ByteArrayInputStream(catalogContents.getBytes()), "testAddToCatalog", ".bom");
+        filesToDelete.add(bomFile);
+        return bomFile;
+    }
+    
+    @Test
     public void testGeneratePasswordCommandParsed() throws Exception {
         Cli<BrooklynCommand> cli = buildCli();
         BrooklynCommand command = cli.parse("generate-password", "--user", 
"myname");

Reply via email to