You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/03/18 12:52:06 UTC
[1/3] incubator-brooklyn git commit: Adds Yamls.getAt utility
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master 52a6c708f -> 5fa14442d
Adds Yamls.getAt utility
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/d3878877
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d3878877
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d3878877
Branch: refs/heads/master
Commit: d38788771c5ed67d7ab8fbdf105995a252174932
Parents: ab46e6f
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 17 14:46:28 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Mar 17 14:46:28 2015 +0000
----------------------------------------------------------------------
.../src/main/java/brooklyn/util/yaml/Yamls.java | 41 +++++++++++++++++
.../test/java/brooklyn/util/yaml/YamlsTest.java | 47 ++++++++++++++++++++
2 files changed, 88 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d3878877/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
index cad4395..7c946dd 100644
--- a/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
+++ b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
@@ -66,6 +66,47 @@ public class Yamls {
return (T)x;
}
+ /**
+ * Parses the given yaml, and walks the given path to return the referenced object.
+ *
+ * @see #getAt(Object, List)
+ */
+ public static Object getAt(String yaml, List<String> path) {
+ Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
+ Object current = result.iterator().next();
+ return getAtPreParsed(current, path);
+ }
+
+ /**
+ * For pre-parsed yaml, walks the maps/lists to return the given sub-item.
+ * In the given path:
+ * <ul>
+ * <li>A vanilla string is assumed to be a key into a map.
+ * <li>A string in the form like "[0]" is assumed to be an index into a list
+ * </ul>
+ *
+ * Returns {@code null} if that path does not exist.
+ */
+ @SuppressWarnings("unchecked")
+ public static Object getAtPreParsed(Object current, List<String> path) {
+ for (String pathPart : path) {
+ if (pathPart.startsWith("[") && pathPart.endsWith("]")) {
+ String index = pathPart.substring(1, pathPart.length()-1);
+ try {
+ current = Iterables.get((Iterable<?>)current, Integer.parseInt(index));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid index '"+index+"', in path "+path);
+ } catch (IndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("Invalid index '"+index+"', in path "+path);
+ }
+ } else {
+ current = ((Map<String, ?>)current).get(pathPart);
+ }
+ if (current == null) return null;
+ }
+ return current;
+ }
+
@SuppressWarnings("rawtypes")
public static void dump(int depth, Object r) {
if (r instanceof Iterable) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d3878877/utils/common/src/test/java/brooklyn/util/yaml/YamlsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/brooklyn/util/yaml/YamlsTest.java b/utils/common/src/test/java/brooklyn/util/yaml/YamlsTest.java
new file mode 100644
index 0000000..27437d9
--- /dev/null
+++ b/utils/common/src/test/java/brooklyn/util/yaml/YamlsTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 brooklyn.util.yaml;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class YamlsTest {
+
+ @Test
+ public void testGetAt() throws Exception {
+ // leaf of map
+ assertEquals(Yamls.getAt("k1: v", ImmutableList.of("k1")), "v");
+ assertEquals(Yamls.getAt("k1: {k2: v}", ImmutableList.of("k1", "k2")), "v");
+
+ // get list
+ assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1")), ImmutableList.of("v1", "v2"));
+
+ // get map
+ assertEquals(Yamls.getAt("k1: v", ImmutableList.<String>of()), ImmutableMap.of("k1", "v"));
+ assertEquals(Yamls.getAt("k1: {k2: v}", ImmutableList.of("k1")), ImmutableMap.of("k2", "v"));
+
+ // get array index
+ assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1", "[0]")), "v1");
+ assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1", "[1]")), "v2");
+ }
+}
[3/3] incubator-brooklyn git commit: This closes #555
Posted by al...@apache.org.
This closes #555
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/5fa14442
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/5fa14442
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/5fa14442
Branch: refs/heads/master
Commit: 5fa14442dd837214c12046deb2cc4e233a809fc5
Parents: 52a6c70 09a6475
Author: Aled Sage <al...@gmail.com>
Authored: Wed Mar 18 11:51:52 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Mar 18 11:51:52 2015 +0000
----------------------------------------------------------------------
.../main/java/brooklyn/catalog/CatalogItem.java | 5 +-
.../java/brooklyn/location/LocationSpec.java | 27 ++++
.../brooklyn/catalog/CatalogPredicates.java | 4 +
.../catalog/internal/BasicBrooklynCatalog.java | 92 +++++++++--
.../catalog/internal/CatalogClasspathDo.java | 8 +
.../catalog/internal/CatalogItemBuilder.java | 6 +
.../internal/CatalogLocationItemDto.java | 43 ++++++
.../catalog/internal/CatalogXmlSerializer.java | 2 +
.../location/basic/BasicLocationRegistry.java | 87 ++++++++++-
.../location/basic/CatalogLocationResolver.java | 79 ++++++++++
.../services/brooklyn.location.LocationResolver | 1 +
.../brooklyn/osgi/tests/SimpleLocation.java | 35 +++++
.../entity/rebind/RebindCatalogItemTest.java | 36 ++++-
.../entity/rebind/RebindTestFixture.java | 9 +-
.../osgi/brooklyn-test-osgi-entities.jar | Bin 12419 -> 13060 bytes
.../camp/brooklyn/AbstractYamlTest.java | 20 +++
.../brooklyn/EmptySoftwareProcessYamlTest.java | 39 ++---
.../catalog/CatalogYamlLocationTest.java | 152 +++++++++++++++++++
.../rest/resources/LocationResource.java | 83 +++++-----
.../rest/resources/LocationResourceTest.java | 20 ++-
.../src/main/java/brooklyn/util/yaml/Yamls.java | 48 ++++++
.../test/java/brooklyn/util/yaml/YamlsTest.java | 47 ++++++
22 files changed, 760 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
[2/3] incubator-brooklyn git commit: BROOKLYN-136: Persist
dynamically added locs in catalog
Posted by al...@apache.org.
BROOKLYN-136: Persist dynamically added locs in catalog
- Support CatalogItem of type location
- Location items added to catalog automatically added to
LocationRegistry
- LocationResource.create adds new location type to Catalog
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/09a64755
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/09a64755
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/09a64755
Branch: refs/heads/master
Commit: 09a64755e2c16c25f076af6a32f93ee0ff8c2599
Parents: d387887
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 17 14:46:57 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Mar 18 11:02:52 2015 +0000
----------------------------------------------------------------------
.../main/java/brooklyn/catalog/CatalogItem.java | 5 +-
.../java/brooklyn/location/LocationSpec.java | 27 ++++
.../brooklyn/catalog/CatalogPredicates.java | 4 +
.../catalog/internal/BasicBrooklynCatalog.java | 92 +++++++++--
.../catalog/internal/CatalogClasspathDo.java | 8 +
.../catalog/internal/CatalogItemBuilder.java | 6 +
.../internal/CatalogLocationItemDto.java | 43 ++++++
.../catalog/internal/CatalogXmlSerializer.java | 2 +
.../location/basic/BasicLocationRegistry.java | 87 ++++++++++-
.../location/basic/CatalogLocationResolver.java | 79 ++++++++++
.../services/brooklyn.location.LocationResolver | 1 +
.../brooklyn/osgi/tests/SimpleLocation.java | 35 +++++
.../entity/rebind/RebindCatalogItemTest.java | 36 ++++-
.../entity/rebind/RebindTestFixture.java | 9 +-
.../osgi/brooklyn-test-osgi-entities.jar | Bin 12419 -> 13060 bytes
.../camp/brooklyn/AbstractYamlTest.java | 20 +++
.../brooklyn/EmptySoftwareProcessYamlTest.java | 39 ++---
.../catalog/CatalogYamlLocationTest.java | 152 +++++++++++++++++++
.../rest/resources/LocationResource.java | 83 +++++-----
.../rest/resources/LocationResourceTest.java | 20 ++-
.../src/main/java/brooklyn/util/yaml/Yamls.java | 9 +-
21 files changed, 673 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/api/src/main/java/brooklyn/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/catalog/CatalogItem.java b/api/src/main/java/brooklyn/catalog/CatalogItem.java
index 4dd63fa..8abaddc 100644
--- a/api/src/main/java/brooklyn/catalog/CatalogItem.java
+++ b/api/src/main/java/brooklyn/catalog/CatalogItem.java
@@ -33,7 +33,10 @@ import com.google.common.annotations.Beta;
public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
public static enum CatalogItemType {
- TEMPLATE, ENTITY, POLICY
+ TEMPLATE,
+ ENTITY,
+ POLICY,
+ LOCATION;
}
public static interface CatalogBundle {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/api/src/main/java/brooklyn/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationSpec.java b/api/src/main/java/brooklyn/location/LocationSpec.java
index 6cd26ab..7e3c4f9 100644
--- a/api/src/main/java/brooklyn/location/LocationSpec.java
+++ b/api/src/main/java/brooklyn/location/LocationSpec.java
@@ -73,6 +73,25 @@ public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec
return LocationSpec.create(type).configure(config);
}
+ /**
+ * Copies entity spec so its configuration can be overridden without modifying the
+ * original entity spec.
+ */
+ public static <T extends Location> LocationSpec<T> create(LocationSpec<T> spec) {
+ // FIXME Why can I not use LocationSpec<T>?
+ LocationSpec<?> result = create(spec.getType())
+ .displayName(spec.getDisplayName())
+ .tags(spec.getTags())
+ .configure(spec.getConfig())
+ .configure(spec.getFlags())
+ .catalogItemId(spec.getCatalogItemId())
+ .extensions(spec.getExtensions());
+
+ if (spec.getParent() != null) result.parent(spec.getParent());
+
+ return (LocationSpec<T>) result;
+ }
+
private String id;
private Location parent;
private final Map<String, Object> flags = Maps.newLinkedHashMap();
@@ -157,6 +176,14 @@ public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec
return this;
}
+ @SuppressWarnings("unchecked")
+ public <E> LocationSpec<T> extensions(Map<Class<?>, ?> extensions) {
+ for (Map.Entry<Class<?>, ?> entry : extensions.entrySet()) {
+ extension((Class)entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+
/**
* @return The id of the location to be created, or null if brooklyn can auto-generate an id
*
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
index 82ab689..4331a1a 100644
--- a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
+++ b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
@@ -24,6 +24,8 @@ import brooklyn.catalog.CatalogItem.CatalogItemType;
import brooklyn.entity.Application;
import brooklyn.entity.Entity;
import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.Location;
+import brooklyn.location.LocationSpec;
import brooklyn.management.ManagementContext;
import brooklyn.management.entitlement.Entitlements;
import brooklyn.policy.Policy;
@@ -58,6 +60,8 @@ public class CatalogPredicates {
CatalogPredicates.<Entity,EntitySpec<?>>isCatalogItemType(CatalogItemType.ENTITY);
public static final Predicate<CatalogItem<Policy,PolicySpec<?>>> IS_POLICY =
CatalogPredicates.<Policy,PolicySpec<?>>isCatalogItemType(CatalogItemType.POLICY);
+ public static final Predicate<CatalogItem<Location,LocationSpec<?>>> IS_LOCATION =
+ CatalogPredicates.<Location,LocationSpec<?>>isCatalogItemType(CatalogItemType.LOCATION);
public static final Function<CatalogItem<?,?>,String> ID_OF_ITEM_TRANSFORMER = new Function<CatalogItem<?,?>, String>() {
@Override @Nullable
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/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 5c5e05f..96760aa 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -31,6 +31,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import javax.annotation.Nullable;
@@ -38,13 +39,18 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.basic.AbstractBrooklynObjectSpec;
+import brooklyn.basic.BrooklynObjectInternal.ConfigurationSupportInternal;
import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
import brooklyn.catalog.BrooklynCatalog;
import brooklyn.catalog.CatalogItem;
import brooklyn.catalog.CatalogItem.CatalogBundle;
+import brooklyn.catalog.CatalogItem.CatalogItemType;
import brooklyn.catalog.CatalogPredicates;
import brooklyn.config.BrooklynServerConfig;
import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.Location;
+import brooklyn.location.LocationSpec;
+import brooklyn.location.basic.BasicLocationRegistry;
import brooklyn.management.ManagementContext;
import brooklyn.management.classloading.BrooklynClassLoadingContext;
import brooklyn.management.internal.EntityManagementUtils;
@@ -75,6 +81,7 @@ import com.google.common.collect.Iterables;
public class BasicBrooklynCatalog implements BrooklynCatalog {
private static final String POLICIES_KEY = "brooklyn.policies";
+ private static final String LOCATIONS_KEY = "brooklyn.locations";
public static final String NO_VERSION = "0.0.0.SNAPSHOT";
private static final Logger log = LoggerFactory.getLogger(BasicBrooklynCatalog.class);
@@ -253,6 +260,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
if (log.isTraceEnabled()) {
log.trace("Scheduling item for persistence removal: {}", itemDto.getId());
}
+ if (itemDto.getCatalogItemType() == CatalogItemType.LOCATION) {
+ @SuppressWarnings("unchecked")
+ CatalogItem<Location,LocationSpec<?>> locationItem = (CatalogItem<Location, LocationSpec<?>>) itemDto;
+ ((BasicLocationRegistry)mgmt.getLocationRegistry()).removeDefinedLocation(locationItem);
+ }
mgmt.getRebindManager().getChangeListener().onUnmanaged(itemDto);
}
@@ -318,7 +330,10 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
case POLICY:
spec = createPolicySpec(plan, loader);
break;
- default: throw new RuntimeException("Only entity & policy catalog items are supported. Unsupported catalog item type " + item.getCatalogItemType());
+ case LOCATION:
+ spec = createLocationSpec(plan, loader);
+ break;
+ default: throw new RuntimeException("Only entity, policy & location catalog items are supported. Unsupported catalog item type " + item.getCatalogItemType());
}
((AbstractBrooklynObjectSpec<?, ?>)spec).catalogItemId(item.getId());
return spec;
@@ -366,7 +381,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
}
}
-
@SuppressWarnings("unchecked")
private <T, SpecT> SpecT createPolicySpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
//Would ideally re-use io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver.PolicySpecResolver
@@ -378,23 +392,70 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
Object policy = Iterables.getOnlyElement((Iterable<?>)policies);
- Map<String, Object> policyConfig;
+ Map<String, Object> config;
if (policy instanceof String) {
- policyConfig = ImmutableMap.<String, Object>of("type", policy);
+ config = ImmutableMap.<String, Object>of("type", policy);
} else if (policy instanceof Map) {
- policyConfig = (Map<String, Object>) policy;
+ config = (Map<String, Object>) policy;
} else {
- throw new IllegalStateException("Policy exepcted to be string or map. Unsupported object type " + policy.getClass().getName() + " (" + policy.toString() + ")");
+ throw new IllegalStateException("Policy expected to be string or map. Unsupported object type " + policy.getClass().getName() + " (" + policy.toString() + ")");
}
- String policyType = (String) checkNotNull(Yamls.getMultinameAttribute(policyConfig, "policy_type", "policyType", "type"), "policy type");
- Map<String, Object> brooklynConfig = (Map<String, Object>) policyConfig.get("brooklyn.config");
- PolicySpec<? extends Policy> spec = PolicySpec.create(loader.loadClass(policyType, Policy.class));
+ String type = (String) checkNotNull(Yamls.getMultinameAttribute(config, "policy_type", "policyType", "type"), "policy type");
+ Map<String, Object> brooklynConfig = (Map<String, Object>) config.get("brooklyn.config");
+ PolicySpec<? extends Policy> spec = PolicySpec.create(loader.loadClass(type, Policy.class));
if (brooklynConfig != null) {
spec.configure(brooklynConfig);
}
return (SpecT) spec;
}
+
+ @SuppressWarnings("unchecked")
+ private <T, SpecT> SpecT createLocationSpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+ // See #createPolicySpec; this impl is modeled on that.
+ // spec.catalogItemId is set by caller
+ Object locations = checkNotNull(plan.getCustomAttributes().get(LOCATIONS_KEY), "location config");
+ if (!(locations instanceof Iterable<?>)) {
+ throw new IllegalStateException("The value of " + LOCATIONS_KEY + " must be an Iterable.");
+ }
+
+ Object location = Iterables.getOnlyElement((Iterable<?>)locations);
+
+ Map<String, Object> config;
+ if (location instanceof String) {
+ config = ImmutableMap.<String, Object>of("type", location);
+ } else if (location instanceof Map) {
+ config = (Map<String, Object>) location;
+ } else {
+ throw new IllegalStateException("Location expected to be string or map. Unsupported object type " + location.getClass().getName() + " (" + location.toString() + ")");
+ }
+
+ String type = (String) checkNotNull(Yamls.getMultinameAttribute(config, "location_type", "locationType", "type"), "location type");
+ Map<String, Object> brooklynConfig = (Map<String, Object>) config.get("brooklyn.config");
+ Maybe<Class<? extends Location>> javaClass = loader.tryLoadClass(type, Location.class);
+ if (javaClass.isPresent()) {
+ LocationSpec<?> spec = LocationSpec.create(javaClass.get());
+ if (brooklynConfig != null) {
+ spec.configure(brooklynConfig);
+ }
+ return (SpecT) spec;
+ } else {
+ Maybe<Location> loc = mgmt.getLocationRegistry().resolve(type, false, brooklynConfig);
+ if (loc.isPresent()) {
+ // TODO extensions?
+ Map<String, Object> locConfig = ((ConfigurationSupportInternal)loc.get().config()).getBag().getAllConfig();
+ Class<? extends Location> locType = loc.get().getClass();
+ Set<Object> locTags = loc.get().tags().getTags();
+ String locDisplayName = loc.get().getDisplayName();
+ return (SpecT) LocationSpec.create(locType)
+ .configure(locConfig)
+ .displayName(locDisplayName)
+ .tags(locTags);
+ } else {
+ throw new IllegalStateException("No class or resolver found for location type "+type);
+ }
+ }
+ }
@SuppressWarnings("unchecked")
@Override
@@ -557,6 +618,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
private AbstractBrooklynObjectSpec<?,?> createSpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
if (isPolicyPlan(plan)) {
return createPolicySpec(plan, loader);
+ } else if (isLocationPlan(plan)) {
+ return createLocationSpec(plan, loader);
} else {
return createEntitySpec(symbolicName, plan, loader);
}
@@ -571,6 +634,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
}
} else if (spec instanceof PolicySpec) {
return CatalogItemBuilder.newPolicy(itemId, version);
+ } else if (spec instanceof LocationSpec) {
+ return CatalogItemBuilder.newLocation(itemId, version);
} else {
throw new IllegalStateException("Unknown spec type " + spec.getClass().getName() + " (" + spec + ")");
}
@@ -584,6 +649,10 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
return plan.getCustomAttributes().containsKey(POLICIES_KEY);
}
+ private boolean isLocationPlan(DeploymentPlan plan) {
+ return plan.getCustomAttributes().containsKey(LOCATIONS_KEY);
+ }
+
private DeploymentPlan makePlanFromYaml(String yaml) {
CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
return camp.pdp().parseDeploymentPlan(Streams.newReaderWithContents(yaml));
@@ -611,6 +680,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
if (log.isTraceEnabled()) {
log.trace("Scheduling item for persistence addition: {}", itemDto.getId());
}
+ if (itemDto.getCatalogItemType() == CatalogItemType.LOCATION) {
+ @SuppressWarnings("unchecked")
+ CatalogItem<Location,LocationSpec<?>> locationItem = (CatalogItem<Location, LocationSpec<?>>) itemDto;
+ ((BasicLocationRegistry)mgmt.getLocationRegistry()).updateDefinedLocation(locationItem);
+ }
mgmt.getRebindManager().getChangeListener().onManaged(itemDto);
return itemDto;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
index 6ec073f..095ebfd 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
@@ -36,6 +36,7 @@ import brooklyn.entity.Application;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.ApplicationBuilder;
import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.location.Location;
import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.policy.Policy;
import brooklyn.util.exceptions.Exceptions;
@@ -193,6 +194,12 @@ public class CatalogClasspathDo {
addCatalogEntry(new CatalogPolicyItemDto(), c);
count++;
}
+
+ Iterable<Class<? extends Location>> locations = this.excludeInvalidClasses(scanner.getSubTypesOf(Location.class));
+ for (Class<?> c: locations) {
+ addCatalogEntry(new CatalogLocationItemDto(), c);
+ count++;
+ }
} else {
throw new IllegalStateException("Unsupported catalog scan mode "+scanMode+" for "+this);
}
@@ -233,6 +240,7 @@ public class CatalogClasspathDo {
if (ApplicationBuilder.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogTemplateItemDto(), c);
if (Entity.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogEntityItemDto(), c);
if (Policy.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogPolicyItemDto(), c);
+ if (Location.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogLocationItemDto(), c);
throw new IllegalStateException("Cannot add "+c+" to catalog: unsupported type "+c.getName());
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/catalog/internal/CatalogItemBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogItemBuilder.java b/core/src/main/java/brooklyn/catalog/internal/CatalogItemBuilder.java
index 722220b..2b16cc6 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogItemBuilder.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogItemBuilder.java
@@ -46,6 +46,12 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
.version(version);
}
+ public static CatalogItemBuilder<CatalogLocationItemDto> newLocation(String symbolicName, String version) {
+ return new CatalogItemBuilder<CatalogLocationItemDto>(new CatalogLocationItemDto())
+ .symbolicName(symbolicName)
+ .version(version);
+ }
+
public CatalogItemBuilder(CatalogItemType dto) {
this.dto = dto;
this.dto.setLibraries(Collections.<CatalogBundle>emptyList());
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
new file mode 100644
index 0000000..e8bf2ec
--- /dev/null
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
@@ -0,0 +1,43 @@
+/*
+ * 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 brooklyn.catalog.internal;
+
+import brooklyn.location.Location;
+import brooklyn.location.LocationSpec;
+
+
+public class CatalogLocationItemDto extends CatalogItemDtoAbstract<Location,LocationSpec<?>> {
+
+ @Override
+ public CatalogItemType getCatalogItemType() {
+ return CatalogItemType.LOCATION;
+ }
+
+ @Override
+ public Class<Location> getCatalogItemJavaType() {
+ return Location.class;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public Class<LocationSpec<?>> getSpecType() {
+ return (Class)LocationSpec.class;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/catalog/internal/CatalogXmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogXmlSerializer.java b/core/src/main/java/brooklyn/catalog/internal/CatalogXmlSerializer.java
index 46c014f..dbfd3fc 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogXmlSerializer.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogXmlSerializer.java
@@ -45,10 +45,12 @@ public class CatalogXmlSerializer extends XmlSerializer<Object> {
xstream.addImplicitCollection(CatalogDto.class, "entries", CatalogTemplateItemDto.class);
xstream.addImplicitCollection(CatalogDto.class, "entries", CatalogEntityItemDto.class);
xstream.addImplicitCollection(CatalogDto.class, "entries", CatalogPolicyItemDto.class);
+ xstream.addImplicitCollection(CatalogDto.class, "entries", CatalogLocationItemDto.class);
xstream.aliasType("template", CatalogTemplateItemDto.class);
xstream.aliasType("entity", CatalogEntityItemDto.class);
xstream.aliasType("policy", CatalogPolicyItemDto.class);
+ xstream.aliasType("location", CatalogPolicyItemDto.class);
xstream.aliasField("registeredType", CatalogItemDtoAbstract.class, "symbolicName");
xstream.aliasAttribute(CatalogItemDtoAbstract.class, "displayName", "name");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
index 365b347..f0b466e 100644
--- a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
+++ b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
@@ -33,6 +33,9 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.catalog.BrooklynCatalog;
+import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
import brooklyn.config.ConfigMap;
import brooklyn.config.ConfigPredicates;
import brooklyn.config.ConfigUtils;
@@ -41,6 +44,7 @@ import brooklyn.location.LocationDefinition;
import brooklyn.location.LocationRegistry;
import brooklyn.location.LocationResolver;
import brooklyn.location.LocationResolver.EnableableLocationResolver;
+import brooklyn.location.LocationSpec;
import brooklyn.management.ManagementContext;
import brooklyn.management.internal.LocalLocationManager;
import brooklyn.util.collections.MutableMap;
@@ -59,9 +63,65 @@ import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
+/**
+ * See {@link LocationRegistry} for general description.
+ * <p>
+ * TODO The relationship between the catalog and the location registry is a bit messy.
+ * For all existing code, the location registry is the definitive way to resolve
+ * locations.
+ * <p>
+ * Any location item added to the catalog must therefore be registered here.
+ * Whenever an item is added to the catalog, it will automatically call
+ * {@link #updateDefinedLocation(CatalogItem)}. Similarly, when a location
+ * is deleted from the catalog it will call {@link #removeDefinedLocation(CatalogItem)}.
+ * <p>
+ * However, the location item in the catalog has an unparsed blob of YAML, which contains
+ * important things like the type and the config of the location. This is only parsed when
+ * {@link BrooklynCatalog#createSpec(CatalogItem)} is called. We therefore jump through
+ * some hoops to wire together the catalog and the registry.
+ * <p>
+ * To add a location to the catalog, and then to resolve a location that is in the catalog,
+ * it goes through the following steps:
+ *
+ * <ol>
+ * <li>Call {@link BrooklynCatalog#addItem(String)}
+ * <ol>
+ * <li>This automatically calls {@link #updateDefinedLocation(CatalogItem)}
+ * <li>A LocationDefinition is creating, using as its id the {@link CatalogItem#getSymbolicName()}.
+ * The definition's spec is {@code brooklyn.catalog:<symbolicName>:<version>},
+ * </ol>
+ * <li>A blueprint can reference the catalog item using its symbolic name,
+ * such as the YAML {@code location: my-new-location}.
+ * (this feels similar to the "named locations").
+ * <ol>
+ * <li>This automatically calls {@link #resolve(String)}.
+ * <li>The LocationDefinition is found by lookig up this name.
+ * <li>The {@link LocationDefiniton.getSpec()} is retrieved; the right {@link LocationResolver} is
+ * found for it.
+ * <li>This uses the {@link CatalogLocationResolver}, because the spec starts with {@code brooklyn.catalog:}.
+ * <li>This resolver extracts from the spec the <symobolicName>:<version>, and looks up the
+ * catalog item using {@link BrooklynCatalog#getCatalogItem(String, String)}.
+ * <li>It then creates a {@link LocationSpec} by calling {@link BrooklynCatalog#createSpec(CatalogItem)}.
+ * <ol>
+ * <li>This first tries to use the type (that is in the YAML) as a simple Java class.
+ * <li>If that fails, it will resolve the type using {@link #resolve(String, Boolean, Map)}, which
+ * returns an actual location object.
+ * <li>It extracts from that location object the appropriate metadata to create a {@link LocationSpec},
+ * returns the spec and discards the location object.
+ * </ol>
+ * <li>The resolver creates the {@link Location} from the {@link LocationSpec}
+ * </ol>
+ * </ol>
+ *
+ * There is no concept of a location version in this registry. The version
+ * in the catalog is generally ignored.
+ */
@SuppressWarnings({"rawtypes","unchecked"})
public class BasicLocationRegistry implements LocationRegistry {
+ // TODO save / serialize
+ // (we persist live locations, ie those in the LocationManager, but not "catalog" locations, ie those in this Registry)
+
public static final Logger log = LoggerFactory.getLogger(BasicLocationRegistry.class);
/**
@@ -139,6 +199,25 @@ public class BasicLocationRegistry implements LocationRegistry {
}
}
+ /**
+ * Converts the given item from the catalog into a LocationDefinition, and adds it
+ * to the registry (overwriting anything already registered with the id
+ * {@link CatalogItem#getCatalogItemId()}.
+ */
+ public void updateDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
+ String id = item.getCatalogItemId();
+ String symbolicName = item.getSymbolicName();
+ String spec = CatalogLocationResolver.NAME + ":" + id;
+ Map<String, Object> config = ImmutableMap.<String, Object>of();
+ BasicLocationDefinition locDefinition = new BasicLocationDefinition(symbolicName, symbolicName, spec, config);
+
+ updateDefinedLocation(locDefinition);
+ }
+
+ public void removeDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
+ removeDefinedLocation(item.getSymbolicName());
+ }
+
@Override
public void removeDefinedLocation(String id) {
LocationDefinition removed;
@@ -183,12 +262,14 @@ public class BasicLocationRegistry implements LocationRegistry {
definedLocations.put(id, localhost(id));
definedLocations.putAll(oldDefined);
}
+
+ for (CatalogItem<Location, LocationSpec<?>> item : mgmt.getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) {
+ updateDefinedLocation(item);
+ count++;
+ }
}
}
- // TODO save / serialize
- // (we persist live locations, ie those in the LocationManager, but not "catalog" locations, ie those in this Registry)
-
@VisibleForTesting
void disablePersistence() {
// persistence isn't enabled yet anyway (have to manually save things,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java b/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
new file mode 100644
index 0000000..4823b05
--- /dev/null
+++ b/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
@@ -0,0 +1,79 @@
+/*
+ * 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 brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.location.Location;
+import brooklyn.location.LocationRegistry;
+import brooklyn.location.LocationResolver;
+import brooklyn.location.LocationSpec;
+import brooklyn.management.ManagementContext;
+
+/**
+ * Given a location spec in the form {@code brooklyn.catalog:<symbolicName>:<version>},
+ * looks up the catalog to get its definition and creates such a location.
+ */
+public class CatalogLocationResolver implements LocationResolver {
+
+ private static final Logger log = LoggerFactory.getLogger(CatalogLocationResolver.class);
+
+ public static final String NAME = "brooklyn.catalog";
+
+ private ManagementContext managementContext;
+
+ @Override
+ public void init(ManagementContext managementContext) {
+ this.managementContext = checkNotNull(managementContext, "managementContext");
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes" })
+ public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
+ String id = spec.substring(NAME.length()+1);
+ CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(managementContext, id);
+ LocationSpec<?> origLocSpec = managementContext.getCatalog().createSpec((CatalogItem<Location, LocationSpec<?>>)item);
+ LocationSpec<?> locSpec = LocationSpec.create(origLocSpec)
+ .configure(locationFlags);
+ return managementContext.getLocationManager().createLocation(locSpec);
+ }
+
+ @Override
+ public String getPrefix() {
+ return NAME;
+ }
+
+ /**
+ * accepts anything that looks like it will be a YAML catalog item (e.g. starting "brooklyn.locations")
+ */
+ @Override
+ public boolean accepts(String spec, LocationRegistry registry) {
+ if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
+ if (registry.getDefinedLocationByName(spec)!=null) return true;
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver b/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
index 74df3da..fd14323 100644
--- a/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
+++ b/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
@@ -1,5 +1,6 @@
brooklyn.location.basic.DefinedLocationByIdResolver
brooklyn.location.basic.NamedLocationResolver
+brooklyn.location.basic.CatalogLocationResolver
brooklyn.location.basic.LocalhostLocationResolver
brooklyn.location.basic.ByonLocationResolver
brooklyn.location.basic.SingleMachineLocationResolver
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/test/dependencies/osgi/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/dependencies/osgi/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java b/core/src/test/dependencies/osgi/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
new file mode 100644
index 0000000..253a2b0
--- /dev/null
+++ b/core/src/test/dependencies/osgi/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
@@ -0,0 +1,35 @@
+/*
+ * 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 brooklyn.osgi.tests;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.location.basic.AbstractLocation;
+import brooklyn.util.flags.SetFromFlag;
+
+public class SimpleLocation extends AbstractLocation {
+ @SetFromFlag("config1")
+ public static final ConfigKey<String> CONFIG1 = ConfigKeys.newStringConfigKey("config1");
+
+ @SetFromFlag("config2")
+ public static final ConfigKey<String> CONFIG2 = ConfigKeys.newStringConfigKey("config2");
+
+ @SetFromFlag("config3")
+ public static final ConfigKey<String> CONFIG3 = ConfigKeys.newStringConfigKey("config3");
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
index 4454354..a64b269 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
@@ -34,6 +34,7 @@ import org.testng.annotations.Test;
import brooklyn.camp.lite.CampPlatformWithJustBrooklynMgmt;
import brooklyn.camp.lite.TestAppAssemblyInstantiator;
import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogItem.CatalogItemType;
import brooklyn.catalog.CatalogLoadMode;
import brooklyn.catalog.internal.BasicBrooklynCatalog;
import brooklyn.catalog.internal.CatalogDto;
@@ -41,11 +42,15 @@ import brooklyn.config.BrooklynProperties;
import brooklyn.config.BrooklynServerConfig;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.internal.BrooklynFeatureEnablement;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.management.ManagementContext;
import brooklyn.management.internal.LocalManagementContext;
import brooklyn.policy.basic.AbstractPolicy;
import brooklyn.test.entity.TestEntity;
+import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
@@ -112,8 +117,7 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
" version: " + TEST_VERSION + "\n" +
"services:\n" +
"- type: io.camp.mock:AppServer";
- CatalogItem<?, ?> added = origManagementContext.getCatalog().addItem(yaml);
- LOG.info("Added item to catalog: {}, id={}", added, added.getId());
+ addItem(origManagementContext, yaml);
rebindAndAssertCatalogsAreEqual();
}
@@ -135,8 +139,24 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
" brooklyn.config:\n" +
" cfg1: 111\n" +
" cfg2: 222";
- CatalogItem<?, ?> added = origManagementContext.getCatalog().addItem(yaml);
- LOG.info("Added item to catalog: {}, id={}", added, added.getId());
+ addItem(origManagementContext, yaml);
+ rebindAndAssertCatalogsAreEqual();
+ }
+
+ @Test
+ public void testAddAndRebindLocation() {
+ String yaml = Joiner.on("\n").join(ImmutableList.of(
+ "name: Test Location",
+ "brooklyn.catalog:",
+ " id: sample_location",
+ " version: " + TEST_VERSION,
+ "brooklyn.locations:",
+ "- type: "+LocalhostMachineProvisioningLocation.class.getName(),
+ " brooklyn.config:",
+ " cfg1: 111",
+ " cfg2: 222"));
+ CatalogItem<?, ?> added = addItem(origManagementContext, yaml);
+ assertEquals(added.getCatalogItemType(), CatalogItemType.LOCATION);
rebindAndAssertCatalogsAreEqual();
}
@@ -210,6 +230,13 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
assertTrue(catalogItemAfterRebind.isDeprecated(), "Expected item to be deprecated");
}
+ protected CatalogItem<?, ?> addItem(ManagementContext mgmt, String yaml) {
+ CatalogItem<?, ?> added = mgmt.getCatalog().addItem(yaml);
+ LOG.info("Added item to catalog: {}, id={}", added, added.getId());
+ assertCatalogContains(mgmt.getCatalog(), added);
+ return added;
+ }
+
private void rebindAndAssertCatalogsAreEqual() {
try {
rebind();
@@ -218,5 +245,4 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
}
assertCatalogsEqual(newManagementContext.getCatalog(), origManagementContext.getCatalog());
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
index 8f1c1c6..21ab69f 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
@@ -19,6 +19,7 @@
package brooklyn.entity.rebind;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
import java.io.File;
import java.util.List;
@@ -53,9 +54,9 @@ import brooklyn.util.task.BasicExecutionManager;
import brooklyn.util.text.Identifiers;
import brooklyn.util.time.Duration;
-import com.google.common.collect.Sets;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
public abstract class RebindTestFixture<T extends StartableApplication> {
@@ -303,4 +304,10 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
assertEquals(actual.getSymbolicName(), expected.getSymbolicName());
assertEquals(actual.getLibraries(), expected.getLibraries());
}
+
+ protected void assertCatalogContains(BrooklynCatalog catalog, CatalogItem<?, ?> item) {
+ CatalogItem<?, ?> found = catalog.getCatalogItem(item.getSymbolicName(), item.getVersion());
+ assertNotNull(found);
+ assertCatalogItemsEqual(found, item);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/core/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar
----------------------------------------------------------------------
diff --git a/core/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar b/core/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar
index 008150a..5a3b052 100644
Binary files a/core/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar and b/core/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar differ
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
index aa1922c..dd7ad58 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
@@ -39,8 +39,12 @@ import brooklyn.management.Task;
import brooklyn.management.internal.LocalManagementContext;
import brooklyn.test.entity.LocalManagementContextForTests;
import brooklyn.util.ResourceUtils;
+import brooklyn.util.config.ConfigBag;
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
public abstract class AbstractYamlTest {
@@ -119,6 +123,14 @@ public abstract class AbstractYamlTest {
getLogger().info("Test - created " + assembly);
final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
getLogger().info("App - " + app);
+
+ // wait for app to have started
+ Set<Task<?>> tasks = brooklynMgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+ BrooklynTaskTags.EFFECTOR_TAG,
+ BrooklynTaskTags.tagForContextEntity(app),
+ BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
+ Iterables.getOnlyElement(tasks).get();
+
return app;
}
@@ -132,6 +144,10 @@ public abstract class AbstractYamlTest {
return app;
}
+ protected void addCatalogItem(Iterable<String> catalogYaml) {
+ addCatalogItem(join(catalogYaml));
+ }
+
protected void addCatalogItem(String... catalogYaml) {
addCatalogItem(join(catalogYaml));
}
@@ -148,6 +164,10 @@ public abstract class AbstractYamlTest {
return LOG;
}
+ private String join(Iterable<String> catalogYaml) {
+ return Joiner.on("\n").join(catalogYaml);
+ }
+
private String join(String[] catalogYaml) {
return Joiner.on("\n").join(catalogYaml);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
index eb2358d..9b7bc7b 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
@@ -32,17 +32,19 @@ import brooklyn.entity.basic.Entities;
import brooklyn.location.Location;
import brooklyn.location.basic.SshMachineLocation;
import brooklyn.util.collections.Jsonya;
-import brooklyn.util.stream.Streams;
@Test
public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
private static final Logger log = LoggerFactory.getLogger(EnrichersYamlTest.class);
- @Test
+ @Test(groups="Integration")
public void testProvisioningProperties() throws Exception {
- Entity app = createAndStartApplication(Streams.newReaderWithContents(
- "services: [ { serviceType: "+EmptySoftwareProcess.class.getName()+","
- + " provisioning.properties: { minRam: 16384 } } ]"));
+ Entity app = createAndStartApplication(
+ "location: localhost",
+ "services:",
+ "- type: "+EmptySoftwareProcess.class.getName(),
+ " provisioning.properties:",
+ " minRam: 16384");
waitForApplicationTasks(app);
log.info("App started:");
@@ -53,14 +55,15 @@ public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
Assert.assertEquals(pp.get("minRam"), 16384);
}
- @Test
+ @Test(groups="Integration")
public void testProvisioningPropertiesViaJsonya() throws Exception {
- Entity app = createAndStartApplication(Streams.newReaderWithContents(
- Jsonya.newInstance().at("services").list()
- .put("serviceType", EmptySoftwareProcess.class.getName())
+ Entity app = createAndStartApplication(
+ Jsonya.newInstance()
+ .put("location", "localhost")
+ .at("services").list()
+ .put("type", EmptySoftwareProcess.class.getName())
.at("provisioning.properties").put("minRam", 16384)
- .root().toString()
- ));
+ .root().toString());
waitForApplicationTasks(app);
log.info("App started:");
@@ -71,13 +74,14 @@ public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
Assert.assertEquals(pp.get("minRam"), 16384);
}
- @Test
- // for issue #1377
+ // for https://github.com/brooklyncentral/brooklyn/issues/1377
+ @Test(groups="Integration")
public void testWithAppAndEntityLocations() throws Exception {
- Entity app = createAndStartApplication(Streams.newReaderWithContents("services:\n"+
- "- serviceType: "+EmptySoftwareProcess.class.getName()+"\n"+
- " location: localhost:(name=localhost on entity)"+"\n"+
- "location: byon:(hosts=\"127.0.0.1\", name=loopback on app)"));
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: "+EmptySoftwareProcess.class.getName(),
+ " location: localhost:(name=localhost on entity)",
+ "location: byon:(hosts=\"127.0.0.1\", name=loopback on app)");
waitForApplicationTasks(app);
Entities.dumpInfo(app);
@@ -96,5 +100,4 @@ public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
// TODO this, below, probably should be 'localhost on entity', see #1377
Assert.assertEquals(actualMachine.getParent().getDisplayName(), "loopback on app");
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
new file mode 100644
index 0000000..ef5aa0f
--- /dev/null
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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 io.brooklyn.camp.brooklyn.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import io.brooklyn.camp.brooklyn.AbstractYamlTest;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.Entity;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.location.Location;
+import brooklyn.location.LocationDefinition;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+import brooklyn.test.TestResourceUnavailableException;
+import brooklyn.util.text.StringFunctions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class CatalogYamlLocationTest extends AbstractYamlTest {
+ private static final String LOCALHOST_LOCATION_SPEC = "localhost";
+ private static final String LOCALHOST_LOCATION_TYPE = LocalhostMachineProvisioningLocation.class.getName();
+ private static final String SIMPLE_LOCATION_TYPE = "brooklyn.osgi.tests.SimpleLocation";
+
+ @Test
+ public void testAddCatalogItem() throws Exception {
+ assertEquals(countCatalogLocations(), 0);
+
+ String symbolicName = "my.catalog.location.id.load";
+ addCatalogOSGiLocation(symbolicName, SIMPLE_LOCATION_TYPE);
+
+ CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+ assertEquals(item.getSymbolicName(), symbolicName);
+ assertEquals(countCatalogLocations(), 1);
+
+ // Item added to catalog should automatically be available in location registry
+ LocationDefinition def = mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName);
+ assertEquals(def.getId(), symbolicName);
+ assertEquals(def.getName(), symbolicName);
+
+ // Deleting item: should be gone from catalog, and from location registry
+ deleteCatalogEntity(symbolicName);
+
+ assertEquals(countCatalogLocations(), 0);
+ assertNull(mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName));
+ }
+
+ @Test
+ public void testLaunchApplicationReferencingLocationClass() throws Exception {
+ String symbolicName = "my.catalog.location.id.launch";
+ addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+ runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+ deleteCatalogEntity(symbolicName);
+ }
+
+ @Test
+ public void testLaunchApplicationReferencingLocationSpec() throws Exception {
+ String symbolicName = "my.catalog.location.id.launch";
+ addCatalogLocation(symbolicName, LOCALHOST_LOCATION_SPEC);
+ runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+ deleteCatalogEntity(symbolicName);
+ }
+
+ @Test
+ public void testLaunchApplicationReferencingOsgiLocation() throws Exception {
+ String symbolicName = "my.catalog.location.id.launch";
+ addCatalogOSGiLocation(symbolicName, SIMPLE_LOCATION_TYPE);
+ runLaunchApplicationReferencingLocation(symbolicName, SIMPLE_LOCATION_TYPE);
+
+ deleteCatalogEntity(symbolicName);
+ }
+
+ protected void runLaunchApplicationReferencingLocation(String locTypeInYaml, String locType) throws Exception {
+ Entity app = createAndStartApplication(
+ "name: simple-app-yaml",
+ "location: ",
+ " "+locTypeInYaml+":",
+ " config2: config2 override",
+ " config3: config3",
+ "services: ",
+ " - type: brooklyn.entity.basic.BasicStartable");
+
+ Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+ Location location = Iterables.getOnlyElement(simpleEntity.getLocations());
+ assertEquals(location.getClass().getName(), locType);
+ assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
+ assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
+ assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
+ }
+
+ private void addCatalogLocation(String symbolicName, String serviceType) {
+ addCatalogLocation(symbolicName, serviceType, ImmutableList.<String>of());
+ }
+
+ private void addCatalogOSGiLocation(String symbolicName, String serviceType) {
+ TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+ addCatalogLocation(symbolicName, serviceType, ImmutableList.of(OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL));
+ }
+
+ private void addCatalogLocation(String symbolicName, String serviceType, List<String> libraries) {
+ ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " name: My Catalog Location",
+ " description: My description",
+ " version: " + TEST_VERSION);
+ if (libraries.size() > 0) {
+ yaml.add(" libraries:")
+ .addAll(Lists.transform(libraries, StringFunctions.prepend(" - url: ")));
+ }
+ yaml.add(
+ "",
+ "brooklyn.locations:",
+ "- type: " + serviceType,
+ " brooklyn.config:",
+ " config1: config1",
+ " config2: config2");
+
+
+ addCatalogItem(yaml.build());
+ }
+
+ private int countCatalogLocations() {
+ return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
index d4f004c..aa73215 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
@@ -29,9 +29,9 @@ import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.catalog.CatalogItem;
import brooklyn.location.Location;
import brooklyn.location.LocationDefinition;
-import brooklyn.location.basic.BasicLocationDefinition;
import brooklyn.location.basic.LocationConfigKeys;
import brooklyn.rest.api.LocationApi;
import brooklyn.rest.domain.LocationSpec;
@@ -43,10 +43,11 @@ import brooklyn.rest.util.EntityLocationUtils;
import brooklyn.rest.util.WebResourceUtils;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.Identifiers;
import com.google.common.base.Function;
+import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
public class LocationResource extends AbstractBrooklynRestResource implements LocationApi {
@@ -101,40 +102,52 @@ public class LocationResource extends AbstractBrooklynRestResource implements Lo
return result;
}
- /** @deprecated since 0.7.0; REST call now handled by below (optional query parameter added) */
- public LocationSummary get(String locationId) {
- return get(locationId, false);
- }
-
- @Override
- public LocationSummary get(String locationId, String fullConfig) {
- return get(locationId, Boolean.valueOf(fullConfig));
- }
-
- public LocationSummary get(String locationId, boolean fullConfig) {
- LocationDetailLevel configLevel = fullConfig ? LocationDetailLevel.FULL_EXCLUDING_SECRET : LocationDetailLevel.LOCAL_EXCLUDING_SECRET;
- Location l1 = mgmt().getLocationManager().getLocation(locationId);
- if (l1!=null) {
- return LocationTransformer.newInstance(mgmt(), l1, configLevel);
+ /** @deprecated since 0.7.0; REST call now handled by below (optional query parameter added) */
+ public LocationSummary get(String locationId) {
+ return get(locationId, false);
}
- LocationDefinition l2 = brooklyn().getLocationRegistry().getDefinedLocationById(locationId);
- if (l2==null) throw WebResourceUtils.notFound("No location matching %s", locationId);
- return LocationTransformer.newInstance(mgmt(), l2, configLevel);
- }
-
- @Override
- public Response create(LocationSpec locationSpec) {
- String id = Identifiers.makeRandomId(8);
- LocationDefinition l = new BasicLocationDefinition(id, locationSpec.getName(), locationSpec.getSpec(), locationSpec.getConfig());
- brooklyn().getLocationRegistry().updateDefinedLocation(l);
- return Response.created(URI.create(id))
- .entity(LocationTransformer.newInstance(mgmt(), l, LocationDetailLevel.LOCAL_EXCLUDING_SECRET))
- .build();
- }
-
- public void delete(String locationId) {
- brooklyn().getLocationRegistry().removeDefinedLocation(locationId);
- }
+ @Override
+ public LocationSummary get(String locationId, String fullConfig) {
+ return get(locationId, Boolean.valueOf(fullConfig));
+ }
+
+ public LocationSummary get(String locationId, boolean fullConfig) {
+ LocationDetailLevel configLevel = fullConfig ? LocationDetailLevel.FULL_EXCLUDING_SECRET : LocationDetailLevel.LOCAL_EXCLUDING_SECRET;
+ Location l1 = mgmt().getLocationManager().getLocation(locationId);
+ if (l1!=null) {
+ return LocationTransformer.newInstance(mgmt(), l1, configLevel);
+ }
+
+ LocationDefinition l2 = brooklyn().getLocationRegistry().getDefinedLocationById(locationId);
+ if (l2==null) throw WebResourceUtils.notFound("No location matching %s", locationId);
+ return LocationTransformer.newInstance(mgmt(), l2, configLevel);
+ }
+ @Override
+ public Response create(LocationSpec locationSpec) {
+ String name = locationSpec.getName();
+ ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
+ "brooklyn.catalog:",
+ " symbolicName: "+name,
+ "",
+ "brooklyn.locations:",
+ "- type: "+locationSpec.getSpec());
+ if (locationSpec.getConfig().size() > 0) {
+ yaml.add(" brooklyn.config:");
+ for (Map.Entry<String, ?> entry : locationSpec.getConfig().entrySet()) {
+ yaml.add(" "+entry.getKey()+": "+entry.getValue());
+ }
+ }
+
+ CatalogItem<?, ?> item = brooklyn().getCatalog().addItem(Joiner.on("\n").join(yaml.build()));
+ LocationDefinition l = brooklyn().getLocationRegistry().getDefinedLocationByName(name);
+ return Response.created(URI.create(name))
+ .entity(LocationTransformer.newInstance(mgmt(), l, LocationDetailLevel.LOCAL_EXCLUDING_SECRET))
+ .build();
+ }
+
+ public void delete(String locationId) {
+ brooklyn().getLocationRegistry().removeDefinedLocation(locationId);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/usage/rest-server/src/test/java/brooklyn/rest/resources/LocationResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/LocationResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/LocationResourceTest.java
index 0511ca4..5ccf591 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/LocationResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/LocationResourceTest.java
@@ -20,7 +20,6 @@ package brooklyn.rest.resources;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
-import static org.testng.Assert.assertFalse;
import java.net.URI;
import java.util.Map;
@@ -57,24 +56,23 @@ public class LocationResourceTest extends BrooklynRestResourceTest {
public void testAddNewLocation() {
Map<String, String> expectedConfig = ImmutableMap.of(
"identity", "bob",
- "credential", "CR3dential",
- "location", "us-east-1");
+ "credential", "CR3dential");
ClientResponse response = client().resource("/v1/locations")
.type(MediaType.APPLICATION_JSON_TYPE)
- .post(ClientResponse.class, new LocationSpec("my-jungle", "aws-ec2", expectedConfig));
+ .post(ClientResponse.class, new LocationSpec("my-jungle", "aws-ec2:us-east-1", expectedConfig));
addedLocationUri = response.getLocation();
log.info("added, at: " + addedLocationUri);
LocationSummary location = client().resource(response.getLocation()).get(LocationSummary.class);
log.info(" contents: " + location);
- assertThat(location.getSpec(), is("aws-ec2"));
-
- assertThat(location.getConfig().get("identity"), is((Object) "bob"));
- assertFalse(location.getConfig().containsKey("CR3dential"));
+ Assert.assertEquals(location.getSpec(), "brooklyn.catalog:my-jungle:0.0.0.SNAPSHOT");
Assert.assertTrue(addedLocationUri.toString().startsWith("/v1/locations/"));
- JcloudsLocation l = (JcloudsLocation) getManagementContext().getLocationRegistry().resolve(location.getId());
+ JcloudsLocation l = (JcloudsLocation) getManagementContext().getLocationRegistry().resolve("my-jungle");
Assert.assertEquals(l.getProvider(), "aws-ec2");
+ Assert.assertEquals(l.getRegion(), "us-east-1");
+ Assert.assertEquals(l.getIdentity(), "bob");
+ Assert.assertEquals(l.getCredential(), "CR3dential");
}
@Test(dependsOnMethods = { "testAddNewLocation" })
@@ -88,14 +86,14 @@ public class LocationResourceTest extends BrooklynRestResourceTest {
}
});
LocationSummary location = Iterables.getOnlyElement(matching);
- assertThat(location.getSpec(), is("aws-ec2"));
+ assertThat(location.getSpec(), is("brooklyn.catalog:my-jungle:0.0.0.SNAPSHOT"));
Assert.assertEquals(location.getLinks().get("self"), addedLocationUri);
}
@Test(dependsOnMethods = { "testListAllLocations" })
public void testGetASpecificLocation() {
LocationSummary location = client().resource(addedLocationUri.toString()).get(LocationSummary.class);
- assertThat(location.getSpec(), is("aws-ec2"));
+ assertThat(location.getSpec(), is("brooklyn.catalog:my-jungle:0.0.0.SNAPSHOT"));
}
@Test(dependsOnMethods = { "testGetASpecificLocation" })
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09a64755/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
index 7c946dd..ad56bfe 100644
--- a/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
+++ b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
@@ -29,6 +29,9 @@ import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.util.collections.Jsonya;
+
+import com.google.common.annotations.Beta;
import com.google.common.collect.Iterables;
public class Yamls {
@@ -71,6 +74,7 @@ public class Yamls {
*
* @see #getAt(Object, List)
*/
+ @Beta
public static Object getAt(String yaml, List<String> path) {
Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
Object current = result.iterator().next();
@@ -85,8 +89,11 @@ public class Yamls {
* <li>A string in the form like "[0]" is assumed to be an index into a list
* </ul>
*
- * Returns {@code null} if that path does not exist.
+ * Also see {@link Jsonya}, such as {@code Jsonya.of(current).at(path).get()}.
+ *
+ * @return The object at the given path, or {@code null} if that path does not exist.
*/
+ @Beta
@SuppressWarnings("unchecked")
public static Object getAtPreParsed(Object current, List<String> path) {
for (String pathPart : path) {