blob: 561578acdac24965e9a164a81a0204bec33a6afe [file] [log] [blame]
/*
* 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 org.apache.brooklyn.camp.brooklyn;
import org.apache.brooklyn.camp.brooklyn.TestSensorAndEffectorInitializerBase.TestConfigurableInitializerConfigBag;
import org.apache.brooklyn.camp.brooklyn.TestSensorAndEffectorInitializerBase.TestConfigurableInitializerOld;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.camp.brooklyn.catalog.CatalogYamlLocationTest;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
import org.apache.brooklyn.core.test.policy.TestEnricher;
import org.apache.brooklyn.core.test.policy.TestPolicy;
import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.test.Asserts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@Test
public class ApplicationsYamlTest extends AbstractYamlTest {
private static final Logger log = LoggerFactory.getLogger(ApplicationsYamlTest.class);
@Test
public void testWrapsEntity() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- type: " + BasicEntity.class.getName());
assertWrapped(app, BasicEntity.class);
}
@Test
public void testWrapsMultipleApps() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- type: " + BasicApplication.class.getName(),
"- type: " + BasicApplication.class.getName());
assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
assertTrue(app instanceof BasicApplication);
assertEquals(app.getChildren().size(), 2);
}
@Test
public void testWrapsWhenEnrichers() throws Exception {
Entity app = createAndStartApplication(
"brooklyn.enrichers:",
"- type: " + TestEnricher.class.getName(),
"services:",
"- type: " + BasicApplication.class.getName());
assertWrapped(app, BasicApplication.class);
}
@Test
public void testWrapsWhenPolicy() throws Exception {
Entity app = createAndStartApplication(
"brooklyn.policies:",
"- type: " + TestPolicy.class.getName(),
"services:",
"- type: " + BasicApplication.class.getName());
assertWrapped(app, BasicApplication.class);
}
@Test
public void testWrapsWhenInitializer() throws Exception {
Entity app = createAndStartApplication(
"brooklyn.initializers:",
"- type: " + TestConfigurableInitializerConfigBag.class.getName(),
"services:",
"- type: " + BasicApplication.class.getName());
assertWrapped(app, BasicApplication.class);
}
@Test
public void testWrapsAppIfForced() throws Exception {
Entity app = createAndStartApplication(
"wrappedApp: true",
"services:",
"- type: " + BasicApplication.class.getName());
assertWrapped(app, BasicApplication.class);
}
@Test
public void testDoesNotWrapApp() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- type: " + BasicApplication.class.getName());
assertDoesNotWrap(app, BasicApplication.class, null);
}
@Test
public void testDoesNotWrapAppIfUnforced() throws Exception {
Entity app = createAndStartApplication(
"wrappedApp: false",
"services:",
"- type: " + BasicApplication.class.getName());
assertDoesNotWrap(app, BasicApplication.class, null);
}
@Test
public void testUnwrappingIfDifferentTopLevelName() throws Exception {
Entity app = createAndStartApplication(
"name: topLevel",
"services:",
"- type: " + BasicApplication.class.getName(),
" name: bottomLevel");
if (EntityManagementUtils.DIFFERENT_NAME_BLOCKS_UNWRAPPING) {
assertWrapped(app, BasicApplication.class);
} else {
assertDoesNotWrap(app, BasicApplication.class, "topLevel");
}
}
@Test
public void testDoesNotWrapsEntityIfNoNameOnService() throws Exception {
Entity app = createAndStartApplication(
"name: topLevel",
"services:",
"- type: " + BasicApplication.class.getName());
assertDoesNotWrap(app, BasicApplication.class, "topLevel");
}
@Test
public void testDoesNotWrapCatalogItemWithDisplayName() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" displayName: catalogLevel",
" item:",
" type: " + BasicApplication.class.getName());
Entity app = createAndStartApplication(
"name: topLevel",
"services:",
"- type: simple:" + TEST_VERSION);
assertDoesNotWrap(app, BasicApplication.class, "topLevel");
}
@Test
public void testDoesNotWrapCatalogItemWithServiceName() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" displayName: catalogLevel",
" item:",
" type: " + BasicApplication.class.getName(),
" defaultDisplayName: defaultServiceName",
" displayName: explicitServiceName");
Entity app = createAndStartApplication(
"name: topLevel",
"services:",
"- type: simple:" + TEST_VERSION);
assertDoesNotWrap(app, BasicApplication.class, "topLevel");
}
@Test
public void testDoesNotWrapCatalogItemAndOverridesName() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" displayName: catalogLevel",
" item:",
" type: " + BasicApplication.class.getName());
Entity app = createAndStartApplication(
"services:",
"- type: simple:" + TEST_VERSION,
" name: serviceLevel");
assertDoesNotWrap(app, BasicApplication.class, "serviceLevel");
}
@Test
public void testDoesNotWrapCatalogItemAndUsesCatalogName() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" displayName: catalogLevel",
" item:",
" type: " + BasicApplication.class.getName());
Entity app = createAndStartApplication(
"services:",
"- type: simple:" + TEST_VERSION);
assertDoesNotWrap(app, BasicApplication.class, "catalogLevel");
}
@Test
public void testDoesNotWrapCatalogItemAndUsesCatalogServiceName() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" displayName: catalogLevel",
" item:",
" type: " + BasicApplication.class.getName(),
" name: catalogServiceLevel");
Entity app = createAndStartApplication(
"services:",
"- type: simple:" + TEST_VERSION);
assertDoesNotWrap(app, BasicApplication.class, "catalogServiceLevel");
}
@Test
public void testUnwrappedChildNotTagged() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: simple",
" version: " + TEST_VERSION,
" itemType: entity",
" item:",
" type: " + BasicEntity.class.getName());
Entity app = createAndStartApplication(
"services:",
"- type: simple:" + TEST_VERSION);
Entity entity = Iterables.getOnlyElement(app.getChildren());
assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
// Note that "brooklyn.wrapper_app" will still make it into
// ((EntityInternal) entity).config().getBag().getAllConfigAsConfigKeyMap();
// so the UI will still show the marker as inherited by the entity.
}
// FIXME Fails with name "My App 1" rather than the overridden value.
// See discussion in https://issues.apache.org/jira/browse/BROOKLYN-248
@Test(groups="WIP")
public void testTypeInheritance() throws Exception {
String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" items:",
" - id: app1",
" name: My App 1",
" item:",
" type: " + BasicApplication.class.getName(),
" brooklyn.config:",
" mykey1: myval1",
" mykey1b: myval1b",
" - id: app2",
" name: My App 2",
" item:",
" type: app1",
" brooklyn.config:",
" mykey1: myvalOverridden",
" mykey2: myval2");
addCatalogItems(yaml);
Entity app1 = createAndStartApplication("services: [ {type: app1} ]");
assertDoesNotWrap(app1, BasicApplication.class, "My App 1");
CatalogYamlLocationTest.assertContainsAll(((EntityInternal)app1).config().getBag().getAllConfig(), ImmutableMap.of("mykey1", "myval1", "mykey1b", "myval1b"));
Entity app2 = createAndStartApplication("services: [ {type: app2} ]");
// assertDoesNotWrap(app2, BasicApplication.class, "My App 2");
// TODO see comment on testNamePrecendance, should be My App 2
assertDoesNotWrap(app2, BasicApplication.class, "My App 1");
CatalogYamlLocationTest.assertContainsAll(((EntityInternal)app2).config().getBag().getAllConfig(), ImmutableMap.of("mykey1", "myvalOverridden", "mykey1b", "myval1b", "mykey2", "myval2"));
}
@Test
public void testNamePrecedence() throws Exception {
String yaml1 = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" name: My name in top-level metadata",
" items:",
" - id: app1",
" name: My name in item metadata",
" item:",
" type: " + BasicApplication.class.getName(),
" name: My name within item");
String yaml2 = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" name: My name in top-level metadata",
" items:",
" - id: app2",
" item:",
" type: " + BasicApplication.class.getName(),
" name: My name within item");
String yaml3 = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" items:",
" - id: app3a",
" name: My name in item 3a metadata",
" item:",
" type: " + BasicApplication.class.getName(),
" name: My name within item 3a",
" items:",
" - id: app3b",
" item:",
" type: app3a",
" name: My name within item 3b");
addCatalogItems(yaml1);
addCatalogItems(yaml2);
addCatalogItems(yaml3);
Entity app1 = createAndStartApplication("services: [ {type: app1} ]");
assertDoesNotWrap(app1, BasicApplication.class, "My name within item");
Entity app2 = createAndStartApplication("services: [ {type: app2} ]");
assertDoesNotWrap(app2, BasicApplication.class, "My name within item");
Entity app3b = createAndStartApplication("services: [ {type: app3b} ]");
// assertDoesNotWrap(app3b, BasicApplication.class, "My name within item 3b");
// FIXME Above is what is expected, not below
// Old discussion in https://issues.apache.org/jira/browse/BROOKLYN-248
// Update 2022-10 -- name, and blueprinting, handling is curious. app3b has plan `services: [ { type: BasicApplication } ]`,
// no reference to app3a, and no reference to either names. the names are handled _only_ in metadata,
// and name from metadata passed via AbstractEntity.DEFAULT_DISPLAY_NAME.
assertDoesNotWrap(app3b, BasicApplication.class, "My name within item 3a");
}
@Test
public void testNameInCatalogMetadata() throws Exception {
String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" name: My name in top-level",
" items:",
" - id: app1",
" item:",
" type: " + BasicApplication.class.getName());
addCatalogItems(yaml);
Entity app1 = createAndStartApplication("services: [ {type: app1} ]");
assertDoesNotWrap(app1, BasicApplication.class, "My name in top-level");
}
@Test
public void testNameInItemMetadata() throws Exception {
String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" items:",
" - id: app1",
" name: My name in item metadata",
" item:",
" type: " + BasicApplication.class.getName());
addCatalogItems(yaml);
Entity app1 = createAndStartApplication("services: [ {type: app1} ]");
assertDoesNotWrap(app1, BasicApplication.class, "My name in item metadata");
}
@Test
public void testNameWithinItem() throws Exception {
String yaml = Joiner.on("\n").join(
"brooklyn.catalog:",
" version: 0.1.2",
" itemType: entity",
" items:",
" - id: app1",
" item:",
" type: " + BasicApplication.class.getName(),
" name: My name within item");
addCatalogItems(yaml);
Entity app1 = createAndStartApplication("services: [ {type: app1} ]");
assertDoesNotWrap(app1, BasicApplication.class, "My name within item");
}
@Test
/** Tests catalog.bom format where service is defined alongside brooklyn.catalog, IE latter has no item/items */
public void testItemFromServicesSectionInCatalog() {
addCatalogItems(
"brooklyn.catalog:",
" id: simple-test",
" version: "+TEST_VERSION,
"services:",
"- type: org.apache.brooklyn.entity.stock.BasicEntity");
Iterable<RegisteredType> retrievedItems = mgmt().getTypeRegistry()
.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo("simple-test")));
Asserts.assertSize(retrievedItems, 1);
Assert.assertEquals(Iterables.getOnlyElement(retrievedItems).getVersion(), TEST_VERSION);
}
@Test
public void testGoodErrorFromServicesEvenWhenEnricherBlockOkay() throws Exception {
Asserts.assertFailsWith(() -> {
addCatalogItems(
"brooklyn.catalog:",
" id: simple-test",
" version: " + TEST_VERSION,
"brooklyn.enrichers:",
"- type: " + TestEnricher.class.getName(),
"services:",
"- type: not_a_real_service");
RegisteredType t = mgmt().getTypeRegistry().get("simple-test", TEST_VERSION);
return t+" - "+t.getSuperTypes();
},
e -> Asserts.expectedFailureContains(e, "not_a_real_service"));
}
@Test
public void testGoodErrorOnServicesBlockWithType() throws Exception {
Asserts.assertFailsWith(() -> {
addCatalogItems(
"brooklyn.catalog:",
" id: simple-test",
" version: " + TEST_VERSION,
"type: foo",
"services:",
"- type: "+BasicEntity.class.getName());
RegisteredType t = mgmt().getTypeRegistry().get("simple-test", TEST_VERSION);
return t+" - "+t.getSuperTypes();
},
e -> Asserts.expectedFailureContains(e, "Blueprint contains both a 'services' block and a 'type' specification"));
}
@Override
protected Logger getLogger() {
return log;
}
private void assertWrapped(Entity app, Class<? extends Entity> wrappedEntityType) {
assertEquals(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER), Boolean.TRUE);
assertTrue(app instanceof BasicApplication);
Entity child = Iterables.getOnlyElement(app.getChildren());
assertTrue(wrappedEntityType.isInstance(child));
assertTrue(child.getChildren().isEmpty());
}
private void assertDoesNotWrap(Entity app, Class<? extends Application> entityType, String displayName) {
assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
assertTrue(entityType.isInstance(app));
if (displayName != null) {
assertEquals(app.getDisplayName(), displayName);
}
assertEquals(app.getChildren().size(), 0);
}
@Test
public void testUnwrapsIfNoConflict() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- type: " + BasicApplication.class.getName(),
" name: serviceLevel",
" id: svc",
" brooklyn.config:",
" serviceConfig: svc",
"brooklyn.config:",
" rootConfig: root",
"");
assertDoesNotWrap(app, BasicApplication.class, "serviceLevel");
Asserts.assertEquals(app.config().get(ConfigKeys.newConfigKey(Object.class, "serviceConfig")), "svc");
Asserts.assertEquals(app.config().get(ConfigKeys.newConfigKey(Object.class, "rootConfig")), "root");
Asserts.assertEquals(app.config().get(BrooklynCampConstants.PLAN_ID), "svc");
}
@Test
public void testNoUnwrappingIfConflictingConfig() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- type: " + BasicApplication.class.getName(),
" name: serviceLevel",
" id: svc",
" brooklyn.config:",
" commonConfig: svc",
"brooklyn.config:",
" commonConfig: root",
"");
if (EntityManagementUtils.DIFFERENT_CONFIG_BLOCKS_UNWRAPPING) {
assertWrapped(app, BasicApplication.class);
Asserts.assertSize(app.getChildren(), 1);
Entity child = Iterables.getOnlyElement(app.getChildren());
Asserts.assertEquals(app.config().get(ConfigKeys.newConfigKey(Object.class, "commonConfig")), "root");
Asserts.assertEquals(child.config().get(ConfigKeys.newConfigKey(Object.class, "commonConfig")), "svc");
Asserts.assertNull(app.config().get(BrooklynCampConstants.PLAN_ID));
Asserts.assertEquals(child.config().get(BrooklynCampConstants.PLAN_ID), "svc");
} else {
assertDoesNotWrap(app, BasicApplication.class, null);
}
}
}