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 2021/08/06 13:27:37 UTC
[brooklyn-server] 04/09: ensure scopeRoot resovles to the root node
of the blueprint _where the DSL is used_
This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 987694403aae28046a94f11d730a55c9c08532f8
Author: Alex Heneveld <al...@cloudsoftcorp.com>
AuthorDate: Fri Aug 6 12:45:48 2021 +0100
ensure scopeRoot resovles to the root node of the blueprint _where the DSL is used_
even for nested (extended) types - do this by replacing the DSL expression _at parse time_
---
.../camp/brooklyn/spi/creation/CampResolver.java | 34 ++++++++++++++++++++--
.../brooklyn/spi/dsl/methods/DslComponent.java | 18 +++++++++++-
.../brooklyn/camp/brooklyn/EntitiesYamlTest.java | 12 ++------
3 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java
index 8ac1ecb..9d809d9 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java
@@ -22,6 +22,8 @@ import com.google.common.annotations.Beta;
import java.util.Set;
import java.util.Stack;
+import java.util.function.Consumer;
+import java.util.function.Function;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
@@ -36,8 +38,11 @@ import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
import org.apache.brooklyn.camp.BasicCampPlatform;
import org.apache.brooklyn.camp.CampPlatform;
import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
import org.apache.brooklyn.camp.spi.AssemblyTemplate;
import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.entity.AbstractEntity;
@@ -176,11 +181,14 @@ class CampResolver {
// above will unwrap but only if it's an Application (and it's permitted);
// but it doesn't know whether we need an App or if an Entity is okay
- if (!isApplication) return EntityManagementUtils.unwrapEntity(appSpec);
+ EntitySpec<?> result = !isApplication ? EntityManagementUtils.unwrapEntity(appSpec) : appSpec;
// if we need an App then definitely *don't* unwrap here because
// the instantiator will have done that, and it knows if the plan
// specified a wrapped app explicitly (whereas we don't easily know that here!)
- return appSpec;
+
+ fixScopeRootAtRoot(result);
+
+ return result;
} else {
if (at.getPlatformComponentTemplates()==null || at.getPlatformComponentTemplates().isEmpty()) {
@@ -191,4 +199,26 @@ class CampResolver {
}
+ private static void fixScopeRootAtRoot(EntitySpec<?> node) {
+ node.getConfig().entrySet().forEach(entry -> {
+ fixScopeRoot(entry.getValue(), newValue -> node.configure( (ConfigKey) entry.getKey(), newValue));
+ });
+ node.getFlags().entrySet().forEach(entry -> {
+ fixScopeRoot(entry.getValue(), newValue -> node.configure( entry.getKey(), newValue));
+ });
+ }
+
+ private static void fixScopeRoot(Object value, Consumer<Object> updater) {
+ Function<String,String> fixString = v -> "$brooklyn:self()" + Strings.removeFromStart((String)v, "$brooklyn:scopeRoot()");
+ if (value instanceof String && ((String)value).startsWith("$brooklyn:scopeRoot()")) {
+ value = fixString.apply((String)value);
+ updater.accept(value);
+ } else if (value instanceof DslComponent) {
+ if ( ((DslComponent)value).getScope() == Scope.SCOPE_ROOT ) {
+ value = DslComponent.newInstanceChangingScope(Scope.THIS, (DslComponent) value, fixString);
+ updater.accept(value);
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
index cf6fa2d..01c68e1 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.camp.brooklyn.spi.dsl.methods;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Set;
+import java.util.function.Function;
import static org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils.resolved;
import java.util.Collection;
@@ -113,6 +114,20 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements
}
}
+ public static DslComponent newInstanceChangingScope(Scope scope, DslComponent old, Function<String,String> dslUpdateFn) {
+ DslComponent result;
+ if (old.componentIdSupplier!=null) result = new DslComponent(scope, old.componentIdSupplier);
+ else if (old.componentId!=null) result = new DslComponent(scope, old.componentId);
+ else result = new DslComponent(scope);
+
+ if (dslUpdateFn!=null && old.dsl instanceof String) {
+ result.dsl = dslUpdateFn.apply((String) old.dsl);
+ } else {
+ result.dsl = old.dsl;
+ }
+ return result;
+ }
+
/**
* Resolve componentId in the {@link Scope#GLOBAL} scope.
*
@@ -1028,7 +1043,8 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements
DESCENDANT,
ANCESTOR,
ROOT,
- /** highest ancestor where all items come from the same catalog item ID */
+ /** root node of blueprint where the the DSL is used; usually the depth in ancestor,
+ * though specially treated in CampResolver to handle usage within blueprints */
SCOPE_ROOT,
THIS;
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index 4ee8a4c..e86ab1a 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -586,7 +586,8 @@ public class EntitiesYamlTest extends AbstractYamlTest {
Entity e2 = nextChild(e1);
assertScopes(e2, "APP-grandchild", app, app);
Entity e3 = nextChild(e2);
- assertScopes(e3, "APP-greatgrandchild=RP", app, e2, app);
+ // see logic in CampResolver which ensures scopeRoot in a nested blueprint refer to the root of that nested blueprint
+ assertScopes(e3, "APP-greatgrandchild=RP", app, e3, app);
Entity e4 = nextChild(e3);
assertScopes(e4, "RP-child", app, e3);
Entity e5 = nextChild(e4);
@@ -622,14 +623,7 @@ public class EntitiesYamlTest extends AbstractYamlTest {
private static void assertScopes(Entity entity, String name, Entity root, Entity scopeRoot, Entity scopeRoot2) {
if (name!=null) assertEquals(entity.getDisplayName(), name);
assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT), root);
-
- Entity actualScopeRoot = entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT);
- if (!actualScopeRoot.equals(scopeRoot) && !actualScopeRoot.equals(scopeRoot2)) {
- Assert.fail("Wrong scope root; should be either "+scopeRoot+" or "+scopeRoot2+"; but is actually "+actualScopeRoot);
- }
- // TODO would be nice if we can capture which blueprint scopeRoot is used in - but this requires introspecting the DSL
- // currently it will always equal scopeRoot2; if we could convert it to "self()" when the definition is loaded, that would solve it
-
+ assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT), scopeRoot);
assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT2), scopeRoot2);
}