You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2014/07/09 23:47:01 UTC
[48/50] git commit: clean up how catalogs are created,
being clearer about URL vs contents,
and support resetting a catalog from a given XML definition,
with REST API endpoint. needed for a master brooklyn to push catalog changes
to a client brooklyn.
clean up how catalogs are created, being clearer about URL vs contents, and support resetting a catalog from a given XML definition, with REST API endpoint.
needed for a master brooklyn to push catalog changes to a client brooklyn.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/df48761c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/df48761c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/df48761c
Branch: refs/heads/master
Commit: df48761c5eba289c185d794e570a1446eeca5fd9
Parents: 450ce96
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Jul 9 11:44:16 2014 -0400
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Jul 9 22:34:47 2014 +0100
----------------------------------------------------------------------
.../catalog/internal/BasicBrooklynCatalog.java | 14 ++--
.../brooklyn/catalog/internal/CatalogDo.java | 2 +-
.../brooklyn/catalog/internal/CatalogDto.java | 62 +++++++++------
.../internal/AbstractManagementContext.java | 2 +-
.../brooklyn/camp/lite/CampYamlLiteTest.java | 81 ++++++++++++++------
.../main/java/brooklyn/rest/api/CatalogApi.java | 9 +++
.../rest/resources/CatalogResource.java | 7 ++
7 files changed, 123 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index b02993c..dfa966a 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -80,14 +80,10 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
}
private final ManagementContext mgmt;
- private final CatalogDo catalog;
+ private CatalogDo catalog;
private volatile CatalogDo manualAdditionsCatalog;
private volatile LoadedClassLoader manualAdditionsClasses;
- public BasicBrooklynCatalog(ManagementContext mgmt, String catalogUrl) {
- this(mgmt, CatalogDto.newDtoFromUrl(catalogUrl));
- }
-
public BasicBrooklynCatalog(final ManagementContext mgmt, final CatalogDto dto) {
this.mgmt = Preconditions.checkNotNull(mgmt, "managementContext");
this.catalog = new CatalogDo(mgmt, dto);
@@ -101,6 +97,14 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
}
}
+ public void reset(CatalogDto dto) {
+ CatalogDo catalog = new CatalogDo(mgmt, dto);
+ log.debug("Resetting "+this+" catalog to "+dto);
+ catalog.load(mgmt, null);
+ log.debug("Reloaded catalog for "+this+", now switching");
+ this.catalog = catalog;
+ }
+
public CatalogDo getCatalog() {
return catalog;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/core/src/main/java/brooklyn/catalog/internal/CatalogDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogDo.java b/core/src/main/java/brooklyn/catalog/internal/CatalogDo.java
index 125d39f..e5eba3d 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogDo.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogDo.java
@@ -90,7 +90,7 @@ public class CatalogDo {
log.warn("Catalog "+this+" being initialised with different mgmt "+mgmt+" when already managed by "+this.mgmt, new Throwable("source of reparented "+this));
this.parent = parent;
this.mgmt = mgmt;
- dto.populateFromUrl();
+ dto.populate();
loadCatalogClasspath();
loadCatalogItems();
isLoaded = true;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
index 272f331..d84b2f9 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
@@ -19,7 +19,7 @@
package brooklyn.catalog.internal;
import java.io.InputStream;
-import java.io.InputStreamReader;
+import java.io.StringReader;
import java.util.List;
import org.slf4j.Logger;
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
import brooklyn.util.ResourceUtils;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.exceptions.PropagatedRuntimeException;
+import brooklyn.util.stream.Streams;
import com.google.common.base.Objects;
@@ -36,7 +37,11 @@ public class CatalogDto {
private static final Logger LOG = LoggerFactory.getLogger(CatalogDto.class);
String id;
+ /** e.g. url */
String url;
+
+ String contents;
+ String contentsDescription;
String name;
String description;
CatalogClasspathDto classpath;
@@ -57,15 +62,22 @@ public class CatalogDto {
if (LOG.isDebugEnabled()) LOG.debug("Retrieving catalog from: {}", url);
try {
InputStream source = ResourceUtils.create().getResourceFromUrl(url);
- CatalogDto result = (CatalogDto) new CatalogXmlSerializer().deserialize(new InputStreamReader(source));
- if (LOG.isDebugEnabled()) LOG.debug("Retrieved catalog from: {}", url);
- return result;
+ String contents = Streams.readFullyString(source);
+ return newDtoFromXmlContents(contents, url);
} catch (Throwable t) {
Exceptions.propagateIfFatal(t);
throw new PropagatedRuntimeException("Unable to retrieve catalog from " + url + ": " + t, t);
}
}
+ public static CatalogDto newDtoFromXmlContents(String xmlContents, String originDescription) {
+ CatalogDto result = (CatalogDto) new CatalogXmlSerializer().deserialize(new StringReader(xmlContents));
+ result.contentsDescription = originDescription;
+
+ if (LOG.isDebugEnabled()) LOG.debug("Retrieved catalog from: {}", originDescription);
+ return result;
+ }
+
public static CatalogDto newNamedInstance(String name, String description) {
CatalogDto result = new CatalogDto();
result.name = name;
@@ -75,9 +87,29 @@ public class CatalogDto {
public static CatalogDto newLinkedInstance(String url) {
CatalogDto result = new CatalogDto();
- result.url = url;
+ result.contentsDescription = url;
+ result.contents = ResourceUtils.create().getResourceAsString(url);
return result;
}
+
+ void populate() {
+ if (contents==null) {
+ if (url != null) {
+ contents = ResourceUtils.create().getResourceAsString(url);
+ contentsDescription = url;
+ } else {
+ LOG.warn("Catalog DTO has no contents); ignoring call to populate it.");
+ return;
+ }
+ }
+
+ CatalogDto remoteDto = newDtoFromXmlContents(contents, contentsDescription);
+ try {
+ copyFrom(remoteDto, true);
+ } catch (Exception e) {
+ Exceptions.propagate(e);
+ }
+ }
/**
* @throws NullPointerException If source is null (and !skipNulls)
@@ -89,35 +121,21 @@ public class CatalogDto {
}
if (!skipNulls || source.id != null) id = source.id;
- if (!skipNulls || source.url != null) url = source.url;
+ if (!skipNulls || source.contentsDescription != null) contentsDescription = source.contentsDescription;
+ if (!skipNulls || source.contents != null) contents = source.contents;
if (!skipNulls || source.name != null) name = source.name;
if (!skipNulls || source.description != null) description = source.description;
if (!skipNulls || source.classpath != null) classpath = source.classpath;
if (!skipNulls || source.entries != null) entries = source.entries;
}
- /**
- * Populates this Dto by loading the catalog at its {@link #url}. Takes no action if url is null.
- * Throws if there are any problems in retrieving or copying from url.
- */
- void populateFromUrl() {
- if (url != null) {
- CatalogDto remoteDto = newDtoFromUrl(url);
- try {
- copyFrom(remoteDto, true);
- } catch (Exception e) {
- Exceptions.propagate(e);
- }
- }
- }
-
@Override
public String toString() {
return Objects.toStringHelper(this)
.omitNullValues()
.add("name", name)
.add("id", id)
- .add("url", url)
+ .add("contentsDescription", contentsDescription)
.toString();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index 55399cd..860e5d4 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -334,7 +334,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
try {
if (!Strings.isEmpty(catalogUrl)) {
- catalog = new BasicBrooklynCatalog(this, catalogUrl);
+ catalog = new BasicBrooklynCatalog(this, CatalogDto.newDtoFromUrl(catalogUrl));
if (log.isDebugEnabled())
log.debug("Loaded catalog from "+catalogUrl+": "+catalog);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
index 3694350..0e081cf 100644
--- a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
+++ b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
@@ -40,6 +40,8 @@ import org.testng.annotations.Test;
import brooklyn.catalog.CatalogItem;
import brooklyn.catalog.CatalogPredicates;
+import brooklyn.catalog.internal.BasicBrooklynCatalog;
+import brooklyn.catalog.internal.CatalogDto;
import brooklyn.entity.Entity;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.management.internal.LocalManagementContext;
@@ -132,8 +134,15 @@ public class CampYamlLiteTest {
public void testRegisterCustomEntityWithBundleWhereEntityIsFromCoreAndIconFromBundle() throws IOException {
String registeredTypeName = "my.catalog.app.id";
String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
- String yaml =
- "brooklyn.catalog:\n"+
+ String yaml = getSampleMyCatalogAppYaml(registeredTypeName, bundleUrl);
+
+ mgmt.getCatalog().addItem(yaml);
+
+ assertMgmtHasSampleMyCatalogApp(registeredTypeName, bundleUrl);
+ }
+
+ private String getSampleMyCatalogAppYaml(String registeredTypeName, String bundleUrl) {
+ return "brooklyn.catalog:\n"+
" id: " + registeredTypeName + "\n"+
" name: My Catalog App\n"+
" description: My description\n"+
@@ -144,31 +153,53 @@ public class CampYamlLiteTest {
"\n"+
"services:\n"+
"- type: brooklyn.test.entity.TestEntity\n";
+ }
- mgmt.getCatalog().addItem(yaml);
-
- CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(registeredTypeName);
- assertEquals(item.getRegisteredTypeName(), registeredTypeName);
-
- // stored as yaml, not java
+ private void assertMgmtHasSampleMyCatalogApp(String registeredTypeName, String bundleUrl) {
+ CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(registeredTypeName);
+ assertEquals(item.getRegisteredTypeName(), registeredTypeName);
+
+ // stored as yaml, not java
// assertEquals(entityItem.getJavaType(), "brooklyn.test.entity.TestEntity");
- Assert.assertNotNull(item.getPlanYaml());
- Assert.assertTrue(item.getPlanYaml().contains("brooklyn.test.entity.TestEntity"));
-
- assertEquals(item.getId(), registeredTypeName);
-
- // and let's check we have libraries
- List<String> libs = item.getLibraries().getBundles();
- assertEquals(libs, MutableList.of(bundleUrl));
-
- // now let's check other things on the item
- assertEquals(item.getName(), "My Catalog App");
- assertEquals(item.getDescription(), "My description");
- assertEquals(item.getIconUrl(), "classpath:/brooklyn/osgi/tests/icon.gif");
-
- // and confirm we can resolve ICON
- byte[] iconData = Streams.readFully( ResourceUtils.create(item.newClassLoadingContext(mgmt)).getResourceFromUrl(item.getIconUrl()) );
- assertEquals(iconData.length, 43);
+ Assert.assertNotNull(item.getPlanYaml());
+ Assert.assertTrue(item.getPlanYaml().contains("brooklyn.test.entity.TestEntity"));
+
+ assertEquals(item.getId(), registeredTypeName);
+
+ // and let's check we have libraries
+ List<String> libs = item.getLibraries().getBundles();
+ assertEquals(libs, MutableList.of(bundleUrl));
+
+ // now let's check other things on the item
+ assertEquals(item.getName(), "My Catalog App");
+ assertEquals(item.getDescription(), "My description");
+ assertEquals(item.getIconUrl(), "classpath:/brooklyn/osgi/tests/icon.gif");
+
+ // and confirm we can resolve ICON
+ byte[] iconData = Streams.readFully( ResourceUtils.create(item.newClassLoadingContext(mgmt)).getResourceFromUrl(item.getIconUrl()) );
+ assertEquals(iconData.length, 43);
}
+
+ @Test
+ public void testResetXmlWithCustomEntity() throws IOException {
+ String registeredTypeName = "my.catalog.app.id";
+ String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
+ String yaml = getSampleMyCatalogAppYaml(registeredTypeName, bundleUrl);
+
+ LocalManagementContextForTests mgmt2 = new LocalManagementContextForTests();
+ try {
+ CampPlatformWithJustBrooklynMgmt platform2 = new CampPlatformWithJustBrooklynMgmt(mgmt2);
+ MockWebPlatform.populate(platform2, TestAppAssemblyInstantiator.class);
+
+ mgmt2.getCatalog().addItem(yaml);
+ String xml = ((BasicBrooklynCatalog)mgmt2.getCatalog()).toXmlString();
+ ((BasicBrooklynCatalog)mgmt.getCatalog()).reset(CatalogDto.newDtoFromXmlContents(xml, "copy of temporary catalog"));
+ } finally {
+ mgmt2.terminate();
+ }
+
+ assertMgmtHasSampleMyCatalogApp(registeredTypeName, bundleUrl);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
index f1f07b7..769c8b9 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
@@ -58,6 +58,15 @@ public interface CatalogApi {
@Valid String yaml
) ;
+ @POST
+ @Consumes(MediaType.APPLICATION_XML)
+ @Path("/reset")
+ @ApiOperation(value = "Resets the catalog to the given (XML) format")
+ public Response resetXml(
+ @ApiParam(name = "xml", value = "XML descriptor of the entire catalog to install", required = true)
+ @Valid String xml
+ ) ;
+
@DELETE
@Path("/entities/{entityId}")
@ApiOperation(value = "Deletes an entity's definition from the catalog")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/df48761c/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
index a575d37..b6323a5 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
@@ -35,6 +35,8 @@ import org.slf4j.LoggerFactory;
import brooklyn.catalog.CatalogItem;
import brooklyn.catalog.CatalogPredicates;
+import brooklyn.catalog.internal.BasicBrooklynCatalog;
+import brooklyn.catalog.internal.CatalogDto;
import brooklyn.entity.Entity;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.rest.api.CatalogApi;
@@ -98,6 +100,11 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
}
}
+ public Response resetXml(String xml) {
+ ((BasicBrooklynCatalog)mgmt().getCatalog()).reset(CatalogDto.newDtoFromXmlContents(xml, "REST reset"));
+ return Response.ok().build();
+ }
+
@Override
public void deleteEntity(String entityId) throws Exception {
CatalogItem<?,?> result = brooklyn().getCatalog().getCatalogItem(entityId);