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 2015/12/21 13:10:56 UTC
[06/12] incubator-brooklyn git commit: type registry: adds validation,
best version support, aliases, tags
type registry: adds validation, best version support, aliases, tags
and a simple registry with lookup tests
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/420ea303
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/420ea303
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/420ea303
Branch: refs/heads/master
Commit: 420ea303498f56b38b59ef221f45bf02ddcf19f3
Parents: 1265796
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Nov 26 10:04:02 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:36:16 2015 +0000
----------------------------------------------------------------------
.../api/typereg/BrooklynTypeRegistry.java | 28 ++-
.../brooklyn/api/typereg/RegisteredType.java | 8 +-
.../core/catalog/internal/CatalogUtils.java | 10 +-
.../typereg/AbstractTypePlanTransformer.java | 2 +-
.../core/typereg/BasicBrooklynTypeRegistry.java | 115 ++++++++++--
.../core/typereg/BasicRegisteredType.java | 34 +++-
.../core/typereg/RegisteredTypePredicates.java | 89 ++++++++-
.../brooklyn/core/typereg/RegisteredTypes.java | 137 ++++++++++----
.../internal/CatalogItemComparatorTest.java | 12 +-
.../typereg/BasicBrooklynTypeRegistryTest.java | 186 +++++++++++++++++++
.../typereg/RegisteredTypePredicatesTest.java | 19 +-
.../BrooklynEntityDecorationResolver.java | 2 +-
.../brooklyn/test/lite/CampYamlLiteTest.java | 2 +-
.../rest/resources/CatalogResource.java | 2 +-
.../util/collections/CollectionFunctionals.java | 23 ++-
.../collections/CollectionFunctionalsTest.java | 24 +++
16 files changed, 585 insertions(+), 108 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
index 78c49d8..eb59d27 100644
--- a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
@@ -23,7 +23,9 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.util.guava.Maybe;
+import com.google.common.annotations.Beta;
import com.google.common.base.Predicate;
@@ -48,23 +50,29 @@ public interface BrooklynTypeRegistry {
* taking the best version if the version is null or a default marker,
* returning null if no matches are found. */
RegisteredType get(String symbolicName, String version);
- /** as {@link #get(String, String)} but allows <code>"name:version"</code>
- * (the {@link RegisteredType#getId()}) in addition to the unversioned name,
- * using a default marker if no version can be inferred */
+ /** as {@link #get(String, String)} but the given string here
+ * is allowed to match any of:
+ * <li>the given string as an ID including version (<code>"name:version"</code>)
+ * <li>the symbolic name unversioned, or
+ * <li>an alias */
RegisteredType get(String symbolicNameWithOptionalVersion);
-
- // TODO remove
-// /** as {@link #get(String, String)}, but applying the optionally supplied {@link RegisteredTypeLoadingContext} */
-// RegisteredType get(String symbolicName, String version, @Nullable RegisteredTypeLoadingContext context);
-// /** as {@link #get(String)}, but applying the optionally supplied {@link RegisteredTypeLoadingContext} */
-// RegisteredType get(String symbolicNameWithOptionalVersion, @Nullable RegisteredTypeLoadingContext context);
+
+ /** as {@link #get(String)} but further filtering for the additional context */
+ public RegisteredType get(String symbolicNameOrAliasWithOptionalVersion, RegisteredTypeLoadingContext context);
+ /** returns a wrapper of the result of {@link #get(String, RegisteredTypeLoadingContext)}
+ * including a detailed message if absent */
+ public Maybe<RegisteredType> getMaybe(String symbolicNameOrAliasWithOptionalVersion, RegisteredTypeLoadingContext context);
// NB the seemingly more correct generics <T,SpecT extends AbstractBrooklynObjectSpec<T,SpecT>>
// cause compile errors, not in Eclipse, but in maven (?)
- // TODO do these belong here, or in a separate master TypePlanTransformer ? see also BrooklynTypePlanTransformer
+ // TODO do these belong here, or in a separate master TypePlanTransformer ? see also BrooklynTypePlanTransformer
+ @Beta
<SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<SpecT> optionalSpecSuperType);
+ @Beta
<SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpecFromPlan(@Nullable String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<SpecT> optionalSpecSuperType);
+ @Beta
<T> T createBean(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<T> optionalResultSuperType);
+ @Beta
<T> T createBeanFromPlan(String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalConstraint, @Nullable Class<T> optionalBeanSuperType);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
index 2674736..29b64d3 100644
--- a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
@@ -21,8 +21,6 @@ package org.apache.brooklyn.api.typereg;
import java.util.Collection;
import java.util.Set;
-import javax.annotation.Nullable;
-
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.objs.BrooklynObject;
@@ -75,6 +73,12 @@ public interface RegisteredType extends Identifiable {
*/
boolean isDisabled();
+ /** Alias words defined for this type */
+ Set<String> getAliases();
+
+ /** Tags attached to this item */
+ Set<Object> getTags();
+
/** @return implementation details, so that the framework can find a suitable {@link BrooklynTypePlanTransformer}
* which can then use this object to instantiate this type */
TypeImplementationPlan getPlan();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index ef455c6..078e1d7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl.RebindTracker;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts;
+import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.text.Strings;
@@ -85,7 +86,7 @@ public class CatalogUtils {
ManagementContext mgmt = ((EntityInternal)entity).getManagementContext();
String catId = entity.getCatalogItemId();
if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt);
- RegisteredType cat = RegisteredTypes.validate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class));
+ RegisteredType cat = RegisteredTypes.validate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
if (cat==null) {
log.warn("Cannot load "+catId+" to get classloader for "+entity+"; will try with standard loader, but might fail subsequently");
return JavaBrooklynClassLoadingContext.create(mgmt);
@@ -267,9 +268,10 @@ public class CatalogUtils {
}
public static boolean isBestVersion(ManagementContext mgmt, CatalogItem<?,?> item) {
- RegisteredType bestVersion = mgmt.getTypeRegistry().get(item.getSymbolicName(), BrooklynCatalog.DEFAULT_VERSION);
- if (bestVersion==null) return false;
- return (bestVersion.getVersion().equals(item.getVersion()));
+ RegisteredType best = RegisteredTypes.getBestVersion(mgmt.getTypeRegistry().getAll(
+ RegisteredTypePredicates.symbolicName(item.getSymbolicName())));
+ if (best==null) return false;
+ return (best.getVersion().equals(item.getVersion()));
}
/** @deprecated since 0.9.0 use {@link BrooklynTypeRegistry#get(String, org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind, Class)} */
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
index ee49d39..283b7da 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
@@ -128,7 +128,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext constraint) {
if (createdObject==null) return null;
try {
- return RegisteredTypes.validate(createdObject, type, constraint);
+ return RegisteredTypes.validate(createdObject, type, constraint).get();
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
throw new IllegalStateException("Created incompatible object: "+Exceptions.collapseText(e), e);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index b36be34..a642861 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -18,6 +18,7 @@
*/
package org.apache.brooklyn.core.typereg;
+import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -34,7 +35,8 @@ import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
@@ -43,16 +45,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.api.client.util.Preconditions;
+import com.google.common.annotations.Beta;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
- @SuppressWarnings("unused")
private static final Logger log = LoggerFactory.getLogger(BasicBrooklynTypeRegistry.class);
private ManagementContext mgmt;
+ private Map<String,RegisteredType> localRegisteredTypes = MutableMap.of();
public BasicBrooklynTypeRegistry(ManagementContext mgmt) {
this.mgmt = mgmt;
@@ -62,40 +65,95 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
return getAll(Predicates.alwaysTrue());
}
+ private Iterable<RegisteredType> getAllWithoutCatalog(Predicate<? super RegisteredType> filter) {
+ // TODO thread safety
+ // TODO optimisation? make indexes and look up?
+ return Iterables.filter(localRegisteredTypes.values(), filter);
+ }
+
+ private RegisteredType getExactWithoutLegacyCatalog(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
+ // TODO look in any nested/private registries
+ RegisteredType item = localRegisteredTypes.get(symbolicName+":"+version);
+ return RegisteredTypes.validate(item, constraint).orNull();
+ }
+
@SuppressWarnings("deprecation")
@Override
public Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> filter) {
- return Iterables.filter(Iterables.transform(mgmt.getCatalog().getCatalogItems(), RegisteredTypes.CI_TO_RT), filter);
+ return Iterables.filter(Iterables.concat(
+ getAllWithoutCatalog(filter),
+ Iterables.transform(mgmt.getCatalog().getCatalogItems(), RegisteredTypes.CI_TO_RT)),
+ filter);
}
@SuppressWarnings("deprecation")
- private RegisteredType get(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
- // probably constraint is not useful?
- if (constraint==null) constraint = RegisteredTypeLoadingContexts.any();
+ private Maybe<RegisteredType> getSingle(String symbolicNameOrAliasIfNoVersion, final String versionFinal, final RegisteredTypeLoadingContext contextFinal) {
+ RegisteredTypeLoadingContext context = contextFinal;
+ if (context==null) context = RegisteredTypeLoadingContexts.any();
+ String version = versionFinal;
if (version==null) version = BrooklynCatalog.DEFAULT_VERSION;
+
+ RegisteredType type;
+ if (!BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
+ type = getExactWithoutLegacyCatalog(symbolicNameOrAliasIfNoVersion, version, context);
+ if (type!=null) return Maybe.of(type);
+ }
- // TODO lookup here, using constraints
+ if (BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
+ Iterable<RegisteredType> types = getAll(Predicates.and(RegisteredTypePredicates.symbolicName(symbolicNameOrAliasIfNoVersion),
+ RegisteredTypePredicates.satisfies(context)));
+ if (Iterables.isEmpty(types)) {
+ // look for alias if no exact symbolic name match AND no version is specified
+ types = getAll(Predicates.and(RegisteredTypePredicates.alias(symbolicNameOrAliasIfNoVersion),
+ RegisteredTypePredicates.satisfies(context) ) );
+ // if there are multiple symbolic names then throw?
+ Set<String> uniqueSymbolicNames = MutableSet.of();
+ for (RegisteredType t: types) {
+ uniqueSymbolicNames.add(t.getSymbolicName());
+ }
+ if (uniqueSymbolicNames.size()>1) {
+ log.warn("Multiple matches found for alias '"+symbolicNameOrAliasIfNoVersion+"': "+uniqueSymbolicNames+"; "
+ + "picking highest version across different symbolic names. Use symbolic_name:version syntax to prevent this lookup.");
+ }
+ }
+ if (!Iterables.isEmpty(types)) {
+ type = RegisteredTypes.getBestVersion(types);
+ if (type!=null) return Maybe.of(type);
+ }
+ }
// fallback to catalog
- CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicName, version);
- // TODO apply constraint
- return RegisteredTypes.CI_TO_RT.apply( item );
+ CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicNameOrAliasIfNoVersion, version);
+ if (item!=null)
+ return Maybe.of( RegisteredTypes.CI_TO_RT.apply( item ) );
+
+ return Maybe.absent("No matches for "+symbolicNameOrAliasIfNoVersion+
+ (versionFinal!=null ? ":"+versionFinal : "")+
+ (contextFinal!=null ? " ("+contextFinal+")" : "") );
}
@Override
public RegisteredType get(String symbolicName, String version) {
- return get(symbolicName, version, null);
+ return getSingle(symbolicName, version, null).orNull();
}
- private RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext constraint) {
- // probably constraint is not useful?
+ @Override
+ public RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext context) {
+ return getMaybe(symbolicNameWithOptionalVersion, context).orNull();
+ }
+ @Override
+ public Maybe<RegisteredType> getMaybe(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext context) {
+ Maybe<RegisteredType> r1 = null;
if (CatalogUtils.looksLikeVersionedId(symbolicNameWithOptionalVersion)) {
String symbolicName = CatalogUtils.getSymbolicNameFromVersionedId(symbolicNameWithOptionalVersion);
String version = CatalogUtils.getVersionFromVersionedId(symbolicNameWithOptionalVersion);
- return get(symbolicName, version, constraint);
- } else {
- return get(symbolicNameWithOptionalVersion, BrooklynCatalog.DEFAULT_VERSION, constraint);
+ r1 = getSingle(symbolicName, version, context);
+ if (r1.isPresent()) return r1;
}
+
+ Maybe<RegisteredType> r2 = getSingle(symbolicNameWithOptionalVersion, BrooklynCatalog.DEFAULT_VERSION, context);
+ if (r2.isPresent() || r1==null) return r2;
+ return r1;
}
@Override
@@ -191,7 +249,8 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
}
if (constraint.getAlreadyEncounteredTypes().contains(type.getSymbolicName())) {
// avoid recursive cycle
- // TODO implement using java if permitted
+ // TODO create type using java if permitted?
+ // OR remove this creator from those permitted
}
}
constraint = RegisteredTypeLoadingContexts.withBeanSuperType(constraint, optionalResultSuperType);
@@ -207,4 +266,26 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
optionalConstraint, optionalBeanSuperType);
}
+ @Beta // API is stabilising
+ public void addToLocalUnpersistedTypeRegistry(RegisteredType type, boolean canForce) {
+ Preconditions.checkNotNull(type);
+ Preconditions.checkNotNull(type.getSymbolicName());
+ Preconditions.checkNotNull(type.getVersion());
+ Preconditions.checkNotNull(type.getId());
+ if (!type.getId().equals(type.getSymbolicName()+":"+type.getVersion()))
+ Asserts.fail("Registered type "+type+" has ID / symname mismatch");
+
+ RegisteredType oldType = localRegisteredTypes.get(type.getId());
+ if (oldType==null || canForce) {
+ log.debug("Inserting "+type+" into "+this);
+ localRegisteredTypes.put(type.getId(), type);
+ } else {
+ if (oldType == type) {
+ // ignore if same instance
+ // (equals not yet implemented, so would be the same, but misleading)
+ return;
+ }
+ throw new IllegalStateException("Cannot add "+type+" to catalog; different "+oldType+" is already present");
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
index 3905d65..05f0773 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
@@ -36,17 +36,20 @@ import com.google.common.collect.ImmutableSet;
/** Instances are usually created by methods in {@link RegisteredTypes}. */
public class BasicRegisteredType implements RegisteredType {
+ final RegisteredTypeKind kind;
final String symbolicName;
final String version;
- final RegisteredTypeKind kind;
- Set<Object> superTypes = MutableSet.of();
- List<OsgiBundleWithUrl> bundles = MutableList.of();
+ final List<OsgiBundleWithUrl> bundles = MutableList.of();
String displayName;
String description;
String iconUrl;
+
+ final Set<Object> superTypes = MutableSet.of();
boolean deprecated;
boolean disabled;
+ final Set<String> aliases = MutableSet.of();
+ final Set<Object> tags = MutableSet.of();
TypeImplementationPlan implementationPlan;
@@ -63,6 +66,11 @@ public class BasicRegisteredType implements RegisteredType {
public String getId() {
return symbolicName + (version!=null ? ":"+version : "");
}
+
+ @Override
+ public RegisteredTypeKind getKind() {
+ return kind;
+ }
@Override
public String getSymbolicName() {
@@ -73,11 +81,6 @@ public class BasicRegisteredType implements RegisteredType {
public String getVersion() {
return version;
}
-
- @Override
- public RegisteredTypeKind getKind() {
- return kind;
- }
@Override
public Collection<OsgiBundleWithUrl> getLibraries() {
@@ -100,6 +103,11 @@ public class BasicRegisteredType implements RegisteredType {
}
@Override
+ public Set<Object> getSuperTypes() {
+ return ImmutableSet.copyOf(superTypes);
+ }
+
+ @Override
public boolean isDisabled() {
return disabled;
}
@@ -110,10 +118,16 @@ public class BasicRegisteredType implements RegisteredType {
}
@Override
- public Set<Object> getSuperTypes() {
- return ImmutableSet.copyOf(superTypes);
+ public Set<String> getAliases() {
+ return ImmutableSet.copyOf(aliases);
+ }
+
+ @Override
+ public Set<Object> getTags() {
+ return ImmutableSet.copyOf(tags);
}
+
@Beta // TODO depending how useful this is, it might be better to replace by a static WeakHashMap in RegisteredTypes
public ConfigBag getCache() {
return cache;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
index ebeccd7..bf6fb6f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
@@ -20,14 +20,15 @@ package org.apache.brooklyn.core.typereg;
import javax.annotation.Nullable;
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -93,6 +94,9 @@ public class RegisteredTypePredicates {
}
}
+ public static Predicate<RegisteredType> symbolicName(final String name) {
+ return symbolicName(Predicates.equalTo(name));
+ }
public static Predicate<RegisteredType> symbolicName(final Predicate<? super String> filter) {
return new SymbolicNameMatches(filter);
}
@@ -109,6 +113,63 @@ public class RegisteredTypePredicates {
}
}
+ public static Predicate<RegisteredType> version(final String name) {
+ return version(Predicates.equalTo(name));
+ }
+ public static Predicate<RegisteredType> version(final Predicate<? super String> filter) {
+ return new versionMatches(filter);
+ }
+
+ private static class versionMatches implements Predicate<RegisteredType> {
+ private final Predicate<? super String> filter;
+
+ public versionMatches(Predicate<? super String> filter) {
+ this.filter = filter;
+ }
+ @Override
+ public boolean apply(@Nullable RegisteredType item) {
+ return (item != null) && filter.apply(item.getVersion());
+ }
+ }
+
+ public static Predicate<RegisteredType> alias(final String alias) {
+ return aliases(CollectionFunctionals.any(Predicates.equalTo(alias)));
+ }
+ public static Predicate<RegisteredType> aliases(final Predicate<Iterable<String>> filter) {
+ return new AliasesMatch(filter);
+ }
+
+ private static class AliasesMatch implements Predicate<RegisteredType> {
+ private final Predicate<Iterable<String>> filter;
+
+ public AliasesMatch(Predicate<Iterable<String>> filter) {
+ this.filter = filter;
+ }
+ @Override
+ public boolean apply(@Nullable RegisteredType item) {
+ return (item != null) && filter.apply(item.getAliases());
+ }
+ }
+
+ public static Predicate<RegisteredType> tag(final Object tag) {
+ return tags(CollectionFunctionals.any(Predicates.equalTo(tag)));
+ }
+ public static Predicate<RegisteredType> tags(final Predicate<Iterable<Object>> filter) {
+ return new TagsMatch(filter);
+ }
+
+ private static class TagsMatch implements Predicate<RegisteredType> {
+ private final Predicate<Iterable<Object>> filter;
+
+ public TagsMatch(Predicate<Iterable<Object>> filter) {
+ this.filter = filter;
+ }
+ @Override
+ public boolean apply(@Nullable RegisteredType item) {
+ return (item != null) && filter.apply(item.getTags());
+ }
+ }
+
public static <T> Predicate<RegisteredType> anySuperType(final Predicate<Class<T>> filter) {
return new AnySuperTypeMatches(filter);
}
@@ -158,7 +219,6 @@ public class RegisteredTypePredicates {
public static Predicate<RegisteredType> isBestVersion(final ManagementContext mgmt) {
return new IsBestVersion(mgmt);
}
-
private static class IsBestVersion implements Predicate<RegisteredType> {
private final ManagementContext mgmt;
@@ -170,11 +230,28 @@ public class RegisteredTypePredicates {
return isBestVersion(mgmt, item);
}
}
-
public static boolean isBestVersion(ManagementContext mgmt, RegisteredType item) {
- RegisteredType bestVersion = mgmt.getTypeRegistry().get(item.getSymbolicName(), BrooklynCatalog.DEFAULT_VERSION);
- if (bestVersion==null) return false;
- return (bestVersion.getVersion().equals(item.getVersion()));
+ if (item==null) return false;
+ Iterable<RegisteredType> matches = mgmt.getTypeRegistry().getAll(
+ RegisteredTypePredicates.symbolicName(item.getSymbolicName()) );
+ if (!matches.iterator().hasNext()) return false;
+ RegisteredType best = RegisteredTypes.getBestVersion(matches);
+ return (best.getVersion().equals(item.getVersion()));
+ }
+
+ public static Predicate<RegisteredType> satisfies(RegisteredTypeLoadingContext context) {
+ return new SatisfiesContext(context);
+ }
+ private static class SatisfiesContext implements Predicate<RegisteredType> {
+ private final RegisteredTypeLoadingContext context;
+
+ public SatisfiesContext(RegisteredTypeLoadingContext context) {
+ this.context = context;
+ }
+ @Override
+ public boolean apply(@Nullable RegisteredType item) {
+ return RegisteredTypes.validate(item, context).isPresent();
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index 18f8f43..3a89e60 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -19,6 +19,8 @@
package org.apache.brooklyn.core.typereg;
import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -30,7 +32,6 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
-import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.api.typereg.RegisteredType.TypeImplementationPlan;
import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
@@ -39,15 +40,18 @@ import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer.JavaClassNameTypeImplementationPlan;
+import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.NaturalOrderComparator;
+import org.apache.brooklyn.util.text.VersionComparator;
import org.apache.brooklyn.util.yaml.Yamls;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ComparisonChain;
import com.google.common.reflect.TypeToken;
/**
@@ -88,16 +92,18 @@ public class RegisteredTypes {
}
BasicRegisteredType type = (BasicRegisteredType) spec(item.getSymbolicName(), item.getVersion(), impl, item.getCatalogItemJavaType());
- type.bundles = item.getLibraries()==null ? ImmutableList.<OsgiBundleWithUrl>of() : ImmutableList.<OsgiBundleWithUrl>copyOf(item.getLibraries());
type.displayName = item.getDisplayName();
type.description = item.getDescription();
type.iconUrl = item.getIconUrl();
+
+ if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
type.disabled = item.isDisabled();
type.deprecated = item.isDeprecated();
+ if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
+ // aliases aren't on item
+ if (item.tags()!=null) type.tags.addAll(item.tags().getTags());
- // TODO
- // probably not: javaType, specType, registeredTypeName ...
- // maybe: tags ?
+ // these things from item we ignore: javaType, specType, registeredTypeName ...
return type;
}
@@ -135,7 +141,6 @@ public class RegisteredTypes {
}
return type;
}
-
@Beta
public static RegisteredType addSuperType(RegisteredType type, @Nullable RegisteredType superType) {
if (superType!=null) {
@@ -146,6 +151,53 @@ public class RegisteredTypes {
}
return type;
}
+ @Beta
+ public static RegisteredType addSuperTypes(RegisteredType type, Iterable<Object> superTypesAsClassOrRegisteredType) {
+ if (superTypesAsClassOrRegisteredType!=null) {
+ for (Object superType: superTypesAsClassOrRegisteredType) {
+ if (superType==null) {
+ // nothing
+ } else if (superType instanceof Class) {
+ addSuperType(type, (Class<?>)superType);
+ } else if (superType instanceof RegisteredType) {
+ addSuperType(type, (RegisteredType)superType);
+ } else {
+ throw new IllegalStateException(superType+" supplied as a supertype of "+type+" but it is not a supported supertype");
+ }
+ }
+ }
+ return type;
+ }
+
+ @Beta
+ public static RegisteredType addAlias(RegisteredType type, String alias) {
+ if (alias!=null) {
+ ((BasicRegisteredType)type).aliases.add( alias );
+ }
+ return type;
+ }
+ @Beta
+ public static RegisteredType addAliases(RegisteredType type, Iterable<String> aliases) {
+ if (aliases!=null) {
+ for (String alias: aliases) addAlias(type, alias);
+ }
+ return type;
+ }
+
+ @Beta
+ public static RegisteredType addTag(RegisteredType type, Object tag) {
+ if (tag!=null) {
+ ((BasicRegisteredType)type).tags.add( tag );
+ }
+ return type;
+ }
+ @Beta
+ public static RegisteredType addTags(RegisteredType type, Iterable<?> tags) {
+ if (tags!=null) {
+ for (Object tag: tags) addTag(type, tag);
+ }
+ return type;
+ }
/** returns the implementation data for a spec if it is a string (e.g. plan yaml or java class name); else throws */
@Beta
@@ -232,16 +284,16 @@ public class RegisteredTypes {
return false;
}
- public static RegisteredType validate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
- if (item==null || constraint==null) return item;
+ public static Maybe<RegisteredType> validate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
+ if (item==null || constraint==null) return Maybe.of(item);
if (constraint.getExpectedKind()!=null && !constraint.getExpectedKind().equals(item.getKind()))
- throw new IllegalStateException(item+" is not the expected kind "+constraint.getExpectedKind());
+ return Maybe.absent(item+" is not the expected kind "+constraint.getExpectedKind());
if (constraint.getExpectedJavaSuperType()!=null) {
if (!isSubtypeOf(item, constraint.getExpectedJavaSuperType())) {
- throw new IllegalStateException(item+" is not for the expected type "+constraint.getExpectedJavaSuperType());
+ return Maybe.absent(item+" is not for the expected type "+constraint.getExpectedJavaSuperType());
}
}
- return item;
+ return Maybe.of(item);
}
/**
@@ -258,68 +310,87 @@ public class RegisteredTypes {
return true;
}
- public static <T> T validate(final T object, final RegisteredType type, final RegisteredTypeLoadingContext constraint) {
+ public static RegisteredType getBestVersion(Iterable<RegisteredType> types) {
+ if (types==null || !types.iterator().hasNext()) return null;
+ return Collections.max(MutableList.copyOf(types), RegisteredTypeComparator.INSTANCE);
+ }
+
+ public static class RegisteredTypeComparator implements Comparator<RegisteredType> {
+ public static Comparator<RegisteredType> INSTANCE = new RegisteredTypeComparator();
+ private RegisteredTypeComparator() {}
+ @Override
+ public int compare(RegisteredType o1, RegisteredType o2) {
+ return ComparisonChain.start()
+ .compareTrueFirst(o1.isDisabled(), o2.isDisabled())
+ .compareTrueFirst(o1.isDeprecated(), o2.isDeprecated())
+ .compare(o1.getSymbolicName(), o2.getSymbolicName(), NaturalOrderComparator.INSTANCE)
+ .compare(o1.getVersion(), o2.getVersion(), VersionComparator.INSTANCE)
+ .result();
+ }
+ }
+
+ public static <T> Maybe<T> validate(final T object, final RegisteredType type, final RegisteredTypeLoadingContext constraint) {
RegisteredTypeKind kind = type!=null ? type.getKind() : constraint!=null ? constraint.getExpectedKind() : null;
if (kind==null) {
if (object instanceof AbstractBrooklynObjectSpec) kind=RegisteredTypeKind.SPEC;
else kind=RegisteredTypeKind.BEAN;
}
- return new RegisteredTypeKindVisitor<T>() {
+ return new RegisteredTypeKindVisitor<Maybe<T>>() {
@Override
- protected T visitSpec() {
+ protected Maybe<T> visitSpec() {
return validateSpec(object, type, constraint);
}
@Override
- protected T visitBean() {
+ protected Maybe<T> visitBean() {
return validateBean(object, type, constraint);
}
}.visit(kind);
}
- private static <T> T validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext constraint) {
- if (object==null) return null;
+ private static <T> Maybe<T> validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext constraint) {
+ if (object==null) return Maybe.absent("object is null");
if (type!=null) {
if (type.getKind()!=RegisteredTypeKind.BEAN)
- throw new IllegalStateException("Validating a bean when type is "+type.getKind()+" "+type);
+ return Maybe.absent("Validating a bean when type is "+type.getKind()+" "+type);
if (!isSubtypeOf(object.getClass(), type))
- throw new IllegalStateException(object+" does not have all the java supertypes of "+type);
+ return Maybe.absent(object+" does not have all the java supertypes of "+type);
}
if (constraint!=null) {
if (constraint.getExpectedKind()!=RegisteredTypeKind.BEAN)
- throw new IllegalStateException("Validating a bean when constraint expected "+constraint.getExpectedKind());
+ return Maybe.absent("Validating a bean when constraint expected "+constraint.getExpectedKind());
if (constraint.getExpectedJavaSuperType()!=null && !constraint.getExpectedJavaSuperType().isInstance(object))
- throw new IllegalStateException(object+" is not of the expected java supertype "+constraint.getExpectedJavaSuperType());
+ return Maybe.absent(object+" is not of the expected java supertype "+constraint.getExpectedJavaSuperType());
}
- return object;
+ return Maybe.of(object);
}
- private static <T> T validateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
- if (object==null) return null;
+ private static <T> Maybe<T> validateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
+ if (object==null) return Maybe.absent("object is null");
if (!(object instanceof AbstractBrooklynObjectSpec)) {
- throw new IllegalStateException("Found "+object+" when expecting a spec");
+ Maybe.absent("Found "+object+" when expecting a spec");
}
Class<?> targetType = ((AbstractBrooklynObjectSpec<?,?>)object).getType();
if (targetType==null) {
- throw new IllegalStateException("Spec "+object+" does not have a target type");
+ Maybe.absent("Spec "+object+" does not have a target type");
}
if (rType!=null) {
if (rType.getKind()!=RegisteredTypeKind.SPEC)
- throw new IllegalStateException("Validating a spec when type is "+rType.getKind()+" "+rType);
+ Maybe.absent("Validating a spec when type is "+rType.getKind()+" "+rType);
if (!isSubtypeOf(targetType, rType))
- throw new IllegalStateException(object+" does not have all the java supertypes of "+rType);
+ Maybe.absent(object+" does not have all the java supertypes of "+rType);
}
if (constraint!=null) {
if (constraint.getExpectedJavaSuperType()!=null) {
if (!constraint.getExpectedJavaSuperType().isAssignableFrom(targetType)) {
- throw new IllegalStateException(object+" does not target the expected java supertype "+constraint.getExpectedJavaSuperType());
+ Maybe.absent(object+" does not target the expected java supertype "+constraint.getExpectedJavaSuperType());
}
if (constraint.getExpectedJavaSuperType().isAssignableFrom(BrooklynObjectInternal.class)) {
// don't check spec type; any spec is acceptable
@@ -328,15 +399,15 @@ public class RegisteredTypes {
Class<? extends AbstractBrooklynObjectSpec<?, ?>> specType = RegisteredTypeLoadingContexts.lookupSpecTypeForTarget( (Class<? extends BrooklynObject>) constraint.getExpectedJavaSuperType());
if (specType==null) {
// means a problem in our classification of spec types!
- throw new IllegalStateException(object+" is returned as spec for unexpected java supertype "+constraint.getExpectedJavaSuperType());
+ Maybe.absent(object+" is returned as spec for unexpected java supertype "+constraint.getExpectedJavaSuperType());
}
if (!specType.isAssignableFrom(object.getClass())) {
- throw new IllegalStateException(object+" is not a spec of the expected java supertype "+constraint.getExpectedJavaSuperType());
+ Maybe.absent(object+" is not a spec of the expected java supertype "+constraint.getExpectedJavaSuperType());
}
}
}
}
- return object;
+ return Maybe.of(object);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
index e7d43cd..3c8ce83 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
@@ -21,22 +21,25 @@ package org.apache.brooklyn.core.catalog.internal;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
-import org.testng.annotations.Test;
import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
-import org.apache.brooklyn.core.catalog.internal.CatalogItemComparator;
+import org.testng.annotations.Test;
public class CatalogItemComparatorTest {
private static final String RC2 = "10.5.8-rc2";
private static final String STABLE = "10.5.8";
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testComparison() {
compare("0.0.1", "0.0.2", 1);
compare("0.0.2", "0.0.1", -1);
compare("0.0.1-qual", "0.0.2", 1);
compare("0.0.1.qual", "0.0.2", 1);
- compare("0.0.1-qual", "0.0.1_qual", 0);
+
+ // NB: semantics of this changed in 090-SNAPSHOT not to be 0 unless identical
+ // (remove when we're used to this)
+// compare("0.0.1-qual", "0.0.1_qual", 0);
+
compare("0.0.1.qual", "0.0.1.qual", 0);
compare("0.0.1", "0.0.2-SNAPSHOT", -1);
compare("0.0.1", "0.0.2.SNAPSHOT", -1);
@@ -70,6 +73,7 @@ public class CatalogItemComparatorTest {
assertTrue(cmp.compare(v(RC2), v("10.5.8-beta1")) == cmp.compare(v(RC2), v("10.5.8-beta3")));
}
+ @SuppressWarnings({ "unchecked", "rawtypes" })
private void compare(String v1, String v2, int expected) {
CatalogItemComparator cmp = CatalogItemComparator.INSTANCE;
assertEquals(cmp.compare(v(v1), v(v2)), expected);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
new file mode 100644
index 0000000..a62ab7e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.typereg;
+
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
+
+ private BasicBrooklynTypeRegistry registry() {
+ return (BasicBrooklynTypeRegistry) mgmt.getTypeRegistry();
+ }
+
+ private void add(RegisteredType type) {
+ add(type, false);
+ }
+ private void add(RegisteredType type, boolean canForce) {
+ registry().addToLocalUnpersistedTypeRegistry(type, canForce);
+ }
+
+ private final static RegisteredType SAMPLE_TYPE = RegisteredTypes.bean("item.A", "1", new BasicTypeImplementationPlan("ignore", null), String.class);
+ private final static RegisteredType SAMPLE_TYPE2 = RegisteredTypes.bean("item.A", "2", new BasicTypeImplementationPlan("ignore", null), String.class);
+
+ @Test
+ public void testAddAndGet() {
+ Assert.assertFalse( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+ Assert.assertNull( registry().get(SAMPLE_TYPE.getSymbolicName(), SAMPLE_TYPE.getVersion()) );
+ Assert.assertNull( registry().get(SAMPLE_TYPE.getId()) );
+ add(SAMPLE_TYPE);
+
+ Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName(), SAMPLE_TYPE.getVersion()), SAMPLE_TYPE );
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+
+ Assert.assertTrue( Iterables.contains(registry().getAll(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName())), SAMPLE_TYPE) );
+ }
+
+ @Test
+ public void testCantAddSameIdUnlessSameInstanceOrForced() {
+ add(SAMPLE_TYPE);
+ RegisteredType sampleTypeClone = RegisteredTypes.bean("item.A", "1", new BasicTypeImplementationPlan("ignore", null), String.class);
+ add(sampleTypeClone, true);
+ Assert.assertNotEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+
+ add(SAMPLE_TYPE, true);
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+
+ try {
+ add(sampleTypeClone);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (Exception e) {
+ Asserts.expectedFailureContains(e, SAMPLE_TYPE.getSymbolicName());
+ }
+
+ // only one entry
+ Assert.assertEquals( Iterables.size(registry().getAll(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 1);
+ // unversioned request returns sample
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName()), SAMPLE_TYPE );
+ }
+
+ @Test
+ public void testGettingBestVersion() {
+ add(SAMPLE_TYPE);
+ add(SAMPLE_TYPE2);
+
+ Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+ Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE2) );
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+ Assert.assertEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE2 );
+ Assert.assertNotEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE );
+
+ Assert.assertEquals( Iterables.size(registry().getAll(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 2);
+
+ // unversioned request returns latest
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName()), SAMPLE_TYPE2 );
+ }
+
+ @Test
+ public void testGetWithFilter() {
+ add(SAMPLE_TYPE);
+
+ Assert.assertEquals( Iterables.size(registry().getAll(Predicates.and(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
+ RegisteredTypePredicates.subtypeOf(String.class)
+ ))), 1 );
+ Assert.assertTrue( Iterables.isEmpty(registry().getAll(Predicates.and(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
+ RegisteredTypePredicates.subtypeOf(Integer.class)
+ ))) );
+ }
+
+ @Test
+ public void testGetWithContext() {
+ add(SAMPLE_TYPE);
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getId(),
+ RegisteredTypeLoadingContexts.bean(String.class)), SAMPLE_TYPE );
+ Assert.assertEquals( registry().get(SAMPLE_TYPE.getId(),
+ RegisteredTypeLoadingContexts.bean(Integer.class)), null );
+ }
+
+ @Test
+ public void testAlias() {
+ add(SAMPLE_TYPE);
+ add(SAMPLE_TYPE2);
+
+ RegisteredType sampleType15WithAliases = RegisteredTypes.addAliases(
+ RegisteredTypes.bean("item.A", "1.1", new BasicTypeImplementationPlan("ignore", null), String.class),
+ MutableList.of("my_a", "the_a"));
+ add(sampleType15WithAliases);
+ Assert.assertEquals(sampleType15WithAliases.getAliases(), MutableSet.of("my_a", "the_a"));
+
+ Assert.assertEquals( Iterables.size(registry().getAll(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
+
+ Assert.assertEquals( registry().get("my_a"), sampleType15WithAliases );
+ Assert.assertEquals( registry().get("the_a"), sampleType15WithAliases );
+ Assert.assertEquals( registry().get(sampleType15WithAliases.getId()), sampleType15WithAliases );
+
+ // but unadorned type still returns v2
+ Assert.assertEquals( registry().get(sampleType15WithAliases.getSymbolicName()), SAMPLE_TYPE2 );
+
+ // and filters work
+ Assert.assertEquals( registry().getAll(RegisteredTypePredicates.alias("the_a")),
+ MutableList.of(sampleType15WithAliases) );
+ Assert.assertEquals( registry().get("my_a",
+ RegisteredTypeLoadingContexts.bean(String.class)), sampleType15WithAliases );
+ Assert.assertEquals( registry().get("my_a",
+ RegisteredTypeLoadingContexts.bean(Integer.class)), null );
+ }
+
+ @Test
+ public void testTags() {
+ add(SAMPLE_TYPE);
+ add(SAMPLE_TYPE2);
+
+ RegisteredType sampleType15WithTags = RegisteredTypes.addTags(
+ RegisteredTypes.bean("item.A", "1.1", new BasicTypeImplementationPlan("ignore", null), String.class),
+ MutableList.of("my_a", "the_a"));
+ add(sampleType15WithTags);
+ Assert.assertEquals(sampleType15WithTags.getTags(), MutableSet.of("my_a", "the_a"));
+
+ Assert.assertEquals( Iterables.size(registry().getAll(
+ RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
+
+ Assert.assertEquals( registry().get(sampleType15WithTags.getId()), sampleType15WithTags );
+
+ // and filters work
+ Assert.assertEquals( registry().getAll(RegisteredTypePredicates.tag("the_a")),
+ MutableList.of(sampleType15WithTags) );
+
+ // but can't lookup by tag as a get
+ Assert.assertEquals( registry().get("my_a"), null );
+
+ // and unadorned type still returns v2
+ Assert.assertEquals( registry().get(sampleType15WithTags.getSymbolicName()), SAMPLE_TYPE2 );
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
index 145c056..9523946 100644
--- a/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
@@ -24,28 +24,13 @@ import static org.testng.Assert.assertTrue;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
import org.testng.annotations.Test;
import com.google.common.base.Predicates;
-public class RegisteredTypePredicatesTest {
- private LocalManagementContext mgmt;
-
- @BeforeMethod(alwaysRun = true)
- public void setUp() throws Exception {
- mgmt = LocalManagementContextForTests.newInstance();
- }
-
- @AfterMethod(alwaysRun = true)
- public void tearDown() throws Exception {
- if (mgmt != null) Entities.destroyAll(mgmt);
- }
+public class RegisteredTypePredicatesTest extends BrooklynMgmtUnitTestSupport {
@Test
public void testDisplayName() {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
index 0147b9d..acde8ec 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -115,7 +115,7 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
String policyType = decoLoader.getTypeName().get();
ManagementContext mgmt = instantiator.loader.getManagementContext();
- RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class));
+ RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class)).get();
PolicySpec<?> spec;
if (item!=null) {
spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
index d8e4b1d..57adfeb 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -230,7 +230,7 @@ public class CampYamlLiteTest {
}
private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {
- RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(symbolicName), RegisteredTypeLoadingContexts.spec(Entity.class));
+ RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(symbolicName), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " +
Joiner.on(",").join(mgmt.getTypeRegistry().getAll()));
assertEquals(item.getSymbolicName(), symbolicName);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index ecbeffb..03b05f9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -149,7 +149,7 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
Entitlements.getEntitlementContext().user());
}
try {
- RegisteredType item = RegisteredTypes.validate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class));
+ RegisteredType item = RegisteredTypes.validate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
if (item==null) {
throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java b/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
index aa6831b..91f53f9 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
@@ -205,15 +205,36 @@ public class CollectionFunctionals {
// ---------
+ /**
+ * Returns a predicate for a collection which is true if
+ * all elements in the collection given to the predicate
+ * which satisfies the predicate given here.
+ * <p>
+ * This will return true for the empty set.
+ * To require additionally that there is at least one
+ * use {@link #quorum(QuorumCheck, Predicate)} with
+ * {@link QuorumChecks#allAndAtLeastOne()}. */
public static <T,TT extends Iterable<T>> Predicate<TT> all(Predicate<T> attributeSatisfies) {
return quorum(QuorumChecks.all(), attributeSatisfies);
}
+ /** Returns a predicate for a collection which is true if
+ * there is at least one element in the collection given to the predicate
+ * which satisfies the predicate given here.
+ */
+ public static <T,TT extends Iterable<T>> Predicate<TT> any(Predicate<T> attributeSatisfies) {
+ // implementation could be more efficient -- ie succeed fast
+ return quorum(QuorumChecks.atLeastOne(), attributeSatisfies);
+ }
+
+ /** Returns a predicate for a collection which is true if
+ * the number of elements in the collection satisfying the predicate given here
+ * passes the {@link QuorumCheck} given here.
+ */
public static <T,TT extends Iterable<T>> Predicate<TT> quorum(QuorumCheck quorumCheck, Predicate<T> attributeSatisfies) {
return new QuorumSatisfies<T, TT>(quorumCheck, attributeSatisfies);
}
-
private static final class QuorumSatisfies<I,T extends Iterable<I>> implements Predicate<T> {
private final Predicate<I> itemCheck;
private final QuorumCheck quorumCheck;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
index 1d75297..1ce4015 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
@@ -22,6 +22,7 @@ import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.testng.Assert;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -55,4 +56,27 @@ public class CollectionFunctionalsTest {
Assert.assertEquals(CollectionFunctionals.firstElement().apply(ImmutableList.of("a")), "a");
Assert.assertEquals(CollectionFunctionals.firstElement().apply(ImmutableList.of("a", "b", "c")), "a");
}
+
+ @Test
+ public void testAllAndAny() {
+ Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+ MutableList.of(1, 1, 1)), true);
+ Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+ MutableList.<Integer>of()), true);
+ Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+ MutableList.of(1, 0, 1)), false);
+ Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+ MutableList.of(0, 0, 0)), false);
+
+ Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+ MutableList.of(1, 1, 1)), true);
+ Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+ MutableList.<Integer>of()), false);
+ Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+ MutableList.of(1, 0, 1)), true);
+ Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+ MutableList.of(0, 0, 0)), false);
+
+ }
+
}