brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject [2/3] brooklyn-server git commit: tweaks to background TypeRegistry and *ClassLoadingContext
Date Mon, 26 Sep 2016 16:11:57 GMT
tweaks to background TypeRegistry and *ClassLoadingContext


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

Branch: refs/heads/master
Commit: 4e76170993ff2330ac8a04e98b97b64ec307f295
Parents: f97b9eb
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Mon Sep 5 18:52:32 2016 +0100
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Wed Sep 7 15:58:59 2016 +0100

----------------------------------------------------------------------
 .../BrooklynClassLoadingContext.java            | 25 ++--------
 .../api/typereg/BrooklynTypeRegistry.java       | 13 +++++-
 .../core/typereg/BasicBrooklynTypeRegistry.java | 33 ++++++++++++--
 .../typereg/BrooklynTypePlanTransformer.java    | 11 +++--
 .../brooklyn/core/typereg/RegisteredTypes.java  | 17 ++++---
 .../java/org/apache/brooklyn/test/Asserts.java  | 27 ++++++++++-
 .../brooklyn/util/exceptions/Exceptions.java    | 10 ++++
 .../util/javalang/ClassLoadingContext.java      | 48 ++++++++++++++++++++
 8 files changed, 146 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java
b/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java
index f95c0d8..2441af5 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java
@@ -18,33 +18,14 @@
  */
 package org.apache.brooklyn.api.mgmt.classloading;
 
-import java.net.URL;
-
-import javax.annotation.Nullable;
-
 import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.javalang.ClassLoadingContext;
 
 /** 
- * Provides functionality for loading classes based on the current context
- * (e.g. the bundles of a registered type from which an entity is created)
+ * As {@link ClassLoadingContext} but the {@link ManagementContext} is also available.
  */
