Skip to content
Permalink
Browse files
Support "externalised config" in catalog definition
  • Loading branch information
ivanayov committed Jan 11, 2016
1 parent dff3014 commit 18cce24fbb2493d91049c0cef650151252b2b652
Showing 2 changed files with 82 additions and 14 deletions.
@@ -25,6 +25,7 @@
import java.util.Map;

import com.google.common.collect.Iterables;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.ExecutionContext;
import org.apache.brooklyn.api.mgmt.ManagementContext;
@@ -33,7 +34,6 @@
import org.apache.brooklyn.core.config.external.AbstractExternalConfigSupplier;
import org.apache.brooklyn.core.config.external.ExternalConfigSupplier;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.mgmt.internal.CampYamlParser;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -53,15 +53,19 @@
public class ExternalConfigYamlTest extends AbstractYamlTest {
private static final Logger log = LoggerFactory.getLogger(ExternalConfigYamlTest.class);

private static final String OSGI_URL = "https://repository.apache.org/content/groups/snapshots/org/apache/brooklyn/brooklyn-core/0.9.0-SNAPSHOT/brooklyn-core-0.9.0-20160108.142251-126.jar";

@Override
protected LocalManagementContext newTestManagementContext() {
BrooklynProperties props = BrooklynProperties.Factory.newEmpty();
props.put("brooklyn.external.myprovider", MyExternalConfigSupplier.class.getName());
props.put("brooklyn.external.myprovider.mykey", "myval");
props.put("brooklyn.external.myprovider.osgikey", OSGI_URL);
props.put("brooklyn.external.myproviderWithoutMapArg", MyExternalConfigSupplierWithoutMapArg.class.getName());

return LocalManagementContextForTests.builder(true)
.useProperties(props)
.disableOsgi(false)
.build();
}

@@ -108,6 +112,60 @@ public void testExternalisedLocationConfigReferencedFromYaml() throws Exception
assertEquals(Iterables.getOnlyElement( app.getLocations() ).config().get(MY_CONFIG_KEY), "myval");
}

@Test
public void testExternalisedCatalogConfigReferencedFromYaml() throws Exception {

String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" id: osgi.test",
" itemType: template",
" version: 1.3",
" description: CentOS 6.6 With GUI - 1.3",
" displayName: CentOS 6.6",
" iconUrl: classpath:///centos.png",
" brooklyn.libraries:",
" - $brooklyn:external(\"myprovider\", \"osgikey\")",
"",
" item:",
" services:",
" - type: brooklyn.entity.database.mysql.MySqlNode");

catalog.addItems(yaml);

for (CatalogItem<Object, Object> item: catalog.getCatalogItems()) {
for (CatalogItem.CatalogBundle library: item.getLibraries()) {
assertEquals(library.getUrl(), OSGI_URL);
}
}
}

@Test
public void testNonExternalisedCatalogConfigReferencedFromYaml() throws Exception {

String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" id: osgi.test",
" itemType: template",
" version: 1.3",
" description: CentOS 6.6 With GUI - 1.3",
" displayName: CentOS 6.6",
" iconUrl: classpath:///centos.png",
" brooklyn.libraries:",
" - " + OSGI_URL,
"",
" item:",
" services:",
" - type: brooklyn.entity.database.mysql.MySqlNode");

catalog.addItems(yaml);

for (CatalogItem<Object, Object> item: catalog.getCatalogItems()) {
for (CatalogItem.CatalogBundle library: item.getLibraries()) {
assertEquals(library.getUrl(), OSGI_URL);
}
}
}

