@Test public void testRebindAfterItemDeprecated() { String symbolicName = "rebind-yaml-catalog-item-test"; String yaml = Joiner.on("\n") .join( "brooklyn.catalog:", " items:", " - id: " + symbolicName, " version: " + TEST_VERSION, " itemType: entity", " item:", " type: io.camp.mock:AppServer"); CatalogEntityItemDto item = CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION) .displayName(symbolicName) .plan(yaml) .build(); origManagementContext.getCatalog().addItem(item); assertNotNull(item, "catalogItem"); BasicBrooklynCatalog catalog = (BasicBrooklynCatalog) origManagementContext.getCatalog(); item.setDeprecated(true); catalog.persist(item); rebindAndAssertCatalogsAreEqual(); RegisteredType catalogItemAfterRebind = newManagementContext.getTypeRegistry().get("rebind-yaml-catalog-item-test", TEST_VERSION); assertTrue(catalogItemAfterRebind.isDeprecated(), "Expected item to be deprecated"); }
private static <T> Maybe<T> tryValidateBean( T object, RegisteredType type, final RegisteredTypeLoadingContext context) { if (object == null) return Maybe.absentNull("object is null"); if (type != null) { if (type.getKind() != RegisteredTypeKind.BEAN) return Maybe.absent("Validating a bean when type is " + type.getKind() + " " + type); if (!isSubtypeOf(object.getClass(), type)) return Maybe.absent(object + " does not have all the java supertypes of " + type); } if (context != null) { 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()); } return Maybe.of(object); }
/** * returns the implementation data for a spec if it is a string (e.g. plan yaml or java class * name); else throws */ @Beta public static String getImplementationDataStringForSpec(RegisteredType item) { if (item == null || item.getPlan() == null) return null; Object data = item.getPlan().getPlanData(); if (!(data instanceof String)) throw new IllegalStateException("Expected plan data for " + item + " to be a string"); return (String) data; }
/** * Queries recursively the supertypes of {@link RegisteredType} to see whether it inherits from * the given {@link RegisteredType} */ public static boolean isSubtypeOf(RegisteredType type, RegisteredType superType) { if (type.equals(superType)) return true; for (Object st : type.getSuperTypes()) { if (st instanceof RegisteredType) { if (isSubtypeOf((RegisteredType) st, superType)) return true; } } return false; }
@Override protected AbstractBrooklynObjectSpec<?, ?> createSpec( RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { if (REGISTERED_SPECS.containsKey(type.getSymbolicName())) return get(type.getSymbolicName()); if (type.getPlan().getPlanData() != null && REGISTERED_SPECS.containsKey(type.getPlan().getPlanData())) return get((String) type.getPlan().getPlanData()); return null; }
private static <T> Maybe<T> tryValidateSpec( T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) { if (object == null) return Maybe.absentNull("object is null"); if (!(object instanceof AbstractBrooklynObjectSpec)) { Maybe.absent("Found " + object + " when expecting a spec"); } Class<?> targetType = ((AbstractBrooklynObjectSpec<?, ?>) object).getType(); if (targetType == null) { Maybe.absent("Spec " + object + " does not have a target type"); } if (rType != null) { if (rType.getKind() != RegisteredTypeKind.SPEC) Maybe.absent("Validating a spec when type is " + rType.getKind() + " " + rType); if (!isSubtypeOf(targetType, 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)) { 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 } else { @SuppressWarnings("unchecked") Class<? extends AbstractBrooklynObjectSpec<?, ?>> specType = RegisteredTypeLoadingContexts.lookupSpecTypeForTarget( (Class<? extends BrooklynObject>) constraint.getExpectedJavaSuperType()); if (specType == null) { // means a problem in our classification of spec types! Maybe.absent( object + " is returned as spec for unexpected java supertype " + constraint.getExpectedJavaSuperType()); } if (!specType.isAssignableFrom(object.getClass())) { Maybe.absent( object + " is not a spec of the expected java supertype " + constraint.getExpectedJavaSuperType()); } } } } return Maybe.of(object); }
@Override protected double scoreForNullFormat( Object planData, RegisteredType type, RegisteredTypeLoadingContext context) { if (REGISTERED_SPECS.containsKey(type.getId())) return 1; if (REGISTERED_SPECS.containsKey(planData)) return 1; return 0; }
@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(); }
/** Checks whether the given object appears to be an instance of the given registered type */ private static boolean isSubtypeOf(Class<?> candidate, RegisteredType type) { for (Object st : type.getSuperTypes()) { if (st instanceof RegisteredType) { if (!isSubtypeOf(candidate, (RegisteredType) st)) return false; } if (st instanceof Class) { if (!((Class<?>) st).isAssignableFrom(candidate)) return false; } } return true; }
/** * Validates that the given type matches the context (if supplied); if not satisfied. returns an * {@link Absent} if failed with details of the error, with {@link Absent#isNull()} true if the * object is null. */ public static Maybe<RegisteredType> tryValidate( RegisteredType item, final RegisteredTypeLoadingContext constraint) { // kept as a Maybe in case someone wants a wrapper around item validity; // unclear what the contract should be, as this can return Maybe.Present(null) // which is suprising, but it is more natural to callers otherwise they'll likely do a separate // null check on the item // (often handling null different to errors) so the Maybe.get() is redundant as they have an // object for the input anyway. if (item == null || constraint == null) return Maybe.ofDisallowingNull(item); if (constraint.getExpectedKind() != null && !constraint.getExpectedKind().equals(item.getKind())) return Maybe.absent(item + " is not the expected kind " + constraint.getExpectedKind()); if (constraint.getExpectedJavaSuperType() != null) { if (!isSubtypeOf(item, constraint.getExpectedJavaSuperType())) { return Maybe.absent( item + " is not for the expected type " + constraint.getExpectedJavaSuperType()); } } return Maybe.of(item); }
/** * validates that the given object (required) satisfies the constraints implied by the given type * and context object, using {@link Maybe} as the result set absent containing the error(s) if not * satisfied. returns an {@link Absent} if failed with details of the error, with {@link * Absent#isNull()} true if the object is null. */ public static <T> Maybe<T> tryValidate( final T object, @Nullable final RegisteredType type, @Nullable final RegisteredTypeLoadingContext context) { if (object == null) return Maybe.absentNull("object is null"); RegisteredTypeKind kind = type != null ? type.getKind() : context != null ? context.getExpectedKind() : null; if (kind == null) { if (object instanceof AbstractBrooklynObjectSpec) kind = RegisteredTypeKind.SPEC; else kind = RegisteredTypeKind.BEAN; } return new RegisteredTypeKindVisitor<Maybe<T>>() { @Override protected Maybe<T> visitSpec() { return tryValidateSpec(object, type, context); } @Override protected Maybe<T> visitBean() { return tryValidateBean(object, type, context); } }.visit(kind); }
/** * Queries recursively the supertypes of {@link RegisteredType} to see whether it inherits from * the given {@link Class} */ public static boolean isSubtypeOf(RegisteredType type, Class<?> superType) { return isAnyTypeSubtypeOf(type.getSuperTypes(), superType); }