in brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java [727:823]
private boolean attemptType(String key, CatalogItemType candidateCiType) {
if (resolved) return false;
if (catalogItemType!=null && catalogItemType!=candidateCiType) return false;
final String candidateYaml;
if (key==null) candidateYaml = itemYaml;
else {
if (item.containsKey(key))
candidateYaml = itemYaml;
else
candidateYaml = key + ":\n" + makeAsIndentedList(itemYaml);
}
// first look in collected items, if a key is given
String type = (String) item.get("type");
String version = null;
if (CatalogUtils.looksLikeVersionedId(type)) {
version = CatalogUtils.getVersionFromVersionedId(type);
type = CatalogUtils.getSymbolicNameFromVersionedId(type);
}
if (type!=null && key!=null) {
for (CatalogItemDtoAbstract<?,?> candidate: itemsDefinedSoFar) {
if (candidateCiType == candidate.getCatalogItemType() &&
(type.equals(candidate.getSymbolicName()) || type.equals(candidate.getId()))) {
if (version==null || version.equals(candidate.getVersion())) {
// matched - exit
catalogItemType = candidateCiType;
planYaml = candidateYaml;
resolved = true;
return true;
}
}
}
}
// then try parsing plan - this will use loader
try {
@SuppressWarnings("rawtypes")
CatalogItem itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
.plan(candidateYaml)
.libraries(libraryBundles)
.build();
@SuppressWarnings("unchecked")
AbstractBrooklynObjectSpec<?, ?> spec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true);
if (spec!=null) {
catalogItemType = candidateCiType;
planYaml = candidateYaml;
resolved = true;
}
return true;
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
// record the error if we have reason to expect this guess to succeed
if (item.containsKey("services") && (candidateCiType==CatalogItemType.ENTITY || candidateCiType==CatalogItemType.TEMPLATE)) {
// explicit services supplied, so plan should have been parseable for an entity or a a service
errors.add(e);
} else if (catalogItemType!=null && key!=null) {
// explicit itemType supplied, so plan should be parseable in the cases where we're given a key
// (when we're not given a key, the previous block should apply)
errors.add(e);
} else {
// all other cases, the error is probably due to us not getting the type right, probably ignore it
// but cache it if we've checked entity, we'll use that as fallback errors
if (candidateCiType==CatalogItemType.ENTITY) {
entityErrors.add(e);
}
if (log.isTraceEnabled())
log.trace("Guessing type of plan, it looks like it isn't "+candidateCiType+"/"+key+": "+e);
}
}
// finally try parsing a cut-down plan, in case there is a nested reference to a newly defined catalog item
if (type!=null && key!=null) {
try {
String cutDownYaml = key + ":\n" + makeAsIndentedList("type: "+type);
@SuppressWarnings("rawtypes")
CatalogItem itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
.plan(cutDownYaml)
.libraries(libraryBundles)
.build();
@SuppressWarnings("unchecked")
AbstractBrooklynObjectSpec<?, ?> cutdownSpec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true);
if (cutdownSpec!=null) {
catalogItemType = candidateCiType;
planYaml = candidateYaml;
resolved = true;
}
return true;
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
}
}
// FIXME we should lookup type in the catalog on its own, then infer the type from that,
// and give proper errors (right now e.g. if there are no transformers then we bail out
// with very little information)
return false;
}