@Test(groups="Integration")
public void testExternalisedLocationConfigSetViaProvisioningPropertiesReferencedFromYaml() throws Exception {
String yaml = Joiner.on("\n").join(
@@ -41,12 +41,14 @@
import org.apache.brooklyn.core.catalog.CatalogPredicates;
import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
import org.apache.brooklyn.core.location.BasicLocationRegistry;
import org.apache.brooklyn.core.mgmt.internal.CampYamlParser;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.AggregateClassLoader;
@@ -360,8 +362,8 @@ private Maybe<Map<?,?>> getFirstAsMap(Map<?,?> map, String firstKey, String ...o
}

private List<CatalogItemDtoAbstract<?,?>> collectCatalogItems(String yaml) {
Map<?,?> itemDef = Yamls.getAs(Yamls.parseAll(yaml), Map.class);
Map<?,?> catalogMetadata = getFirstAsMap(itemDef, "brooklyn.catalog").orNull();
Map<String,?> itemDef = Yamls.getAs(Yamls.parseAll(yaml), Map.class);
Map<String,Object> catalogMetadata = (Map<String, Object>) getFirstAsMap(itemDef, "brooklyn.catalog").orNull();
if (catalogMetadata==null)
log.warn("No `brooklyn.catalog` supplied in catalog request; using legacy mode for "+itemDef);
catalogMetadata = MutableMap.copyOf(catalogMetadata);
@@ -376,7 +378,7 @@ private List<CatalogItemDtoAbstract<?,?>> collectCatalogItems(String yaml) {
catalogMetadata.remove("items");
if (!itemDef.isEmpty()) {
log.debug("Reading brooklyn.catalog peer keys as item ('top-level syntax')");
Map<String,?> rootItem = MutableMap.of("item", itemDef);
Map<String,Object> rootItem = MutableMap.of("item", (Object) itemDef);
String rootItemYaml = yaml;
YamlExtract yamlExtract = Yamls.getTextOfYamlAtPath(rootItemYaml, "brooklyn.catalog");
String match = yamlExtract.withOriginalIndentation(true).withKeyIncluded(true).getMatchedYamlTextOrWarn();
@@ -391,18 +393,26 @@ private List<CatalogItemDtoAbstract<?,?>> collectCatalogItems(String yaml) {
}

@SuppressWarnings("unchecked")
private void collectCatalogItems(String sourceYaml, Map<?,?> itemMetadata, List<CatalogItemDtoAbstract<?, ?>> result, Map<?,?> parentMetadata) {
private void collectCatalogItems(String sourceYaml, Map<?,?> itemMetadata, List<CatalogItemDtoAbstract<?, ?>> result, Map<String,?> parentMetadata) {

if (sourceYaml==null) sourceYaml = new Yaml().dump(itemMetadata);

Map<Object,Object> catalogMetadata = MutableMap.builder().putAll(parentMetadata).putAll(itemMetadata).build();

itemMetadata = mgmt.getConfig().getConfig(CampYamlParser.YAML_PARSER_KEY).parse((Map<String, Object>) itemMetadata);

try {
itemMetadata = (Map<String, Object>) Tasks.resolveDeepValue(itemMetadata, Object.class, mgmt.getServerExecutionContext());
} catch (Exception e) {
throw Exceptions.propagate(e);
}

Map<String,Object> catalogMetadata = MutableMap.<String, Object>builder().putAll(parentMetadata).putAll((Map<? extends String, ?>) itemMetadata).build();

// brooklyn.libraries we treat specially, to append the list, with the child's list preferred in classloading order
// `libraries` is supported in some places as a legacy syntax; it should always be `brooklyn.libraries` for new apps
// TODO in 0.8.0 require brooklyn.libraries, don't allow "libraries" on its own
List<?> librariesNew = MutableList.copyOf(getFirstAs(itemMetadata, List.class, "brooklyn.libraries", "libraries").orNull());
Collection<CatalogBundle> libraryBundlesNew = CatalogItemDtoAbstract.parseLibraries(librariesNew);

List<?> librariesCombined = MutableList.copyOf(librariesNew)
.appendAll(getFirstAs(parentMetadata, List.class, "brooklyn.libraries", "libraries").orNull());
if (!librariesCombined.isEmpty())
@@ -432,8 +442,8 @@ private void collectCatalogItems(String sourceYaml, Map<?,?> itemMetadata, List<

if (items!=null) {
int count = 0;
for (Map<?,?> i: ((List<Map<?,?>>)items)) {
collectCatalogItems(Yamls.getTextOfYamlAtPath(sourceYaml, "items", count).getMatchedYamlTextOrWarn(),
for (Map<?,?> i: ((List<Map<String,Object>>)items)) {
collectCatalogItems(Yamls.getTextOfYamlAtPath(sourceYaml, "items", count).getMatchedYamlTextOrWarn(),
i, result, catalogMetadata);
count++;
}
@@ -582,12 +592,12 @@ private String setFromItemIfUnset(String oldValue, Map<?,?> item, String fieldAt
return oldValue;
}

private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromLocal(ManagementContext mgmt, Map<Object, Object> catalogMetadata) {
private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromLocal(ManagementContext mgmt, Map<String, Object> catalogMetadata) {
CatalogDto dto = CatalogDto.newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the classpath", "scanning-local-classpath");
return scanAnnotationsInternal(mgmt, new CatalogDo(dto), catalogMetadata);
}

private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromBundles(ManagementContext mgmt, Collection<CatalogBundle> libraries, Map<Object, Object> catalogMetadata) {
private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromBundles(ManagementContext mgmt, Collection<CatalogBundle> libraries, Map<String, Object> catalogMetadata) {
CatalogDto dto = CatalogDto.newNamedInstance("Bundles Scanned Catalog", "All annotated Brooklyn entities detected in bundles", "scanning-bundles-classpath-"+libraries.hashCode());
List<String> urls = MutableList.of();
for (CatalogBundle b: libraries) {
@@ -608,7 +618,7 @@ private String setFromItemIfUnset(String oldValue, Map<?,?> item, String fieldAt
return scanAnnotationsInternal(mgmt, subCatalog, catalogMetadata);
}

private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInternal(ManagementContext mgmt, CatalogDo subCatalog, Map<Object, Object> catalogMetadata) {
private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInternal(ManagementContext mgmt, CatalogDo subCatalog, Map<String, Object> catalogMetadata) {
// TODO this does java-scanning only;
// the call when scanning bundles should use the CatalogItem instead and use OSGi when loading for scanning
// (or another scanning mechanism). see comments on CatalogClasspathDo.load
@@ -989,7 +999,7 @@ public CatalogItem<T,SpecT> apply(@Nullable CatalogItemDo<T,SpecT> item) {
};
}

private static <T,SpecT> Function<CatalogItemDo<T, SpecT>, CatalogItem<T,SpecT>> itemDoToDtoAddingSelectedMetadataDuringScan(final Map<Object, Object> catalogMetadata) {
private static <T,SpecT> Function<CatalogItemDo<T, SpecT>, CatalogItem<T,SpecT>> itemDoToDtoAddingSelectedMetadataDuringScan(final Map<String, Object> catalogMetadata) {
return new Function<CatalogItemDo<T,SpecT>, CatalogItem<T,SpecT>>() {
@Override
public CatalogItem<T,SpecT> apply(@Nullable CatalogItemDo<T,SpecT> item) {

0 comments on commit 18cce24

Please sign in to comment.