You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/07/04 11:51:18 UTC

[36/45] git commit: Supports brooklyn.catalog in yaml and its usage in BasicBrooklynCatalog

Supports brooklyn.catalog in yaml and its usage in BasicBrooklynCatalog


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

Branch: refs/heads/master
Commit: f03f52fc0152b0355c860def523563e644f71327
Parents: 24c78d5
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Jul 3 16:22:56 2014 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Jul 3 16:22:56 2014 +0100

----------------------------------------------------------------------
 .../brooklyn/camp/spi/pdp/DeploymentPlan.java   | 27 ++++++++++++-
 .../catalog/internal/BasicBrooklynCatalog.java  | 24 ++++++++++--
 .../catalog/internal/CatalogLibrariesDto.java   | 40 ++++++++++++++++++--
 .../brooklyn/camp/lite/CampYamlLiteTest.java    | 13 ++++++-
 .../camp/lite/test-app-service-blueprint.yaml   |  9 +++++
 .../spi/creation/BrooklynEntityMatcher.java     | 19 ++++++++++
 .../spi/dsl/BrooklynDslInterpreter.java         |  2 +-
 7 files changed, 123 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java
index e5fb05e..1af3ff9 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java
@@ -7,6 +7,7 @@ import java.util.Map;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 import brooklyn.util.collections.MutableMap;
+import brooklyn.util.guava.Maybe;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -69,22 +70,46 @@ public class DeploymentPlan {
     public String getName() {
         return name;
     }
+
     public String getDescription() {
         return description;
     }
+
     public String getOrigin() {
         return origin;
     }
+
     public List<Artifact> getArtifacts() {
         return ImmutableList.copyOf(artifacts);
     }
+
     public List<Service> getServices() {
         return ImmutableList.copyOf(services);
     }
+
     public Map<String, Object> getCustomAttributes() {
         return ImmutableMap.copyOf(customAttributes);
     }
-    
+
+    /**
+     * Returns a present {@link Maybe} of the custom attribute with the given name if the attribute is
+     * non-null and is an instance of the given type. Otherwise returns absent.
+     * <p/>
+     * Does not remove the attribute from the custom attribute map.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Maybe<T> getCustomAttribute(String attributeName, Class<T> type) {
+        Object attribute = customAttributes.get(attributeName);
+        if (attribute == null) {
+            return Maybe.absent("Custom attributes does not contain " + attributeName);
+        } else if (!type.isAssignableFrom(attribute.getClass())) {
+            return Maybe.absent("Custom attribute " + attributeName + " is not of expected type: " +
+                    "expected=" + type.getName() + " actual=" + attribute.getClass().getName());
+        } else {
+            return Maybe.of((T) attribute);
+        }
+    }
+
     @Override
     public String toString() {
         return ToStringBuilder.reflectionToString(this);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index 2f45bb7..9411863 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -1,11 +1,14 @@
 package brooklyn.catalog.internal;
 
+import brooklyn.util.guava.Maybe;
 import io.brooklyn.camp.CampPlatform;
 import io.brooklyn.camp.spi.AssemblyTemplate;
 import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import io.brooklyn.camp.spi.pdp.DeploymentPlan;
 import io.brooklyn.camp.spi.pdp.Service;
 
+import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 
 import javax.annotation.Nullable;
@@ -186,13 +189,26 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
     private CatalogItemDtoAbstract<?,?> getAbstractCatalogItem(String yaml) {
         DeploymentPlan plan = makePlanFromYaml(yaml);
         
-        // TODO #2 parse brooklyn.catalog for metadata - name, bundles/libraries, etc
-        // (for now we default to taking the name from the plan or from a single service type therein, below)
         String name = null;
         CatalogLibrariesDto libraries = null;
-        
+
+        Maybe<Map> possibleCatalog = plan.getCustomAttribute("brooklyn.catalog", Map.class);
+        if (possibleCatalog.isPresent()) {
+            Map catalog = possibleCatalog.get();
+            Map<String, Object> cast = (Map<String, Object>) possibleCatalog.get();
+            if (catalog.containsKey("name") && catalog.get("name") != null) {
+                name = String.valueOf(catalog.get("name"));
+            }
+            Object possibleLibraries = catalog.get("libraries");
+            if (possibleLibraries != null) {
+                if (possibleLibraries instanceof List) {
+                    libraries = CatalogLibrariesDto.fromList((List<?>) possibleLibraries);
+                }
+            }
+        }
+
         // TODO #3 support version info
-        
+
         // take name from plan if not specified in brooklyn.catalog section not supplied
         if (Strings.isBlank(name)) {
             name = plan.getName();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/core/src/main/java/brooklyn/catalog/internal/CatalogLibrariesDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogLibrariesDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogLibrariesDto.java
index 4df1333..7f8f41d 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogLibrariesDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogLibrariesDto.java
@@ -2,8 +2,12 @@ package brooklyn.catalog.internal;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -11,20 +15,50 @@ import brooklyn.catalog.CatalogItem;
 
 public class CatalogLibrariesDto implements CatalogItem.CatalogItemLibraries {
 
+    private static Logger LOG = LoggerFactory.getLogger(CatalogLibrariesDto.class);
+
+    // TODO: Incorporate name and version into entries
     private List<String> bundles = new CopyOnWriteArrayList<String>();
 
     public void addBundle(String url) {
         Preconditions.checkNotNull(bundles, "Cannot add a bundle to a deserialized DTO");
-        bundles.add( Preconditions.checkNotNull(url) );
+        bundles.add(Preconditions.checkNotNull(url, "url"));
     }
 
-    /** @return An immutable copy of the bundle URLs referenced by this object */
+    /**
+     * @return An immutable copy of the bundle URLs referenced by this object
+     */
     public List<String> getBundles() {
-        if (bundles==null)  {
+        if (bundles == null) {
             // can be null on deserialization
             return Collections.emptyList();
         }
         return ImmutableList.copyOf(bundles);
     }
 
+    /**
+     * Parses an instance of CatalogLibrariesDto from the given List. Expects the list entries
+     * to be maps of string -> string. Will skip items that are not.
+     */
+    public static CatalogLibrariesDto fromList(List<?> possibleLibraries) {
+        CatalogLibrariesDto dto = new CatalogLibrariesDto();
+        for (Object object : possibleLibraries) {
+            if (object instanceof Map) {
+                Map entry = (Map) object;
+                String name = stringValOrNull(entry, "name");
+                String version = stringValOrNull(entry, "version");
+                String url = stringValOrNull(entry, "url");
+                dto.addBundle(url);
+            } else {
+                LOG.debug("Unexpected entry in libraries list not instance of map: " + object);
+            }
+        }
+
+        return dto;
+    }
+
+    private static String stringValOrNull(Map map, String key) {
+        Object val = map.get(key);
+        return val != null ? String.valueOf(val) : null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
index c1bfefc..de89b0f 100644
--- a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
+++ b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
@@ -8,6 +8,7 @@ import io.brooklyn.camp.test.mock.web.MockWebPlatform;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.util.Map;
+import java.util.Set;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,6 +29,7 @@ import brooklyn.util.stream.Streams;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
 
 /** Tests of lightweight CAMP integration. Since the "real" integration is in brooklyn-camp project,
  * but some aspects of CAMP we want to be able to test here. */
@@ -83,16 +85,23 @@ public class CampYamlLiteTest {
         MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class);
         
         CatalogItem<?, ?> realItem = mgmt.getCatalog().addItem(Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml")));
-        Iterable<CatalogItem<Object, Object>> retrievedItems = mgmt.getCatalog().getCatalogItems(CatalogPredicates.registeredType(Predicates.equalTo("sample")));
+        Iterable<CatalogItem<Object, Object>> retrievedItems = mgmt.getCatalog()
+                .getCatalogItems(CatalogPredicates.registeredType(Predicates.equalTo("catalog-name")));
         
         Assert.assertEquals(Iterables.size(retrievedItems), 1, "Wrong retrieved items: "+retrievedItems);
         CatalogItem<Object, Object> retrievedItem = Iterables.getOnlyElement(retrievedItems);
         Assert.assertEquals(retrievedItem, realItem);
-        
+
+        Set<String> expectedBundles = Sets.newHashSet("http://www.example.com/bundle.jar");
+        Assert.assertEquals(retrievedItem.getLibraries().getBundles(), expectedBundles);
+        // Assert.assertEquals(retrievedItem.getVersion(), "0.9");
+
+
         EntitySpec<?> spec1 = (EntitySpec<?>) mgmt.getCatalog().createSpec(retrievedItem);
         Assert.assertNotNull(spec1);
         Assert.assertEquals(spec1.getConfig().get(TestEntity.CONF_NAME), "sample");
         
         // TODO other assertions, about children
     }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/core/src/test/resources/brooklyn/camp/lite/test-app-service-blueprint.yaml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/brooklyn/camp/lite/test-app-service-blueprint.yaml b/core/src/test/resources/brooklyn/camp/lite/test-app-service-blueprint.yaml
index 96db31c..13a4189 100644
--- a/core/src/test/resources/brooklyn/camp/lite/test-app-service-blueprint.yaml
+++ b/core/src/test/resources/brooklyn/camp/lite/test-app-service-blueprint.yaml
@@ -9,3 +9,12 @@ services:
         /: hello.war
     controller.spec:
         port: 80
+
+brooklyn.catalog:
+  name: catalog-name
+  type: io.camp.mock.MyApplication
+  version: 0.9
+  libraries:
+  - name: lib1
+    version: v1
+    url: http://www.example.com/bundle.jar
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
index d8e8fc6..76ffbe3 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
@@ -22,6 +22,7 @@ import brooklyn.util.flags.FlagUtils.FlagConfigKeyAndValueRecord;
 import brooklyn.util.text.Strings;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
 public class BrooklynEntityMatcher implements PdpMatcher {
 
@@ -115,6 +116,7 @@ public class BrooklynEntityMatcher implements PdpMatcher {
         addCustomListAttributeIfNonNull(builder, attrs, "brooklyn.enrichers");
         addCustomListAttributeIfNonNull(builder, attrs, "brooklyn.initializers");
         addCustomListAttributeIfNonNull(builder, attrs, "brooklyn.children");
+        addCustomMapAttributeIfNonNull(builder, attrs, "brooklyn.catalog");
 
         if (!attrs.isEmpty()) {
             log.warn("Ignoring PDP attributes on "+deploymentPlanItem+": "+attrs);
@@ -142,6 +144,23 @@ public class BrooklynEntityMatcher implements PdpMatcher {
                 throw new IllegalArgumentException(key + " must be a list, is: " + items.getClass().getName());
             }
         }
+    }
+
+    /**
+     * Looks for the given key in the map of attributes and adds it to the given builder
+     * as a custom attribute with type Map.
+     * @throws java.lang.IllegalArgumentException if map[key] is not an instance of Map
+     */
+    private void addCustomMapAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map attrs, String key) {
+        Object items = attrs.remove(key);
+        if (items != null) {
+            if (items instanceof Map) {
+                Map<?, ?> itemMap = (Map<?, ?>) items;
+                if (!itemMap.isEmpty()) {
+                    builder.customAttribute(key, Maps.newHashMap(itemMap));
+                }
+            } else {
+                throw new IllegalArgumentException(key + " must be a map, is: " + items.getClass().getName());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f03f52fc/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
index 9d1153c..a7ec34c 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
@@ -76,7 +76,7 @@ public class BrooklynDslInterpreter extends PlanInterpreterAdapter {
     
     @Override
     public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut,
-                            PlanInterpretationNode key, PlanInterpretationNode value) {
+            PlanInterpretationNode key, PlanInterpretationNode value) {
         if (key.getNewValue() instanceof FunctionWithArgs) {
             try {
                 currentNode.set(node);