-public interface BrooklynClassLoadingContext {
+public interface BrooklynClassLoadingContext extends ClassLoadingContext {
 
     public ManagementContext getManagementContext();
-    public Class<?> loadClass(String className);
-    public <T> Class<? extends T> loadClass(String className, @Nullable Class<T>
supertype);
-
-    public Maybe<Class<?>> tryLoadClass(String className);
-    public <T> Maybe<Class<? extends T>> tryLoadClass(String className,
@Nullable Class<T> supertype);
-
-    /** As {@link ClassLoader#getResource(String)} */
-    public URL getResource(String name);
-
-    /**
-     * As {@link ClassLoader#getResources(String)} but returning an {@link Iterable} rather
than
-     * an {@link java.util.Enumeration}.
-     */
-    public Iterable<URL> getResources(String name);
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/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 17a7fb3..ae26ac1 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
@@ -63,16 +63,27 @@ public interface BrooklynTypeRegistry {
      * including a detailed message if absent */
     public Maybe<RegisteredType> getMaybe(String symbolicNameOrAliasWithOptionalVersion,
RegisteredTypeLoadingContext context);
 
+    /** Creates an instance of the given type, either a bean or spec as appropriate. */
+    @Beta
+    <T> T create(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext,
@Nullable Class<T> optionalResultSuperType);
+    /** Creates a bean or spec (depending on the super-type hint) for the given plan data
(e.g. a yaml string) for the given format (optional, will auto-detect if null) */
+    @Beta
+    <T> T createFromPlan(Class<T> requiredSuperTypeHint, @Nullable String planFormat,
Object planData, @Nullable RegisteredTypeLoadingContext optionalConstraint);
+
+    /** Typesafe {@link AbstractBrooklynObjectSpec} variant of {@link #create(RegisteredType,
RegisteredTypeLoadingContext, Class)} */
     // 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
     @Beta
     <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType
type, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<SpecT>
optionalSpecSuperType);
+    /** Typesafe {@link AbstractBrooklynObjectSpec} variant of {@link #createFromPlan(Class,
String, Object, RegisteredTypeLoadingContext)} */
     @Beta
     <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpecFromPlan(@Nullable
String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalContext,
@Nullable Class<SpecT> optionalSpecSuperType);
+    /** Typesafe non-spec variant of {@link #create(RegisteredType, RegisteredTypeLoadingContext,
Class)} */
     @Beta
     <T> T createBean(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext,
@Nullable Class<T> optionalResultSuperType);
     @Beta
+    /** Typesafe non-spec variant of {@link #createFromPlan(Class, String, Object, RegisteredTypeLoadingContext)}
*/
     <T> T createBeanFromPlan(String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext
optionalConstraint, @Nullable Class<T> optionalBeanSuperType);
-    
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/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 e28c7b2..c112779 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
@@ -247,8 +247,8 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry
{
     @Override
     public <T> T createBean(RegisteredType type, RegisteredTypeLoadingContext constraint,
Class<T> optionalResultSuperType) {
         Preconditions.checkNotNull(type, "type");
-        if (type.getKind()!=RegisteredTypeKind.SPEC) { 
-            throw new IllegalStateException("Cannot create spec from type "+type+" (kind
"+type.getKind()+")");
+        if (type.getKind()!=RegisteredTypeKind.BEAN) { 
+            throw new IllegalStateException("Cannot create bean from type "+type+" (kind
"+type.getKind()+")");
         }
         if (constraint!=null) {
             if (constraint.getExpectedKind()!=null && constraint.getExpectedKind()!=RegisteredTypeKind.SPEC)
{
@@ -268,9 +268,34 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry
{
     }
 
     @Override
-    public <T> T createBeanFromPlan(String planFormat, Object planData, RegisteredTypeLoadingContext
optionalConstraint, Class<T> optionalBeanSuperType) {
+    public <T> T createBeanFromPlan(String planFormat, Object planData, RegisteredTypeLoadingContext
optionalConstraint, Class<T> optionalSuperType) {
         return createBean(RegisteredTypes.bean(null, null, new BasicTypeImplementationPlan(planFormat,
planData), null),
-            optionalConstraint, optionalBeanSuperType);
+            optionalConstraint, optionalSuperType);
+    }
+    
+    @Override
+    public <T> T create(RegisteredType type, RegisteredTypeLoadingContext constraint,
Class<T> optionalResultSuperType) {
+        Preconditions.checkNotNull(type, "type");
+        if (type.getKind()==RegisteredTypeKind.BEAN) {
+            return createBean(type, constraint, optionalResultSuperType);
+        }
+        if (type.getKind()==RegisteredTypeKind.SPEC) {
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            T result = (T) createSpec(type, constraint, (Class)optionalResultSuperType);
+            return result;
+        }
+        throw new IllegalArgumentException("Kind-agnostic create method can only be used
when the registered type declares its kind, which "+type+" does not");
+    }
+
+    @Override
+    public <T> T createFromPlan(Class<T> requiredSuperTypeHint, String planFormat,
Object planData, RegisteredTypeLoadingContext optionalConstraint) {
+        if (AbstractBrooklynObjectSpec.class.isAssignableFrom(requiredSuperTypeHint)) {
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            T result = (T) createSpecFromPlan(planFormat, planData, optionalConstraint, (Class)requiredSuperTypeHint);
+            return result;
+        }
+        
+        return createBeanFromPlan(planFormat, planData, optionalConstraint, requiredSuperTypeHint);
     }
 
     @Beta // API is stabilising

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java
b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java
index 5609cf9..1001268 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java
@@ -55,7 +55,10 @@ public interface BrooklynTypePlanTransformer extends ManagementContextInjectable
     /** 
      * Determines how appropriate is this transformer for the {@link RegisteredType#getPlan()}
of the type.
      * The framework guarantees arguments are nonnull, and that the {@link RegisteredType#getPlan()}
is also not-null.
-     * However the format in that plan may be null. 
+     * However many fields on the {@link RegisteredType} may be null,
+     * including {@link RegisteredType#getId()} for an ad hoc creation
+     * (eg if invoked from {@link BrooklynTypeRegistry#createBeanFromPlan(String, Object,
RegisteredTypeLoadingContext, Class)})
+     *  
      * @return A co-ordinated score / confidence value in the range 0 to 1. 
      * 0 means not compatible, 
      * 1 means this is clearly the intended transformer and no others need be tried 
@@ -69,13 +72,13 @@ public interface BrooklynTypePlanTransformer extends ManagementContextInjectable
     /** Creates a new instance of the indicated type, or throws if not supported;
      * this method is used by the {@link BrooklynTypeRegistry} when it creates instances,
      * so implementations must respect the {@link RegisteredTypeKind} semantics and the {@link
RegisteredTypeLoadingContext}
-     * if they return an instance.
+     * (or return null / throw).
      * <p>
      * The framework guarantees this will only be invoked when {@link #scoreForType(RegisteredType,
RegisteredTypeLoadingContext)} 
-     * has returned a positive value.
+     * has returned a positive value, and the same constraints on the inputs as for that
method apply.
      * <p>
      * Implementations should either return null or throw {@link UnsupportedTypePlanException}

-     * if the {@link RegisteredType#getPlan()} is not supported. */
+     * if they cannot instantiate the given {@link RegisteredType#getPlan()}. */
     @Nullable Object create(@Nonnull RegisteredType type, @Nonnull RegisteredTypeLoadingContext
context);
 
     // TODO sketch methods for loading *catalog* definitions.  note some potential overlap

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/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 0c7b09b..72e05ea 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
@@ -118,20 +118,25 @@ public class RegisteredTypes {
         return addSuperType(new BasicRegisteredType(RegisteredTypeKind.SPEC, symbolicName,
version, plan), superType);
     }
 
-    /** returns the {@link Class} object corresponding to the given java type name,
-     * using the cache on the type and the loader defined on the type
-     * @param mgmt */
+    /** returns the {@link Class} object corresponding to the given java type name and registered
type,
+     * using the cache on the type in the first instance, falling back to the loader defined
the type and context. */
     @Beta
     // TODO should this be on the AbstractTypePlanTransformer ?
     public static Class<?> loadActualJavaType(String javaTypeName, ManagementContext
mgmt, RegisteredType type, RegisteredTypeLoadingContext context) {
-        Class<?> result = ((BasicRegisteredType)type).getCache().get(ACTUAL_JAVA_TYPE);
+        Class<?> result = peekActualJavaType(type);
         if (result!=null) return result;
         
         result = CatalogUtils.newClassLoadingContext(mgmt, type, context==null ? null : context.getLoader()).loadClass(
javaTypeName );
         
-        ((BasicRegisteredType)type).getCache().put(ACTUAL_JAVA_TYPE, result);
+        cacheActualJavaType(type, result);
         return result;
     }
+    @Beta public static Class<?> peekActualJavaType(RegisteredType type) {
+        return ((BasicRegisteredType)type).getCache().get(ACTUAL_JAVA_TYPE);
+    }
+    @Beta public static void cacheActualJavaType(RegisteredType type, Class<?> clazz)
{
+        ((BasicRegisteredType)type).getCache().put(ACTUAL_JAVA_TYPE, clazz);
+    }
 
     @Beta
     public static RegisteredType addSuperType(RegisteredType type, @Nullable Class<?>
superType) {
@@ -372,7 +377,7 @@ public class RegisteredTypes {
         }
 
         if (context!=null) {
-            if (context.getExpectedKind()!=RegisteredTypeKind.BEAN)
+            if (context.getExpectedKind()!=null && context.getExpectedKind()!=RegisteredTypeKind.BEAN)
                 return Maybe.absent("Validating a bean when constraint expected "+context.getExpectedKind());
             if (context.getExpectedJavaSuperType()!=null && !context.getExpectedJavaSuperType().isInstance(object))
                 return Maybe.absent(object+" is not of the expected java supertype "+context.getExpectedJavaSuperType());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
index 43dcaa1..23624d9 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
@@ -1113,6 +1113,18 @@ public class Asserts {
         }
     }
     
+    public static void assertStringDoesNotContain(String input, String phrase1ToNotContain,
String ...optionalOtherPhrasesToNotContain) {
+        if (input==null) fail("Input is null.");
+        if (phrase1ToNotContain!=null) {
+            assertThat(input, Predicates.not(StringPredicates.containsLiteral(phrase1ToNotContain)));
+        }
+        for (String otherPhrase: optionalOtherPhrasesToNotContain) {
+            if (otherPhrase!=null) {
+                assertThat(input, Predicates.not(StringPredicates.containsLiteral(otherPhrase)));
+            }
+        }
+    }
+    
     public static void assertStringContainsAtLeastOne(String input, String possiblePhrase1ToContain,
String ...optionalOtherPossiblePhrasesToContain) {
         if (input==null) fail("Input is null.");
         List<String> missing = MutableList.of();
@@ -1232,7 +1244,20 @@ public class Asserts {
         }
     }
 
-    /** Implements the return beahvior for {@link #expectedFailureOfType(Throwable, Class...)}
and others. */
+    /** Tests {@link #expectedFailure(Throwable)} and that the <code>toString</code>
+     * satisfies {@link #assertStringContains(String, String, String...)}.
+     * @return as per {@link #expectedFailureOfType(Throwable, Class...)} */
+    public static void expectedFailureDoesNotContain(Throwable e, String phrase1ToNotContain,
String ...optionalOtherPhrasesToNotContain) {
+        if (e instanceof ShouldHaveFailedPreviouslyAssertionError) throw (Error)e;
+        try {
+            assertStringDoesNotContain(e.toString(), phrase1ToNotContain, optionalOtherPhrasesToNotContain);
+        } catch (AssertionError ee) {
+            rethrowPreferredException(e, ee);
+        }
+    }
+    
+    /** Implements the return behavior for {@link #expectedFailureOfType(Throwable, Class...)}
and others,
+     * to log interesting earlier errors but to suppress those which are internal or redundant.
*/
     private static void rethrowPreferredException(Throwable earlierPreferredIfFatalElseLogged,
Throwable laterPreferredOtherwise) throws AssertionError {
         if (!(earlierPreferredIfFatalElseLogged instanceof AssertionError)) {
             Exceptions.propagateIfFatal(earlierPreferredIfFatalElseLogged);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
index 2dfd28e..e4c9980 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
@@ -461,4 +461,14 @@ public class Exceptions {
         return appendSeparator(getPrefixText(t), t.getMessage());
     }
 
+    /** Returns true if the root cause is a "boring" CNF, ie a straightforward declaration
that the clazz is not found;
+     * this permits callers to include the cause only when it is interesting, ie caused by
a dependent class not loadable.
+     */
+    public static boolean isRootBoringClassNotFound(Exception e, String clazz) {
+        Throwable root = Throwables.getRootCause(e);
+        if (!(root instanceof ClassNotFoundException)) return false;
+        if (clazz.equals(root.getMessage())) return true;
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4e761709/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ClassLoadingContext.java
b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ClassLoadingContext.java
new file mode 100644
index 0000000..1b2fbf4
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ClassLoadingContext.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util.javalang;
+
+import java.net.URL;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.util.guava.Maybe;
+
+/** 
+ * Provides functionality for loading classes based on the current context
+ * (e.g. the bundles of a registered type from which an entity is created)
+ */
+public interface ClassLoadingContext {
+
+    public Class<?> loadClass(String className);
+    public <T> Class<? extends T> loadClass(String className, @Nullable Class<T>
supertype);
+
+    public Maybe<Class<?>> tryLoadClass(String className);
+    public <T> Maybe<Class<? extends T>> tryLoadClass(String className,
@Nullable Class<T> supertype);
+
+    /** As {@link ClassLoader#getResource(String)} */
+    public URL getResource(String name);
+
+    /**
+     * As {@link ClassLoader#getResources(String)} but returning an {@link Iterable} rather
than
+     * an {@link java.util.Enumeration}.
+     */
+    public Iterable<URL> getResources(String name);
+
+}


Mime
View raw message