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 2014/09/10 00:49:21 UTC
[18/19] git commit: address most code review comments,
including refactoring to move common add-children logic and some app
creation logic to new class EntityManagementUtils
address most code review comments, including refactoring to move common add-children logic and some app creation logic to new class EntityManagementUtils
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/b05a9c11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/b05a9c11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/b05a9c11
Branch: refs/heads/master
Commit: b05a9c11d30fdfc8aefde2c386f34d8bab4efcdd
Parents: f7ce1a2
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Sep 9 23:08:48 2014 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Sep 9 23:42:06 2014 +0100
----------------------------------------------------------------------
.../entity/basic/ServiceStateLogic.java | 4 +-
.../entity/effector/AddChildrenEffector.java | 202 +-----------
.../internal/EntityManagementUtils.java | 304 +++++++++++++++++++
.../entity/proxy/nginx/NginxControllerImpl.java | 2 +-
.../BrooklynAssemblyTemplateInstantiator.java | 38 +--
.../webapp/assets/js/libs/brooklyn-utils.js | 10 +-
.../webapp/assets/js/view/add-child-invoke.js | 3 +-
.../webapp/assets/js/view/change-name-invoke.js | 13 +-
.../webapp/assets/js/view/entity-advanced.js | 22 +-
.../main/webapp/assets/js/view/entity-config.js | 10 +-
.../webapp/assets/js/view/entity-summary.js | 5 +-
.../main/webapp/assets/js/view/policy-new.js | 1 -
.../webapp/assets/tpl/apps/add-child-modal.html | 2 +-
.../main/webapp/assets/tpl/apps/advanced.html | 5 +-
.../main/webapp/assets/tpl/apps/summary.html | 2 +-
.../specs/view/entity-details-spec.js | 5 -
.../main/java/brooklyn/rest/api/EntityApi.java | 2 +-
.../java/brooklyn/rest/api/EntityConfigApi.java | 2 +-
usage/rest-server/pom.xml | 14 -
.../rest/resources/ApplicationResource.java | 35 +--
.../brooklyn/rest/resources/EntityResource.java | 12 +-
.../rest/testing/BrooklynRestApiTest.java | 2 +-
22 files changed, 381 insertions(+), 314 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
index 7448445..3510121 100644
--- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
+++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
@@ -449,10 +449,10 @@ public class ServiceStateLogic {
// quorate
return null;
- if (onesNotHealthy.size()==0)
+ if (onesNotHealthy.isEmpty())
return "Not enough entities running to be quorate";
} else {
- if (onesNotHealthy.size()==0)
+ if (onesNotHealthy.isEmpty())
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/core/src/main/java/brooklyn/entity/effector/AddChildrenEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/effector/AddChildrenEffector.java b/core/src/main/java/brooklyn/entity/effector/AddChildrenEffector.java
index f216a53..5ce5bde 100644
--- a/core/src/main/java/brooklyn/entity/effector/AddChildrenEffector.java
+++ b/core/src/main/java/brooklyn/entity/effector/AddChildrenEffector.java
@@ -18,49 +18,22 @@
*/
package brooklyn.entity.effector;
-import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-
-import java.io.Reader;
-import java.io.StringReader;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
-import brooklyn.config.BrooklynServerConfig;
import brooklyn.config.ConfigKey;
import brooklyn.entity.Effector;
import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BrooklynTaskTags;
import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityFunctions;
-import brooklyn.entity.basic.EntityLocal;
import brooklyn.entity.effector.Effectors.EffectorBuilder;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.trait.Startable;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
-import brooklyn.util.collections.MutableList;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagementUtils.CreationResult;
import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.text.Strings;
-import brooklyn.util.time.Duration;
import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
import com.google.gson.Gson;
/** Entity initializer which defines an effector which adds a child blueprint to an entity.
@@ -136,175 +109,10 @@ public class AddChildrenEffector extends AddEffector {
}
log.debug(this+" adding children to "+entity()+":\n"+blueprint);
- AddChildrenResult result = addChildren(entity(), blueprint, autostart, Duration.ZERO);
- log.debug(this+" added children to "+entity()+": "+result.getChildren());
- return result.getTask().getUnchecked();
- }
- }
-
- public static class AddChildrenResult {
- public final List<Entity> children;
- public final Task<List<String>> task;
- public AddChildrenResult(List<Entity> children, Task<List<String>> task) {
- super();
- this.children = children;
- this.task = task;
- }
- public List<Entity> getChildren() {
- return children;
- }
- public Task<List<String>> getTask() {
- return task;
- }
- }
-
- public static AddChildrenResult addChildren(final EntityLocal parent, String yaml, Boolean start, Duration timeout) {
- log.debug("Creating child of "+parent+" from yaml:\n{}", yaml);
-
- ManagementContext mgmt = parent.getApplication().getManagementContext();
- CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
-
- Reader input = new StringReader(yaml);
- AssemblyTemplate at = camp.pdp().registerDeploymentPlan(input);
-
- AssemblyTemplateInstantiator instantiator;
- try {
- instantiator = at.getInstantiator().newInstance();
- } catch (Exception e) {
- throw Exceptions.propagate(e);
- }
- if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
- BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
- EntitySpec<?> specA = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, false);
-
- boolean promoted;
-
- // see whether we can promote children
- List<EntitySpec<?>> specs = MutableList.of();
- if (hasNoNameOrCustomKeysOrRoot(at, specA)) {
- // we can promote
- promoted = true;
- for (EntitySpec<?> specC: specA.getChildren()) {
- collapseSpec(specA, specC);
- specs.add(specC);
- }
- } else {
- // if not promoting, set a nice name if needed
- if (Strings.isEmpty(specA.getDisplayName())) {
- int size = specA.getChildren().size();
- String childrenCountString = size+" "+(size!=1 ? "children" : "child");
- specA.displayName("Dynamically added "+childrenCountString);
- }
- promoted = false;
- specs.add(specA);
- }
-
- final List<Entity> children = MutableList.of();
- for (EntitySpec<?> spec: specs) {
- Entity child = (Entity)parent.addChild(spec);
- Entities.manage(child);
- children.add(child);
- }
-
- String childrenCountString;
- if (promoted) {
- int size = children.size();
- childrenCountString = size+" "+(size!=1 ? "children" : "child");
- } else {
- int size = specA.getChildren().size();
- childrenCountString = "entity with "+size+" "+(size!=1 ? "children" : "child");
- }
-
- TaskBuilder<List<String>> taskM = Tasks.<List<String>>builder().name("add children")
- .dynamic(true)
- .tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
- .body(new Callable<List<String>>() {
- @Override public List<String> call() throws Exception {
- return ImmutableList.copyOf(Iterables.transform(children, EntityFunctions.id()));
- }})
- .description("Add" + (start==null ? " and potentially start" : start ? " and start" : "") + " "+childrenCountString);
- TaskBuilder<?> taskS = Tasks.builder().parallel(true).name("add (parallel)")
- .description(
- (start==null ? "Add or start" : start ? "Start" : "Add")+" each new entity");
-
- // should we autostart?
- for (Entity child: children) {
- if (Boolean.TRUE.equals(start) || (start==null && child instanceof Startable)) {
- taskS.add(Effectors.invocation(child, Startable.START, ImmutableMap.of("locations", ImmutableList.of())));
- } else {
- taskS.add(Tasks.builder().name("create").description("Created and added as child of "+parent)
- .body(new Runnable() { public void run() {} })
- .tag(BrooklynTaskTags.tagForTargetEntity(child))
- .build());
- }
- }
- taskM.add(taskS.build());
- Task<List<String>> task = Entities.submit(parent, taskM.build());
-
- // wait a few ms in case start is trivially simple, save the client a call to get the task result
- task.blockUntilEnded(timeout);
-
- return new AddChildrenResult(children, task);
- } else {
- throw new IllegalStateException("Spec could not be parsed to supply a compatible instantiator");
- }
- }
-
- /** worker method to combine specs */
- @Beta //where should this live long-term?
- public static void collapseSpec(EntitySpec<?> sourceToBeCollapsed, EntitySpec<?> targetToBeExpanded) {
- if (Strings.isEmpty(targetToBeExpanded.getDisplayName()))
- targetToBeExpanded.displayName(sourceToBeCollapsed.getDisplayName());
- if (!sourceToBeCollapsed.getLocations().isEmpty())
- targetToBeExpanded.locations(sourceToBeCollapsed.getLocations());
-
- // NB: this clobbers child config; might prefer to deeply merge maps etc
- // (but this should not be surprising, as unwrapping is often parameterising the nested blueprint, so outer config should dominate)
- targetToBeExpanded.configure(sourceToBeCollapsed.getConfig());
- targetToBeExpanded.configure(sourceToBeCollapsed.getFlags());
-
- // TODO copying tags to all entities is not ideal;
- // in particular the BrooklynTags.YAML_SPEC tag will show all entities if the root has multiple
- targetToBeExpanded.tags(sourceToBeCollapsed.getTags());
- }
-
- /** worker method to help determine whether child/children can be promoted */
- @Beta //where should this live long-term?
- public static boolean hasNoNameOrCustomKeysOrRoot(AssemblyTemplate template, EntitySpec<?> spec) {
- if (!Strings.isEmpty(template.getName())) {
- if (spec.getChildren().size()==1) {
- String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName();
- if (Strings.isEmpty(childName) || childName.equals(template.getName())) {
- // if child has no name, or it's the same, could still promote
- } else {
- return false;
- }
- } else {
- // if name set at root and promoting children would be ambiguous, do not promote
- return false;
- }
- } else if (spec.getChildren().size()>1) {
- // don't allow multiple children if a name is specified as a root
- return false;
- }
-
- Set<String> rootAttrs = template.getCustomAttributes().keySet();
- for (String rootAttr: rootAttrs) {
- if (rootAttr.equals("brooklyn.catalog") || rootAttr.equals("brooklyn.config")) {
- // these do not block promotion
- continue;
- }
- if (rootAttr.startsWith("brooklyn.")) {
- // any others in 'brooklyn' namespace will block promotion
- return false;
- }
- // location is allowed in both, and is copied on promotion
- // (name also copied)
- // others are root currently are ignored on promotion; they are usually metadata
- // TODO might be nice to know what we are excluding
+ CreationResult<List<Entity>, List<String>> result = EntityManagementUtils.addChildren(entity(), blueprint, autostart);
+ log.debug(this+" added children to "+entity()+": "+result.get());
+ return result.task().getUnchecked();
}
-
- return true;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
new file mode 100644
index 0000000..0db77ab
--- /dev/null
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.management.internal;
+
+import io.brooklyn.camp.CampPlatform;
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityFunctions;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.trait.Startable;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.task.TaskBuilder;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.text.Strings;
+import brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+/** Utility methods for working with entities and applications */
+public class EntityManagementUtils {
+
+ private static final Logger log = LoggerFactory.getLogger(EntityManagementUtils.class);
+
+ /** creates an application from the given app spec, managed by the given management context */
+ public static <T extends Application> T createUnstarted(ManagementContext mgmt, EntitySpec<T> spec) {
+ T app = mgmt.getEntityManager().createEntity(spec);
+ Entities.startManagement(app, mgmt);
+ return app;
+ }
+
+ /** convenience for accessing camp */
+ public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) {
+ return BrooklynServerConfig.getCampPlatform(mgmt);
+ }
+
+ /** as {@link #createApplication(ManagementContext, EntitySpec)} but for a YAML spec */
+ public static <T extends Application> T createUnstarted(ManagementContext mgmt, String yaml) {
+ AssemblyTemplate at = getCampPlatform(mgmt).get().pdp().registerDeploymentPlan( new StringReader(yaml) );
+ return createUnstarted(mgmt, at);
+ }
+
+ /** as {@link #createApplication(ManagementContext, EntitySpec)} but for an assembly template */
+ @SuppressWarnings("unchecked")
+ public static <T extends Application> T createUnstarted(ManagementContext mgmt, AssemblyTemplate at) {
+ CampPlatform camp = getCampPlatform(mgmt).get();
+ AssemblyTemplateInstantiator instantiator;
+ try {
+ instantiator = at.getInstantiator().newInstance();
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ Assembly assembly;
+ if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
+ BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
+
+ EntitySpec<?> spec = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, true);
+ Entity app = mgmt.getEntityManager().createEntity(spec);
+ Entities.startManagement(app);
+ return (T) app;
+ } else {
+ assembly = instantiator.instantiate(at, camp);
+ return (T) mgmt.getEntityManager().getEntity(assembly.getId());
+ }
+ }
+
+ /** container for operation which creates something and which wants to return both
+ * the items created and any pending create/start task */
+ public static class CreationResult<T,U> {
+ private final T thing;
+ @Nullable private final Task<U> task;
+ public CreationResult(T thing, Task<U> task) {
+ super();
+ this.thing = thing;
+ this.task = task;
+ }
+
+ protected static <T,U> CreationResult<T,U> of(T thing, @Nullable Task<U> task) {
+ return new CreationResult<T,U>(thing, task);
+ }
+
+ /** returns the thing/things created */
+ @Nullable public T get() { return thing; }
+ /** associated task, ie the one doing the creation/starting */
+ public Task<U> task() { return task; }
+ public CreationResult<T,U> blockUntilComplete(Duration timeout) { if (task!=null) task.blockUntilEnded(timeout); return this; }
+ public CreationResult<T,U> blockUntilComplete() { if (task!=null) task.blockUntilEnded(); return this; }
+ }
+
+ public static <T extends Application> CreationResult<T,Void> createStarting(ManagementContext mgmt, EntitySpec<T> appSpec) {
+ return start(createUnstarted(mgmt, appSpec));
+ }
+
+ public static CreationResult<? extends Application,Void> createStarting(ManagementContext mgmt, String appSpec) {
+ return start(createUnstarted(mgmt, appSpec));
+ }
+
+ public static CreationResult<? extends Application,Void> createStarting(ManagementContext mgmt, AssemblyTemplate at) {
+ return start(createUnstarted(mgmt, at));
+ }
+
+ public static <T extends Application> CreationResult<T,Void> start(T app) {
+ Task<Void> task = Entities.invokeEffector((EntityLocal)app, app, Startable.START,
+ // locations already set in the entities themselves;
+ // TODO make it so that this arg does not have to be supplied to START !
+ MutableMap.of("locations", MutableList.of()));
+ return CreationResult.of(app, task);
+ }
+
+ public static CreationResult<List<Entity>, List<String>> addChildren(final EntityLocal parent, String yaml, Boolean start) {
+ if (Boolean.FALSE.equals(start))
+ return CreationResult.of(addChildrenUnstarted(parent, yaml), null);
+ return addChildrenStarting(parent, yaml);
+ }
+
+ /** adds entities from the given yaml, under the given parent; but does not start them */
+ public static List<Entity> addChildrenUnstarted(final EntityLocal parent, String yaml) {
+ log.debug("Creating child of "+parent+" from yaml:\n{}", yaml);
+
+ ManagementContext mgmt = parent.getApplication().getManagementContext();
+ CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
+
+ AssemblyTemplate at = camp.pdp().registerDeploymentPlan( new StringReader(yaml) );
+
+ AssemblyTemplateInstantiator instantiator;
+ try {
+ instantiator = at.getInstantiator().newInstance();
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
+ BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
+ EntitySpec<?> specA = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, false);
+
+ // see whether we can promote children
+ List<EntitySpec<?>> specs = MutableList.of();
+ if (hasNoNameOrCustomKeysOrRoot(at, specA)) {
+ // we can promote
+ for (EntitySpec<?> specC: specA.getChildren()) {
+ collapseSpec(specA, specC);
+ specs.add(specC);
+ }
+ } else {
+ // if not promoting, set a nice name if needed
+ if (Strings.isEmpty(specA.getDisplayName())) {
+ int size = specA.getChildren().size();
+ String childrenCountString = size+" "+(size!=1 ? "children" : "child");
+ specA.displayName("Dynamically added "+childrenCountString);
+ }
+ specs.add(specA);
+ }
+
+ final List<Entity> children = MutableList.of();
+ for (EntitySpec<?> spec: specs) {
+ Entity child = (Entity)parent.addChild(spec);
+ Entities.manage(child);
+ children.add(child);
+ }
+
+ return children;
+ } else {
+ throw new IllegalStateException("Spec could not be parsed to supply a compatible instantiator");
+ }
+ }
+
+ public static CreationResult<List<Entity>,List<String>> addChildrenStarting(final EntityLocal parent, String yaml) {
+ final List<Entity> children = addChildrenUnstarted(parent, yaml);
+ String childrenCountString;
+
+ int size = children.size();
+ childrenCountString = size+" "+(size!=1 ? "children" : "child");
+
+ TaskBuilder<List<String>> taskM = Tasks.<List<String>>builder().name("add children")
+ .dynamic(true)
+ .tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
+ .body(new Callable<List<String>>() {
+ @Override public List<String> call() throws Exception {
+ return ImmutableList.copyOf(Iterables.transform(children, EntityFunctions.id()));
+ }})
+ .description("Add and start "+childrenCountString);
+
+ TaskBuilder<?> taskS = Tasks.builder().parallel(true).name("add (parallel)").description("Start each new entity");
+
+ // autostart if requested
+ for (Entity child: children) {
+ if (child instanceof Startable) {
+ taskS.add(Effectors.invocation(child, Startable.START, ImmutableMap.of("locations", ImmutableList.of())));
+ } else {
+ // include a task, just to give feedback in the GUI
+ taskS.add(Tasks.builder().name("create").description("Skipping start (not a Startable Entity)")
+ .body(new Runnable() { public void run() {} })
+ .tag(BrooklynTaskTags.tagForTargetEntity(child))
+ .build());
+ }
+ }
+ taskM.add(taskS.build());
+ Task<List<String>> task = Entities.submit(parent, taskM.build());
+
+ return CreationResult.of(children, task);
+ }
+
+ /** worker method to combine specs */
+ @Beta //where should this live long-term?
+ public static void collapseSpec(EntitySpec<?> sourceToBeCollapsed, EntitySpec<?> targetToBeExpanded) {
+ if (Strings.isEmpty(targetToBeExpanded.getDisplayName()))
+ targetToBeExpanded.displayName(sourceToBeCollapsed.getDisplayName());
+ if (!sourceToBeCollapsed.getLocations().isEmpty())
+ targetToBeExpanded.locations(sourceToBeCollapsed.getLocations());
+
+ // NB: this clobbers child config; might prefer to deeply merge maps etc
+ // (but this should not be surprising, as unwrapping is often parameterising the nested blueprint, so outer config should dominate)
+ targetToBeExpanded.configure(sourceToBeCollapsed.getConfig());
+ targetToBeExpanded.configure(sourceToBeCollapsed.getFlags());
+
+ // TODO copying tags to all entities is not ideal;
+ // in particular the BrooklynTags.YAML_SPEC tag will show all entities if the root has multiple
+ targetToBeExpanded.tags(sourceToBeCollapsed.getTags());
+ }
+
+ /** worker method to help determine whether child/children can be promoted */
+ @Beta //where should this live long-term?
+ public static boolean hasNoNameOrCustomKeysOrRoot(AssemblyTemplate template, EntitySpec<?> spec) {
+ if (!Strings.isEmpty(template.getName())) {
+ if (spec.getChildren().size()==1) {
+ String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName();
+ if (Strings.isEmpty(childName) || childName.equals(template.getName())) {
+ // if child has no name, or it's the same, could still promote
+ } else {
+ return false;
+ }
+ } else {
+ // if name set at root and promoting children would be ambiguous, do not promote
+ return false;
+ }
+ } else if (spec.getChildren().size()>1) {
+ // don't allow multiple children if a name is specified as a root
+ return false;
+ }
+
+ Set<String> rootAttrs = template.getCustomAttributes().keySet();
+ for (String rootAttr: rootAttrs) {
+ if (rootAttr.equals("brooklyn.catalog") || rootAttr.equals("brooklyn.config")) {
+ // these do not block promotion
+ continue;
+ }
+ if (rootAttr.startsWith("brooklyn.")) {
+ // any others in 'brooklyn' namespace will block promotion
+ return false;
+ }
+ // location is allowed in both, and is copied on promotion
+ // (name also copied)
+ // others are root currently are ignored on promotion; they are usually metadata
+ // TODO might be nice to know what we are excluding
+ }
+
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index 2b0edc5..b9d4ecf 100644
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -110,7 +110,7 @@ public class NginxControllerImpl extends AbstractControllerImpl implements Nginx
addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS)
.from(NGINX_URL_ANSWERS_NICELY)
- .computing(Functionals.ifNotEquals(true).value("URL where nginx listens is not answering correctly") )
+ .computing(Functionals.ifNotEquals(true).value("URL where nginx listens is not answering correctly (with expected header)") )
.build());
connectServiceUpIsRunning();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index d21259d..5e1a8ca 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -47,18 +47,12 @@ import brooklyn.config.BrooklynServerConfig;
import brooklyn.entity.Application;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.BasicApplicationImpl;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.effector.AddChildrenEffector;
import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.trait.Startable;
import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagementUtils.CreationResult;
import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.flags.TypeCoercions;
import brooklyn.util.net.Urls;
@@ -76,23 +70,14 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
@Override
public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) {
Application app = create(template, platform);
- Task<?> task = start(app, platform);
- log.info("CAMP created "+app+"; starting in "+task);
+ CreationResult<Application, Void> start = EntityManagementUtils.start(app);
+ log.debug("CAMP created "+app+"; starting in "+start.task());
return platform.assemblies().get(app.getApplicationId());
}
- // note: based on BrooklynRestResourceUtils, but modified to not allow child entities (yet)
- // (will want to revise that when building up from a non-brooklyn template)
public Application create(AssemblyTemplate template, CampPlatform platform) {
- ManagementContext mgmt = getBrooklynManagementContext(platform);
-
- BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
- EntitySpec<? extends Application> spec = createSpec(template, platform, loader, true);
-
- Application instance = mgmt.getEntityManager().createEntity(spec);
- log.info("CAMP placing '{}' under management", instance);
- Entities.startManagement(instance, mgmt);
-
+ Application instance = EntityManagementUtils.createUnstarted(getBrooklynManagementContext(platform), template);
+ log.debug("CAMP created {}", instance);
return instance;
}
@@ -100,13 +85,6 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
}
- public Task<?> start(Application app, CampPlatform platform) {
- return Entities.invokeEffector((EntityLocal)app, app, Startable.START,
- // locations already set in the entities themselves;
- // TODO make it so that this arg does not have to be supplied to START !
- MutableMap.of("locations", MutableList.of()));
- }
-
@SuppressWarnings("unchecked")
public EntitySpec<? extends Application> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfPossible) {
log.debug("CAMP creating application instance for {} ({})", template.getId(), template);
@@ -129,7 +107,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
// if promoted, apply the transformations done to the app
// (transformations will be done by the resolveSpec call above, but we are collapsing oldApp so transfer to app=newApp)
- AddChildrenEffector.collapseSpec(oldApp, app);
+ EntityManagementUtils.collapseSpec(oldApp, app);
}
return app;
@@ -163,7 +141,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
if (childSpec.getType()==null || !Application.class.isAssignableFrom(childSpec.getType()))
return false;
- return AddChildrenEffector.hasNoNameOrCustomKeysOrRoot(template, app);
+ return EntityManagementUtils.hasNoNameOrCustomKeysOrRoot(template, app);
}
private List<EntitySpec<?>> buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
index acd8135..e85913f 100644
--- a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
+++ b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
@@ -114,9 +114,17 @@ define([
* alternate message if parsing fails or the parsed object has no message.
* @param {jqXHR} xhrResponse
* @param {string} alternateMessage
+ * @param {string} logMessage, if false or null, does not log;
+ * otherwise it logs a message and the xhrResponse, with logMessage (or with alternateMessage if logMessage is true)
* @returns {*}
*/
- Util.extractError = function (xhrResponse, alternateMessage) {
+ Util.extractError = function (xhrResponse, alternateMessage, logMessage) {
+ if (logMessage) {
+ if (logMessage==true) log("ERROR: "+alternateMessage);
+ else log("ERROR: "+logMessage);
+ log(xhrResponse);
+ }
+
try {
var response = JSON.parse(xhrResponse.responseText);
return response.message ? response.message : alternateMessage;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/add-child-invoke.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/add-child-invoke.js b/usage/jsgui/src/main/webapp/assets/js/view/add-child-invoke.js
index b29f295..ea7d6c9 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/add-child-invoke.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/add-child-invoke.js
@@ -46,8 +46,7 @@ define([
self.options.target.reload();
},
error: function(response) {
- var message = JSON.parse(response.responseText).message;
- self.showError(message);
+ self.showError(Util.extractError(response, "Error contacting server", url));
}
});
return ajax;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/change-name-invoke.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/change-name-invoke.js b/usage/jsgui/src/main/webapp/assets/js/view/change-name-invoke.js
index 95d2abc..30c2277 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/change-name-invoke.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/change-name-invoke.js
@@ -20,9 +20,9 @@
* Render entity expungement as a modal
*/
define([
- "underscore", "jquery", "backbone",
+ "underscore", "jquery", "backbone", "brooklyn-utils",
"text!tpl/apps/change-name-modal.html"
-], function(_, $, Backbone, ChangeNameModalHtml) {
+], function(_, $, Backbone, Util, ChangeNameModalHtml) {
return Backbone.View.extend({
template: _.template(ChangeNameModalHtml),
initialize: function() {
@@ -44,14 +44,7 @@ define([
self.options.target.reload();
},
error: function(response) {
- var message = "Error contacting server";
- try {
- message = JSON.parse(response.responseText).message;
- } catch (e) {
- log("UNPARSEABLE RESPONSE");
- log(response);
- }
- self.showError(message);
+ self.showError(Util.extractError(response, "Error contacting server", url));
}
});
return ajax;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/entity-advanced.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-advanced.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-advanced.js
index 49114f6..362cadb 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-advanced.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-advanced.js
@@ -30,7 +30,7 @@ define(["underscore", "jquery", "backbone", "brooklyn", "brooklyn-utils", "view/
"click button#change-name": "showChangeNameModal",
"click button#add-child": "showAddChildModal",
"click button#add-new-policy": "showNewPolicyModal",
- "click button#reset-problems": "doResetProblems",
+ "click button#reset-problems": "confirmResetProblems",
"click button#expunge": "confirmExpunge",
"click button#unmanage": "confirmUnmanage",
"click #advanced-tab-error-closer": "closeAdvancedTabError"
@@ -95,6 +95,17 @@ define(["underscore", "jquery", "backbone", "brooklyn", "brooklyn-utils", "view/
entity: this.model,
}));
},
+
+ confirmResetProblems: function () {
+ var entity = this.model.get("name");
+ var title = "Confirm the reset of problem indicators in " + entity;
+ var q = "<p>Are you sure you want to reset the problem indicators for this entity?</p>" +
+ "<p>If a problem has been fixed externally, but the fix is not being detected, this will clear problems. " +
+ "If the problem is not actually fixed, many feeds and enrichers will re-detect it, but note that some may not, " +
+ "and the entity may show as healthy when it is not." +
+ "</p>";
+ Brooklyn.view.requestConfirmation(q, title).done(this.doResetProblems);
+ },
doResetProblems: function() {
this.post(this.model.get('links').sensors+"/"+"service.notUp.indicators", {});
this.post(this.model.get('links').sensors+"/"+"service.problems", {});
@@ -110,11 +121,8 @@ define(["underscore", "jquery", "backbone", "brooklyn", "brooklyn-utils", "view/
success: function() {
self.reload();
},
- error: function(data) {
- self.showAdvancedTabError("Error connecting to Brooklyn server");
-
- log("ERROR invoking operation");
- log(data);
+ error: function(response) {
+ self.showAdvancedTabError(Util.extractError(response, "Error contacting server", url));
}
});
},
@@ -161,7 +169,6 @@ define(["underscore", "jquery", "backbone", "brooklyn", "brooklyn-utils", "view/
self.$("#advanced-tab-error-section").removeClass("hide");
},
closeAdvancedTabError: function() {
- log("close")
self.$("#advanced-tab-error-section").addClass("hide");
},
@@ -169,6 +176,7 @@ define(["underscore", "jquery", "backbone", "brooklyn", "brooklyn-utils", "view/
if (this.activeModal)
this.activeModal.close();
this.options.tabView.configView.close();
+ this.model.off();
}
});
return EntityAdvancedView;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
index e22763e..175dbcc 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
@@ -42,7 +42,7 @@ define([
zeroClipboard: null,
events:{
- 'click .refresh':'refreshNow',
+ 'click .refresh':'updateConfigNow',
'click .filterEmpty':'toggleFilterEmpty',
'click .toggleAutoRefresh':'toggleAutoRefresh',
@@ -205,7 +205,13 @@ define([
this.toggleFilterEmpty();
return this;
},
-
+
+ beforeClose: function () {
+ if (this.zeroClipboard) {
+ this.zeroClipboard.destroy();
+ }
+ },
+
floatMenuActive: false,
lastFloatMenuRowId: null,
lastFloatFocusInTextForEventUnmangling: null,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
index 0405ca7..7984fac 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
@@ -138,9 +138,10 @@ define([
if (this.problemIndicators) {
var indicatorText = _.values(this.problemIndicators);
- for (error in indicatorText) {
- if (problemDetails)
+ for (var error in indicatorText) {
+ if (problemDetails) {
problemDetails = problemDetails + "<br style='line-height: 24px;'>";
+ }
problemDetails = problemDetails + _.escape(indicatorText[error]);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/js/view/policy-new.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/policy-new.js b/usage/jsgui/src/main/webapp/assets/js/view/policy-new.js
index 3b88290..c190f78 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/policy-new.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/policy-new.js
@@ -26,7 +26,6 @@ define([
return Backbone.View.extend({
template: _.template(NewPolicyHtml),
- title: "Attach New Policy",
initialize: function () {
if (!this.options.entity) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/tpl/apps/add-child-modal.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/add-child-modal.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/add-child-modal.html
index 1f0f6af..53e7535 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/add-child-modal.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/add-child-modal.html
@@ -27,7 +27,7 @@ under the License.
<textarea id="child-spec" style="width: 100%; height: 120px;"/>
</div>
- <input type="checkbox" id="child-autostart" checked="checked"> Auto-start
+ <label><input type="checkbox" id="child-autostart" checked="checked"/> Auto-start </label>
<div class="hide alert alert-error child-add-error-container" style="margin-top: 9px;">
<strong>Error</strong>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/tpl/apps/advanced.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/advanced.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/advanced.html
index 52b71d0..c9f5f92 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/advanced.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/advanced.html
@@ -19,9 +19,8 @@ under the License.
-->
<div id="advanced-summary">
- <h3><span id="entity-name">Entity</span>
- <button id="change-name" class="btn pull-right">Change Name</button><br/>
- </h3>
+ <button id="change-name" class="btn pull-right">Change Name</button>
+ <h3><span id="entity-name">Entity</span></h3>
<div style="text-align: center; padding-top: 24px;">
<button id="add-child" class="btn">Add Child</button>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
index bf7d5a6..f249552 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
@@ -79,7 +79,7 @@ under the License.
<div id="entity-spec-yaml-toggler" class="toggler-region region-config hide" style="margin-top: 18px;">
<div class="toggler-header user-hidden">
<div class="toggler-icon icon-chevron-left"></div>
- <div><b>Blueprint YAML</b></div>
+ <div><b>Blueprint</b></div>
</div>
<div id="entity-spec-yaml" class="for-textarea hide">
<textarea readonly="readonly" style="width: 100%;"/>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/jsgui/src/test/javascript/specs/view/entity-details-spec.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/test/javascript/specs/view/entity-details-spec.js b/usage/jsgui/src/test/javascript/specs/view/entity-details-spec.js
index 46d5e59..3ca76ef 100644
--- a/usage/jsgui/src/test/javascript/specs/view/entity-details-spec.js
+++ b/usage/jsgui/src/test/javascript/specs/view/entity-details-spec.js
@@ -89,11 +89,6 @@ define([
view.render();
});
- // TODO textarea only appears if it's got yaml
-// it('must render textarea contents', function () {
-// expect(view.$("textarea").length).toBe(1);
-// expect(view.$("textarea").val()).toMatch("Tomcat");
-// });
});
// TODO complains about instanceof on a non-object in underscore; probably because we are now doing $.get
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-api/src/main/java/brooklyn/rest/api/EntityApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityApi.java
index 8d68b6b..f99ef18 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityApi.java
@@ -103,7 +103,7 @@ public interface EntityApi {
@ApiParam(name = "timeout", value = "Delay before server should respond with incomplete activity task, rather than completed task: " +
"'never' means block until complete; " +
"'0' means return task immediately; " +
- "and e.g. '20ms' (the default) will wait 20ms for copmleted task information to be available",
+ "and e.g. '20ms' (the default) will wait 20ms for completed task information to be available",
required = false, defaultValue = "20ms")
@QueryParam("timeout") final String timeout,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
index 58249a5..b299b73 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
@@ -100,7 +100,7 @@ public interface EntityConfigApi {
@Path("/{config}")
@ApiOperation(value = "Manually set a config value")
@ApiErrors(value = {
- @ApiError(code = 404, reason = "Could not find application, entity or sensor")
+ @ApiError(code = 404, reason = "Could not find application, entity or config key")
})
public void set(
@ApiParam(value = "Application ID or name", required = true)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-server/pom.xml
----------------------------------------------------------------------
diff --git a/usage/rest-server/pom.xml b/usage/rest-server/pom.xml
index 9379423..8483543 100644
--- a/usage/rest-server/pom.xml
+++ b/usage/rest-server/pom.xml
@@ -142,20 +142,6 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
-<!--
- <dependency>
- <groupId>org.eclipse.jetty.orbit</groupId>
- <artifactId>javax.servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.jaxrs</groupId>
- <artifactId>jackson-jaxrs-json-provider</artifactId>
- </dependency>
--->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
index 47faf3a..e1af603 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
@@ -22,12 +22,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.status;
import static javax.ws.rs.core.Response.Status.ACCEPTED;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
-import io.brooklyn.camp.spi.Assembly;
import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
@@ -52,8 +48,6 @@ import brooklyn.entity.Application;
import brooklyn.entity.Entity;
import brooklyn.entity.Group;
import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityLocal;
import brooklyn.entity.basic.Lifecycle;
import brooklyn.entity.trait.Startable;
import brooklyn.event.AttributeSensor;
@@ -64,6 +58,8 @@ import brooklyn.management.Task;
import brooklyn.management.entitlement.EntitlementPredicates;
import brooklyn.management.entitlement.Entitlements;
import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagementUtils.CreationResult;
import brooklyn.rest.api.ApplicationApi;
import brooklyn.rest.domain.ApplicationSpec;
import brooklyn.rest.domain.ApplicationSummary;
@@ -76,7 +72,6 @@ import brooklyn.rest.transform.TaskTransformer;
import brooklyn.rest.util.BrooklynRestResourceUtils;
import brooklyn.rest.util.WebResourceUtils;
import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.exceptions.Exceptions;
@@ -265,8 +260,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
}
log.debug("Creating app from yaml:\n{}", yaml);
- Reader input = new StringReader(yaml);
- AssemblyTemplate at = camp().pdp().registerDeploymentPlan(input);
+ AssemblyTemplate at = camp().pdp().registerDeploymentPlan( new StringReader(yaml) );
if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION, at)) {
throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
@@ -278,33 +272,20 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
private Response launch(AssemblyTemplate at) {
try {
- AssemblyTemplateInstantiator instantiator = at.getInstantiator().newInstance();
- Assembly assembly;
- Task<?> task = null;
- if (instantiator instanceof BrooklynAssemblyTemplateInstantiator) {
- Application app = ((BrooklynAssemblyTemplateInstantiator) instantiator).create(at, camp());
- assembly = camp().assemblies().get(app.getApplicationId());
-
- task = Entities.invokeEffector((EntityLocal)app, app, Startable.START,
- // locations already set in the entities themselves;
- // TODO make it so that this arg does not have to be supplied to START !
- MutableMap.of("locations", MutableList.of()));
- } else {
- assembly = instantiator.instantiate(at, camp());
- }
- Entity app = mgmt().getEntityManager().getEntity(assembly.getId());
+ CreationResult<? extends Application, Void> result = EntityManagementUtils.createStarting(mgmt(), at);
+ Application app = result.get();
if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, Startable.START.getName()))) {
throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
Entitlements.getEntitlementContext().user(), at.getType());
}
- log.info("Launched from YAML: " + assembly + " (" + task + ")");
+ log.info("Launched from YAML: " + at + " -> " + app + " (" + result.task() + ")");
URI ref = URI.create(app.getApplicationId());
ResponseBuilder response = created(ref);
- if (task != null)
- response.entity(TaskTransformer.FROM_TASK.apply(task));
+ if (result.task() != null)
+ response.entity(TaskTransformer.FROM_TASK.apply(result.task()));
return response.build();
} catch (Exception e) {
throw Exceptions.propagate(e);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
index 9792c28..ea3e4b7 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
@@ -43,11 +43,12 @@ import brooklyn.entity.basic.BrooklynTags;
import brooklyn.entity.basic.BrooklynTags.NamedStringTag;
import brooklyn.entity.basic.BrooklynTaskTags;
import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.effector.AddChildrenEffector;
import brooklyn.location.Location;
import brooklyn.management.Task;
import brooklyn.management.entitlement.EntitlementPredicates;
import brooklyn.management.entitlement.Entitlements;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagementUtils.CreationResult;
import brooklyn.rest.api.EntityApi;
import brooklyn.rest.domain.EntitySummary;
import brooklyn.rest.domain.LocationSummary;
@@ -115,11 +116,12 @@ public class EntityResource extends AbstractBrooklynRestResource implements Enti
throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'",
Entitlements.getEntitlementContext().user(), entityToken);
}
- AddChildrenEffector.AddChildrenResult added = AddChildrenEffector.addChildren(parent, yaml, start, timeoutS==null ? Duration.millis(20) : Duration.of(timeoutS));
+ CreationResult<List<Entity>, List<String>> added = EntityManagementUtils.addChildren(parent, yaml, start)
+ .blockUntilComplete(timeoutS==null ? Duration.millis(20) : Duration.of(timeoutS));
ResponseBuilder response;
- if (added.getChildren().size()==1) {
- Entity child = Iterables.getOnlyElement(added.getChildren());
+ if (added.get().size()==1) {
+ Entity child = Iterables.getOnlyElement(added.get());
URI ref = uriInfo.getBaseUriBuilder()
.path(EntityApi.class)
.path(EntityApi.class, "get")
@@ -128,7 +130,7 @@ public class EntityResource extends AbstractBrooklynRestResource implements Enti
} else {
response = Response.status(Status.CREATED);
}
- return response.entity(TaskTransformer.taskSummary(added.getTask())).build();
+ return response.entity(TaskTransformer.taskSummary(added.task())).build();
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b05a9c11/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
index 982dfc0..fc34f0e 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
@@ -116,7 +116,7 @@ public abstract class BrooklynRestApiTest {
protected void addDefaultResources() {
// seems we have to provide our own injector because the jersey test framework
// doesn't inject ServletConfig and it all blows up
-// addProvider(NullServletConfigProvider.class);
+ // and the servlet config provider must be an instance; addClasses doesn't work for some reason
addResource(new NullServletConfigProvider());
addProvider(NullHttpServletRequestProvider.class);
}