http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java new file mode 100644 index 0000000..99830c9 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java @@ -0,0 +1,262 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertTrue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.annotations.Test; + +import brooklyn.basic.BrooklynTypes; + +import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; +import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher; +import org.apache.brooklyn.catalog.BrooklynCatalog; +import org.apache.brooklyn.catalog.CatalogItem; +import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType; +import brooklyn.catalog.internal.CatalogUtils; +import brooklyn.entity.Entity; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.LocationSpec; +import brooklyn.management.osgi.OsgiVersionMoreEntityTest; +import brooklyn.policy.Policy; +import brooklyn.policy.PolicySpec; +import org.apache.brooklyn.test.TestResourceUnavailableException; +import brooklyn.util.ResourceUtils; +import brooklyn.util.text.Strings; + +import com.google.common.collect.Iterables; + +/** Many of the same tests as per {@link OsgiVersionMoreEntityTest} but using YAML for catalog and entities, so catalog item ID is set automatically */ +public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest { + + private static final Logger log = LoggerFactory.getLogger(CatalogOsgiVersionMoreEntityTest.class); + + private static String getLocalResource(String filename) { + return ResourceUtils.create(CatalogOsgiVersionMoreEntityTest.class).getResourceAsString( + "classpath:/"+CatalogOsgiVersionMoreEntityTest.class.getPackage().getName().replace('.', '/')+"/"+filename); + } + + @Test + public void testMoreEntityV1() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar"); + + addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml")); + CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity"); + Assert.assertNotNull(item); + Assert.assertEquals(item.getVersion(), "1.0"); + Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY); + Assert.assertEquals(item.getLibraries().size(), 1); + + Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0"); + OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity); + OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity); + } + + /** TODO we get warnings from {@link BrooklynEntityMatcher#extractValidConfigFlagsOrKeys}; + * if we passed the correct loader at that point we could avoid those warnings. */ + @Test + public void testMoreEntityV1WithPolicy() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("simple-policy-osgi-catalog.yaml")); + addCatalogItems(getLocalResource("more-entity-v1-with-policy-osgi-catalog.yaml")); + Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0"); + + Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies()); + Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies()); + // it was loaded by yaml w ref to catalog, so should have the simple-policy catalog-id + Assert.assertEquals(policy.getCatalogItemId(), "simple-policy:1.0"); + } + + @Test + public void testMoreEntityV2() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml")); + Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0"); + OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity); + OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity); + + Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies()); + Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies()); + // it was loaded from the java so should have the base more-entity catalog id + Assert.assertEquals(policy.getCatalogItemId(), "more-entity:1.0"); + } + + @Test + /** TODO this test works if we assume most recent version wins, but semantics TBC */ + public void testMoreEntityV2ThenV1GivesV1() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml")); + forceCatalogUpdate(); + addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml")); + Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity); + OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity); + } + + /** unlike {@link #testMoreEntityV2ThenV1GivesV1()} this test should always work, + * because default should probably be either most-recent version or highest version, + * in either case this works */ + @Test + public void testMoreEntityV1ThenV2GivesV2() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml")); + forceCatalogUpdate(); + addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml")); + Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity); + OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity); + } + + @Test + public void testMoreEntityBothV1AndV2() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entity-v1-called-v1-osgi-catalog.yaml")); + addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml")); + Entity v1 = createAndStartApplication("services: [ { type: 'more-entity-v1:1.0' } ]"); + Entity v2 = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]"); + + Entity moreEntityV1 = Iterables.getOnlyElement(v1.getChildren()); + Entity moreEntityV2 = Iterables.getOnlyElement(v2.getChildren()); + + OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntityV1); + OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntityV1); + + OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntityV2); + OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntityV2); + } + + // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161 + public void testMoreEntityV2AutoscanWithClasspath() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml")); + + log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", ")); + + CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity"); + Assert.assertNotNull(item); + Assert.assertEquals(item.getVersion(), "2.0.test"); + Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY); + + // this refers to the java item, where the libraries are defined + item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MoreEntity"); + Assert.assertEquals(item.getVersion(), "2.0.test_java"); + Assert.assertEquals(item.getLibraries().size(), 2); + + Entity app = createAndStartApplication("services: [ { type: 'more-entity:2.0.test' } ]"); + Entity moreEntity = Iterables.getOnlyElement(app.getChildren()); + + Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:2.0.test"); + OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity); + OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity); + } + + // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161 + public void testMorePolicyV2AutoscanWithClasspath() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-policies-osgi-catalog-scan.yaml")); + + log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", ")); + + CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-policy"); + Assert.assertNotNull(item); + Assert.assertEquals(item.getVersion(), "2.0.test"); + Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.POLICY); + + // this refers to the java item, where the libraries are defined + item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MorePolicy"); + Assert.assertEquals(item.getVersion(), "2.0.test_java"); + Assert.assertEquals(item.getLibraries().size(), 2); + + Entity app = createAndStartApplication( + "services: ", + "- type: brooklyn.entity.basic.BasicEntity", + " brooklyn.policies:", + " - type: more-policy:2.0.test"); + Entity basicEntity = Iterables.getOnlyElement(app.getChildren()); + Policy morePolicy = Iterables.getOnlyElement(basicEntity.getPolicies()); + + Assert.assertEquals(morePolicy.getCatalogItemId(), "more-policy:2.0.test"); + OsgiVersionMoreEntityTest.assertV2MethodCall(morePolicy); + } + + // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161 + public void testAutoscanWithClasspathCanCreateSpecs() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar"); + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar"); + + addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml")); + + log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", ")); + + BrooklynCatalog catalog = mgmt().getCatalog(); + Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(); + for (CatalogItem<Object, Object> item: items) { + Object spec = catalog.createSpec(item); + switch (item.getCatalogItemType()) { + case TEMPLATE: + case ENTITY: + assertTrue(spec instanceof EntitySpec, "Not an EntitySpec: " + spec); + BrooklynTypes.getDefinedEntityType(((EntitySpec<?>)spec).getType()); + break; + case POLICY: + assertTrue(spec instanceof PolicySpec, "Not a PolicySpec: " + spec); + BrooklynTypes.getDefinedBrooklynType(((PolicySpec<?>)spec).getType()); + break; + case LOCATION: + assertTrue(spec instanceof LocationSpec, "Not a LocationSpec: " + spec); + BrooklynTypes.getDefinedBrooklynType(((LocationSpec<?>)spec).getType()); + break; + } + } + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java new file mode 100644 index 0000000..fc2c7e5 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java @@ -0,0 +1,37 @@ +/* + * 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.catalog; + +import org.testng.annotations.Test; + +public class CatalogXmlOsgiTest extends AbstractCatalogXmlTest { + + public CatalogXmlOsgiTest(String catalogUrl) { + super("classpath://osgi-catalog.xml"); + } + + //OSGi libraries not supported with old-style catalog items + //We treat those catalog items just as an alias to the java type they hold. + //No loader wrapping their libraries is ever created. + @Test(expectedExceptions=IllegalStateException.class) + public void testOsgiItem() throws Exception { + startApp("OsgiApp"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java new file mode 100644 index 0000000..4bed94d --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java @@ -0,0 +1,58 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import brooklyn.entity.Entity; + +public class CatalogXmlVersionTest extends AbstractCatalogXmlTest { + + public CatalogXmlVersionTest(String catalogUrl) { + super("classpath://simple-catalog.xml"); + } + + @DataProvider(name = "types") + public Object[][] createTypes() { + return new Object[][] { + {"brooklyn.entity.basic.BasicApplication"}, + {"brooklyn.entity.basic.BasicApplication:0.0.0.SNAPSHOT"}, + {"brooklyn.entity.basic.BasicApplication:2.0"}, + {"BasicApp"}, // test that items with symbolicName not matching the type work + {"BasicApp:0.0.0.SNAPSHOT"}, + {"BasicApp:2.0"}, + {"brooklyn.osgi.tests.SimpleApplication"}, //test that classpath is used + }; + } + + @Test(dataProvider = "types") + public void testXmlCatalogItem(String type) throws Exception { + startApp(type); + } + + @Test + public void testJavaPrefixDoesNotLoadXMLCatalogItem() throws Exception { + Entity entity = startApp("java:org.apache.brooklyn.camp.brooklyn.catalog.TestBasicApp"); + assertTrue(entity instanceof TestBasicApp, "Entity is not a " + TestBasicApp.class.getName() + ", instead the type is " + entity.getEntityType().getName()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java new file mode 100644 index 0000000..e66c185 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java @@ -0,0 +1,143 @@ +/* + * 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.catalog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.annotations.Test; +import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; +import org.apache.brooklyn.catalog.CatalogItem; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.BasicEntity; +import brooklyn.entity.basic.BasicStartable; +import brooklyn.entity.basic.ConfigKeys; +import brooklyn.entity.basic.Entities; +import brooklyn.policy.Policy; +import brooklyn.policy.ha.ServiceRestarter; +import brooklyn.util.exceptions.Exceptions; + +import com.google.common.collect.Iterables; + + +public class CatalogYamlCombiTest extends AbstractYamlTest { + + private static final Logger log = LoggerFactory.getLogger(CatalogYamlCombiTest.class); + + @Test + public void testBRefEntityA() throws Exception { + addCatalogItems( + "brooklyn.catalog:", + " version: "+TEST_VERSION, + " items:", + " - item:", + " id: A", + " type: "+BasicEntity.class.getName(), + " brooklyn.config: { a: 1, b: 0 }", + " - item:", + " id: B", + " type: A", + " brooklyn.config: { b: 1 }"); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("B", TEST_VERSION); + Assert.assertNotNull(item); + + Entity a = launchEntity("A"); + Assert.assertTrue(BasicEntity.class.isInstance(a), "Wrong type: "+a); + Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1); + Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)0); + + Entity b = launchEntity("B"); + Assert.assertTrue(BasicEntity.class.isInstance(b), "Wrong type: "+b); + Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1); + Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)1); + + deleteCatalogEntity("A"); + + // now loading B makes an error + try { + launchEntity("B"); + Assert.fail("B should not be launchable"); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + log.info("Got expected error: "+e); + } + + deleteCatalogEntity("B"); + } + + @Test + public void testBRefPolicyALocationZ() throws Exception { + addCatalogItems( + "brooklyn.catalog:", + " version: "+TEST_VERSION, + " id: Z", + " items:", + " - item: ", + " type: localhost", + " brooklyn.config: { z: 9 }"); + addCatalogItems( + "brooklyn.catalog:", + " version: "+TEST_VERSION, + " items:", + " - item_type: policy", + " item:", + " id: A", + " type: "+ServiceRestarter.class.getName(), + " brooklyn.config: { a: 99 }", + " - item:", + " id: B", + " type: "+BasicStartable.class.getName(), + " location: Z", + " brooklyn.policies:", + " - type: A"); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("A", TEST_VERSION); + Assert.assertNotNull(item); + + Entity b = launchEntity("B", false); + Assert.assertTrue(BasicStartable.class.isInstance(b), "Wrong type: "+b); + Entities.dumpInfo(b); + + Assert.assertEquals(Iterables.getOnlyElement(b.getLocations()).getConfig(ConfigKeys.newIntegerConfigKey("z")), (Integer)9); + + Policy p = Iterables.getOnlyElement(b.getPolicies()); + Assert.assertTrue(ServiceRestarter.class.isInstance(p), "Wrong type: "+p); + Assert.assertEquals(p.getConfig(ConfigKeys.newIntegerConfigKey("a")), (Integer)99); + + deleteCatalogEntity("A"); + deleteCatalogEntity("B"); + deleteCatalogEntity("Z"); + } + + private Entity launchEntity(String symbolicName) throws Exception { + return launchEntity(symbolicName, true); + } + + private Entity launchEntity(String symbolicName, boolean includeLocation) throws Exception { + String yaml = "name: simple-app-yaml\n" + + (includeLocation ? "location: localhost\n" : "") + + "services: \n" + + " - type: "+ver(symbolicName); + Entity app = createAndStartApplication(yaml); + return Iterables.getOnlyElement(app.getChildren()); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java new file mode 100644 index 0000000..5d3dc75 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java @@ -0,0 +1,780 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.io.InputStream; +import java.util.Collection; +import java.util.List; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; +import org.apache.brooklyn.catalog.BrooklynCatalog; +import org.apache.brooklyn.catalog.CatalogItem; +import brooklyn.catalog.internal.CatalogUtils; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.BasicEntity; +import brooklyn.management.osgi.OsgiStandaloneTest; +import brooklyn.management.osgi.OsgiTestResources; +import org.apache.brooklyn.test.TestResourceUnavailableException; +import brooklyn.test.entity.TestEntity; +import brooklyn.test.entity.TestEntityImpl; +import brooklyn.util.ResourceUtils; +import brooklyn.util.collections.MutableList; +import brooklyn.util.exceptions.Exceptions; + +import com.google.common.collect.Iterables; + + +public class CatalogYamlEntityTest extends AbstractYamlTest { + + private static final String SIMPLE_ENTITY_TYPE = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY; + + @Test + public void testAddCatalogItemVerySimple() throws Exception { + String symbolicName = "my.catalog.app.id.load"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: " + TEST_VERSION, + " item:", + " type: "+ BasicEntity.class.getName()); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertTrue(item.getPlanYaml().indexOf("services:")>=0, "expected 'services:' block: "+item+"\n"+item.getPlanYaml()); + + deleteCatalogEntity(symbolicName); + } + @Test + public void testAddCatalogItem() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.load"; + addCatalogOSGiEntity(symbolicName); + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testAddCatalogItemTypeAsString() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.load"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item: " + SIMPLE_ENTITY_TYPE); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testAddCatalogItemTypeExplicitTypeAsString() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.load"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " item_type: entity", + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item: " + SIMPLE_ENTITY_TYPE); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testAddCatalogItemTopLevelSyntax() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.load"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testAddCatalogItemWithoutVersion() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "unversioned.app"; + addCatalogItems( + "brooklyn.catalog:", + " name: " + id, + " libraries:", + " - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item:", + " type: "+ SIMPLE_ENTITY_TYPE); + CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, BrooklynCatalog.DEFAULT_VERSION); + assertEquals(catalogItem.getVersion(), "0.0.0.SNAPSHOT"); + mgmt().getCatalog().deleteCatalogItem(id, "0.0.0.SNAPSHOT"); + } + + @Test + public void testAddCatalogItemWithInlinedVersion() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "inline_version.app"; + addCatalogItems( + "brooklyn.catalog:", + " name: " + id+":"+TEST_VERSION, + " libraries:", + " - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, TEST_VERSION); + assertEquals(catalogItem.getVersion(), TEST_VERSION); + mgmt().getCatalog().deleteCatalogItem(id, TEST_VERSION); + } + + @Test + public void testLaunchApplicationReferencingCatalog() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.launch"; + registerAndLaunchAndAssertSimpleEntity(symbolicName, SIMPLE_ENTITY_TYPE); + } + + @Test + public void testLaunchApplicationUnversionedCatalogReference() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = "my.catalog.app.id.fail"; + addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE); + try { + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + " - serviceType: " + symbolicName; + createAndStartApplication(yaml); + } finally { + deleteCatalogEntity(symbolicName); + } + } + + @Test + public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String referencedSymbolicName = "my.catalog.app.id.referenced"; + String referrerSymbolicName = "my.catalog.app.id.referring"; + addCatalogOSGiEntities(referencedSymbolicName, SIMPLE_ENTITY_TYPE, referrerSymbolicName, ver(referencedSymbolicName)); + + CatalogItem<?, ?> referrer = mgmt().getCatalog().getCatalogItem(referrerSymbolicName, TEST_VERSION); + Assert.assertTrue(referrer.getPlanYaml().indexOf("services")>=0, "expected services in: "+referrer.getPlanYaml()); + + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + " - type: " + ver(referrerSymbolicName); + Entity app = createAndStartApplication(yaml); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(referencedSymbolicName); + deleteCatalogEntity(referrerSymbolicName); + } + + @Test + public void testLaunchApplicationWithCatalogReferencingOtherCatalogInTwoSteps() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String referencedSymbolicName = "my.catalog.app.id.referenced"; + String referrerSymbolicName = "my.catalog.app.id.referring"; + addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE); + addCatalogOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName)); + + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + " - serviceType: " + ver(referrerSymbolicName); + Entity app = createAndStartApplication(yaml); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(referencedSymbolicName); + deleteCatalogEntity(referrerSymbolicName); + } + + @Test + public void testLaunchApplicationChildWithCatalogReferencingOtherCatalog() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String referencedSymbolicName = "my.catalog.app.id.child.referenced"; + String referrerSymbolicName = "my.catalog.app.id.child.referring"; + addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE); + addCatalogChildOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName)); + + Entity app = createAndStartApplication( + "name: simple-app-yaml", + "location: localhost", + "services:", + "- type: "+BasicEntity.class.getName(), + " brooklyn.children:", + " - type: " + ver(referrerSymbolicName)); + + Collection<Entity> children = app.getChildren(); + assertEquals(children.size(), 1); + Entity child = Iterables.getOnlyElement(children); + assertEquals(child.getEntityType().getName(), BasicEntity.class.getName()); + Collection<Entity> grandChildren = child.getChildren(); + assertEquals(grandChildren.size(), 1); + Entity grandChild = Iterables.getOnlyElement(grandChildren); + assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName()); + Collection<Entity> grandGrandChildren = grandChild.getChildren(); + assertEquals(grandGrandChildren.size(), 1); + Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren); + assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(referencedSymbolicName); + deleteCatalogEntity(referrerSymbolicName); + } + + @Test + public void testLaunchApplicationChildWithCatalogReferencingOtherCatalogServicesBlock() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String referencedSymbolicName = "my.catalog.app.id.child.referenced"; + String referrerSymbolicName = "my.catalog.app.id.child.referring"; + addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE); + addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referencedSymbolicName)); + + Entity app = createAndStartApplication( + "name: simple-app-yaml", + "location: localhost", + "services:", + "- serviceType: "+BasicEntity.class.getName(), + " brooklyn.children:", + " - type: " + ver(referrerSymbolicName)); + + Collection<Entity> children = app.getChildren(); + assertEquals(children.size(), 1); + Entity child = Iterables.getOnlyElement(children); + assertEquals(child.getEntityType().getName(), BasicEntity.class.getName()); + Collection<Entity> grandChildren = child.getChildren(); + assertEquals(grandChildren.size(), 1); + Entity grandChild = Iterables.getOnlyElement(grandChildren); + assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName()); + Collection<Entity> grandGrandChildren = grandChild.getChildren(); + assertEquals(grandGrandChildren.size(), 1); + Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren); + assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(referencedSymbolicName); + deleteCatalogEntity(referrerSymbolicName); + } + + @Test + public void testLaunchApplicationWithTypeUsingJavaColonPrefix() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = SIMPLE_ENTITY_TYPE; + String serviceName = "java:"+SIMPLE_ENTITY_TYPE; + registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName); + } + + @Test + public void testLaunchApplicationLoopWithJavaTypeName() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String symbolicName = SIMPLE_ENTITY_TYPE; + String serviceName = SIMPLE_ENTITY_TYPE; + registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName); + } + + @Test + public void testLaunchApplicationChildLoopCatalogIdFails() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String referrerSymbolicName = "my.catalog.app.id.child.referring"; + try { + // TODO only fails if using 'services', because that forces plan parsing; should fail in all cases + addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referrerSymbolicName)); + fail("Expected to throw"); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + assertTrue(e.getMessage().contains(referrerSymbolicName), "message was: "+e); + } + } + + @Test + public void testReferenceInstalledBundleByName() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String firstItemId = "my.catalog.app.id.register_bundle"; + String secondItemId = "my.catalog.app.id.reference_bundle"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + firstItemId, + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + deleteCatalogEntity(firstItemId); + + addCatalogItems( + "brooklyn.catalog:", + " id: " + secondItemId, + " version: " + TEST_VERSION, + " libraries:", + " - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME, + " version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(secondItemId); + } + + @Test + public void testReferenceNonInstalledBundledByNameFails() { + String nonExistentId = "none-existent-id"; + String nonExistentVersion = "9.9.9"; + try { + addCatalogItems( + "brooklyn.catalog:", + " id: my.catalog.app.id.non_existing.ref", + " version: " + TEST_VERSION, + " libraries:", + " - name: " + nonExistentId, + " version: " + nonExistentVersion, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + fail(); + } catch (IllegalStateException e) { + Assert.assertEquals(e.getMessage(), "Bundle from null failed to install: Bundle CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=null} not previously registered, but URL is empty."); + } + } + + @Test + public void testPartialBundleReferenceFails() { + try { + addCatalogItems( + "brooklyn.catalog:", + " id: my.catalog.app.id.non_existing.ref", + " version: " + TEST_VERSION, + " libraries:", + " - name: io.brooklyn.brooklyn-test-osgi-entities", + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + fail(); + } catch (NullPointerException e) { + Assert.assertEquals(e.getMessage(), "both name and version are required"); + } + try { + addCatalogItems( + "brooklyn.catalog:", + " id: my.catalog.app.id.non_existing.ref", + " version: " + TEST_VERSION, + " libraries:", + " - version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + fail(); + } catch (NullPointerException e) { + Assert.assertEquals(e.getMessage(), "both name and version are required"); + } + } + + @Test + public void testFullBundleReference() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String itemId = "my.catalog.app.id.full_ref"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + itemId, + " version: " + TEST_VERSION, + " libraries:", + " - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME, + " version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION, + " url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + deleteCatalogEntity(itemId); + } + + /** + * Test that the name:version contained in the OSGi bundle will + * override the values supplied in the YAML. + */ + @Test + public void testFullBundleReferenceUrlMetaOverridesLocalNameVersion() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String firstItemId = "my.catalog.app.id.register_bundle"; + String nonExistentId = "non_existent_id"; + String nonExistentVersion = "9.9.9"; + try { + addCatalogItems( + "brooklyn.catalog:", + " id: " + firstItemId, + " version: " + TEST_VERSION, + " libraries:", + " - name: " + nonExistentId, + " version: " + nonExistentVersion, + " url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + fail(); + } catch (IllegalStateException e) { + assertEquals(e.getMessage(), "Bundle from " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + " failed to install: " + + "Bundle already installed as " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME + ":" + + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION + " but user explicitly requested " + + "CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=" + + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + "}"); + } + } + + @Test + public void testUpdatingItemAllowedIfSame() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "my.catalog.app.id.duplicate"; + addCatalogOSGiEntity(id); + addCatalogOSGiEntity(id); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testUpdatingItemFailsIfDifferent() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "my.catalog.app.id.duplicate"; + addCatalogOSGiEntity(id); + addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE, true); + } + + @Test + public void testForcedUpdatingItem() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "my.catalog.app.id.duplicate"; + addCatalogOSGiEntity(id); + forceCatalogUpdate(); + addCatalogOSGiEntity(id); + deleteCatalogEntity(id); + } + + @Test + public void testCreateSpecFromCatalogItem() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + String id = "my.catalog.app.id.create_spec"; + addCatalogOSGiEntity(id); + BrooklynCatalog catalog = mgmt().getCatalog(); + CatalogItem<?, ?> item = catalog.getCatalogItem(id, TEST_VERSION); + Object spec = catalog.createSpec(item); + Assert.assertNotNull(spec); + } + + @Test + public void testLoadResourceFromBundle() throws Exception { + String id = "resource.test"; + addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE); + String yaml = + "services: \n" + + " - serviceType: "+ver(id); + Entity app = createAndStartApplication(yaml); + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + InputStream icon = new ResourceUtils(simpleEntity).getResourceFromUrl("classpath:/brooklyn/osgi/tests/icon.gif"); + assertTrue(icon != null); + icon.close(); + } + + @Test + public void testMissingTypeDoesNotRecurse() { + String symbolicName = "my.catalog.app.id.basic"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: " + TEST_VERSION, + "", + "services:", + "- type: brooklyn.entity.basic.BasicEntity"); + + try { + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: " + TEST_VERSION + "-update", + "", + "services:", + "- type: " + symbolicName); + fail("Catalog addition expected to fail due to non-existent java type " + symbolicName); + } catch (IllegalStateException e) { + assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e); + } + } + + @Test + public void testVersionedTypeDoesNotRecurse() { + String symbolicName = "my.catalog.app.id.basic"; + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: " + TEST_VERSION, + "", + "services:", + "- type: brooklyn.entity.basic.BasicEntity"); + + String versionedId = CatalogUtils.getVersionedId(symbolicName, TEST_VERSION); + try { + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: " + TEST_VERSION + "-update", + "", + "services:", + "- type: " + versionedId); + fail("Catalog addition expected to fail due to non-existent java type " + versionedId); + } catch (IllegalStateException e) { + assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e); + } + } + + @Test + public void testOsgiNotLeakingToParent() { + addCatalogOSGiEntity(SIMPLE_ENTITY_TYPE); + try { + addCatalogItems( + "brooklyn.catalog:", + " id: " + SIMPLE_ENTITY_TYPE, + " version: " + TEST_VERSION + "-update", + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE); + fail("Catalog addition expected to fail due to non-existent java type " + SIMPLE_ENTITY_TYPE); + } catch (IllegalStateException e) { + assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e); + } + } + + @Test + public void testConfigAppliedToCatalogItem() throws Exception { + addCatalogOSGiEntity("test", TestEntity.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " brooklyn.config:", + " test.confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + @Test + public void testFlagsAppliesToCatalogItem() throws Exception { + addCatalogOSGiEntity("test", TestEntity.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + @Test + public void testExplicitFlagsAppliesToCatalogItem() throws Exception { + addCatalogOSGiEntity("test", TestEntity.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " brooklyn.flags:", + " confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + + @Test + public void testConfigAppliedToCatalogItemImpl() throws Exception { + addCatalogOSGiEntity("test", TestEntityImpl.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " brooklyn.config:", + " test.confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + @Test + public void testFlagsAppliesToCatalogItemImpl() throws Exception { + addCatalogOSGiEntity("test", TestEntityImpl.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + @Test + public void testExplicitFlagsAppliesToCatalogItemImpl() throws Exception { + addCatalogOSGiEntity("test", TestEntityImpl.class.getName()); + String testName = "test-applies-config-on-catalog-item"; + Entity app = createAndStartApplication( + "services:", + "- type: " + ver("test"), + " brooklyn.flags:", + " confName: " + testName); + Entity testEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName); + } + + private void registerAndLaunchAndAssertSimpleEntity(String symbolicName, String serviceType) throws Exception { + addCatalogOSGiEntity(symbolicName, serviceType); + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + " - serviceType: "+ver(symbolicName); + Entity app = createAndStartApplication(yaml); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE); + + deleteCatalogEntity(symbolicName); + } + + private void addCatalogOSGiEntity(String symbolicName) { + addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE); + } + + private void addCatalogOSGiEntity(String symbolicName, String serviceType) { + addCatalogOSGiEntity(symbolicName, serviceType, false); + } + + private void addCatalogOSGiEntity(String symbolicName, String serviceType, boolean extraLib) { + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + + (extraLib ? "\n"+" - url: "+OsgiStandaloneTest.BROOKLYN_OSGI_TEST_A_0_1_0_URL : ""), + " item:", + " type: " + serviceType); + } + + private void addCatalogOSGiEntities(String ...namesAndTypes) { + List<String> lines = MutableList.of( + "brooklyn.catalog:", + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " items:"); + + for (int i=0; i<namesAndTypes.length; i+=2) { + lines.addAll(MutableList.of( + " - id: " + namesAndTypes[i], + " item:", + " type: " + namesAndTypes[i+1])); + } + + addCatalogItems(lines); + } + private void addCatalogChildOSGiEntityWithServicesBlock(String symbolicName, String serviceType) { + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item:", + " services:", + " - type: " + BasicEntity.class.getName(), + " brooklyn.children:", + " - type: " + serviceType); + } + private void addCatalogChildOSGiEntity(String symbolicName, String serviceType) { + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item:", + " type: " + BasicEntity.class.getName(), + " brooklyn.children:", + " - type: " + serviceType); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java new file mode 100644 index 0000000..b46ed92 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java @@ -0,0 +1,247 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.util.Collection; +import java.util.List; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.Test; +import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; +import org.apache.brooklyn.catalog.CatalogItem; +import org.apache.brooklyn.catalog.CatalogItem.CatalogBundle; +import brooklyn.catalog.CatalogPredicates; +import brooklyn.entity.Entity; +import brooklyn.event.basic.BasicConfigKey; +import brooklyn.location.Location; +import brooklyn.location.LocationDefinition; +import brooklyn.location.LocationSpec; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.management.osgi.OsgiStandaloneTest; +import org.apache.brooklyn.test.TestResourceUnavailableException; +import brooklyn.util.text.StringFunctions; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +public class CatalogYamlLocationTest extends AbstractYamlTest { + private static final String LOCALHOST_LOCATION_SPEC = "localhost"; + private static final String LOCALHOST_LOCATION_TYPE = LocalhostMachineProvisioningLocation.class.getName(); + private static final String SIMPLE_LOCATION_TYPE = "brooklyn.osgi.tests.SimpleLocation"; + + @AfterMethod + public void tearDown() { + for (CatalogItem<Location, LocationSpec<?>> ci : mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) { + mgmt().getCatalog().deleteCatalogItem(ci.getSymbolicName(), ci.getVersion()); + } + } + + @Test + public void testAddCatalogItem() throws Exception { + assertEquals(countCatalogLocations(), 0); + + String symbolicName = "my.catalog.location.id.load"; + addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null); + assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE); + removeAndAssert(symbolicName); + } + + @Test + public void testAddCatalogItemOsgi() throws Exception { + assertEquals(countCatalogLocations(), 0); + + String symbolicName = "my.catalog.location.id.load"; + addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries()); + assertAdded(symbolicName, SIMPLE_LOCATION_TYPE); + assertOsgi(symbolicName); + removeAndAssert(symbolicName); + } + + @Test + public void testAddCatalogItemTopLevelItemSyntax() throws Exception { + assertEquals(countCatalogLocations(), 0); + + String symbolicName = "my.catalog.location.id.load"; + addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null); + assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE); + removeAndAssert(symbolicName); + } + + @Test + public void testAddCatalogItemOsgiTopLevelItemSyntax() throws Exception { + assertEquals(countCatalogLocations(), 0); + + String symbolicName = "my.catalog.location.id.load"; + addCatalogLocationTopLevelItemSyntax(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries()); + assertAdded(symbolicName, SIMPLE_LOCATION_TYPE); + assertOsgi(symbolicName); + removeAndAssert(symbolicName); + } + + private void assertOsgi(String symbolicName) { + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + Collection<CatalogBundle> libs = item.getLibraries(); + assertEquals(libs.size(), 1); + assertEquals(Iterables.getOnlyElement(libs).getUrl(), Iterables.getOnlyElement(getOsgiLibraries())); + } + + private void assertAdded(String symbolicName, String expectedJavaType) { + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + assertEquals(countCatalogLocations(), 1); + + // Item added to catalog should automatically be available in location registry + LocationDefinition def = mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName); + assertEquals(def.getId(), symbolicName); + assertEquals(def.getName(), symbolicName); + + LocationSpec<?> spec = (LocationSpec<?>)mgmt().getCatalog().createSpec(item); + assertEquals(spec.getType().getName(), expectedJavaType); + } + + private void removeAndAssert(String symbolicName) { + // Deleting item: should be gone from catalog, and from location registry + deleteCatalogEntity(symbolicName); + + assertEquals(countCatalogLocations(), 0); + assertNull(mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName)); + } + + @Test + public void testLaunchApplicationReferencingLocationClass() throws Exception { + String symbolicName = "my.catalog.location.id.launch"; + addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null); + runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingLocationSpec() throws Exception { + String symbolicName = "my.catalog.location.id.launch"; + addCatalogLocation(symbolicName, LOCALHOST_LOCATION_SPEC, null); + runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingLocationClassTopLevelItemSyntax() throws Exception { + String symbolicName = "my.catalog.location.id.launch"; + addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null); + runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingLocationSpecTopLevelSyntax() throws Exception { + String symbolicName = "my.catalog.location.id.launch"; + addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_SPEC, null); + runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingOsgiLocation() throws Exception { + String symbolicName = "my.catalog.location.id.launch"; + addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries()); + runLaunchApplicationReferencingLocation(symbolicName, SIMPLE_LOCATION_TYPE); + + deleteCatalogEntity(symbolicName); + } + + protected void runLaunchApplicationReferencingLocation(String locTypeInYaml, String locType) throws Exception { + Entity app = createAndStartApplication( + "name: simple-app-yaml", + "location: ", + " "+locTypeInYaml+":", + " config2: config2 override", + " config3: config3", + "services: ", + " - type: brooklyn.entity.basic.BasicStartable"); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + Location location = Iterables.getOnlyElement(simpleEntity.getLocations()); + assertEquals(location.getClass().getName(), locType); + assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1"); + assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override"); + assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3"); + } + + private List<String> getOsgiLibraries() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + return ImmutableList.of(OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL); + } + + private void addCatalogLocation(String symbolicName, String locationType, List<String> libraries) { + ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog Location", + " description: My description", + " version: " + TEST_VERSION); + if (libraries!=null && libraries.size() > 0) { + yaml.add(" libraries:") + .addAll(Lists.transform(libraries, StringFunctions.prepend(" - url: "))); + } + yaml.add( + " item.type: location", + " item:", + " type: " + locationType, + " brooklyn.config:", + " config1: config1", + " config2: config2"); + + + addCatalogItems(yaml.build()); + } + + private void addCatalogLocationTopLevelItemSyntax(String symbolicName, String locationType, List<String> libraries) { + ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog Location", + " description: My description", + " version: " + TEST_VERSION); + if (libraries!=null && libraries.size() > 0) { + yaml.add(" libraries:") + .addAll(Lists.transform(libraries, StringFunctions.prepend(" - url: "))); + } + yaml.add( + "", + "brooklyn.locations:", + "- type: " + locationType, + " brooklyn.config:", + " config1: config1", + " config2: config2"); + + + addCatalogItems(yaml.build()); + } + + private int countCatalogLocations() { + return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java new file mode 100644 index 0000000..ab738b6 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java @@ -0,0 +1,195 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; +import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; +import org.apache.brooklyn.catalog.CatalogItem; +import brooklyn.catalog.CatalogPredicates; +import brooklyn.entity.Entity; +import brooklyn.event.basic.BasicConfigKey; +import brooklyn.management.osgi.OsgiStandaloneTest; +import brooklyn.policy.Policy; +import org.apache.brooklyn.test.TestResourceUnavailableException; + +import com.google.common.collect.Iterables; + +public class CatalogYamlPolicyTest extends AbstractYamlTest { + private static final String SIMPLE_POLICY_TYPE = "brooklyn.osgi.tests.SimplePolicy"; + private static final String SIMPLE_ENTITY_TYPE = "brooklyn.osgi.tests.SimpleEntity"; + + @Test + public void testAddCatalogItem() throws Exception { + assertEquals(countCatalogPolicies(), 0); + + String symbolicName = "my.catalog.policy.id.load"; + addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + assertEquals(countCatalogPolicies(), 1); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testAddCatalogItemTopLevelSyntax() throws Exception { + assertEquals(countCatalogPolicies(), 0); + + String symbolicName = "my.catalog.policy.id.load"; + addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE); + + CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION); + assertEquals(item.getSymbolicName(), symbolicName); + assertEquals(countCatalogPolicies(), 1); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingPolicy() throws Exception { + String symbolicName = "my.catalog.policy.id.launch"; + addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE); + Entity app = createAndStartApplication( + "name: simple-app-yaml", + "location: localhost", + "services: ", + " - type: brooklyn.entity.basic.BasicEntity\n" + + " brooklyn.policies:\n" + + " - type: " + ver(symbolicName), + " brooklyn.config:", + " config2: config2 override", + " config3: config3"); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies()); + assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1"); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override"); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3"); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationReferencingPolicyTopLevelSyntax() throws Exception { + String symbolicName = "my.catalog.policy.id.launch"; + addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE); + Entity app = createAndStartApplication( + "name: simple-app-yaml", + "location: localhost", + "services: ", + " - type: brooklyn.entity.basic.BasicEntity\n" + + " brooklyn.policies:\n" + + " - type: " + ver(symbolicName), + " brooklyn.config:", + " config2: config2 override", + " config3: config3"); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies()); + assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1"); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override"); + assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3"); + + deleteCatalogEntity(symbolicName); + } + + @Test + public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception { + String referencedSymbolicName = "my.catalog.policy.id.referenced"; + String referrerSymbolicName = "my.catalog.policy.id.referring"; + addCatalogOsgiPolicy(referencedSymbolicName, SIMPLE_POLICY_TYPE); + + addCatalogItems( + "brooklyn.catalog:", + " id: " + referrerSymbolicName, + " name: My Catalog App", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "services:", + "- type: " + SIMPLE_ENTITY_TYPE, + " brooklyn.policies:", + " - type: " + ver(referencedSymbolicName)); + + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + "- type: "+ ver(referrerSymbolicName); + + Entity app = createAndStartApplication(yaml); + + Entity simpleEntity = Iterables.getOnlyElement(app.getChildren()); + Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies()); + assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE); + + deleteCatalogEntity(referencedSymbolicName); + } + + private void addCatalogOsgiPolicy(String symbolicName, String policyType) { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog Policy", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + " item:", + " type: " + policyType, + " brooklyn.config:", + " config1: config1", + " config2: config2"); + } + + private void addCatalogOsgiPolicyTopLevelSyntax(String symbolicName, String policyType) { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + addCatalogItems( + "brooklyn.catalog:", + " id: " + symbolicName, + " name: My Catalog Policy", + " description: My description", + " icon_url: classpath://path/to/myicon.jpg", + " version: " + TEST_VERSION, + " libraries:", + " - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL, + "", + "brooklyn.policies:", + "- type: " + policyType, + " brooklyn.config:", + " config1: config1", + " config2: config2"); + } + + private int countCatalogPolicies() { + return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_POLICY)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java new file mode 100644 index 0000000..29a1227 --- /dev/null +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java @@ -0,0 +1,132 @@ +/* + * 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.catalog; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; + +import org.apache.brooklyn.camp.brooklyn.AbstractYamlRebindTest; +import org.testng.annotations.Test; + +import brooklyn.catalog.internal.CatalogUtils; +import brooklyn.entity.basic.BasicEntity; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.basic.StartableApplication; +import brooklyn.internal.BrooklynFeatureEnablement; +import brooklyn.policy.Enricher; +import brooklyn.policy.Policy; +import brooklyn.test.policy.TestEnricher; +import brooklyn.test.policy.TestPolicy; + +import com.google.common.base.Joiner; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; + +public class CatalogYamlRebindTest extends AbstractYamlRebindTest { + + // TODO Other tests (relating to https://issues.apache.org/jira/browse/BROOKLYN-149) include: + // - entities cannot be instantiated because class no longer on classpath (e.g. was OSGi) + // - config/attribute cannot be instantiated (e.g. because class no longer on classpath) + // - entity file corrupt + + enum RebindWithCatalogTestMode { + NO_OP, + DELETE_CATALOG, + REPLACE_CATALOG_WITH_NEWER_VERSION; + } + + @Test + public void testRebindWithCatalogAndApp() throws Exception { + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.NO_OP); + } + + // See https://issues.apache.org/jira/browse/BROOKLYN-149. + // Deletes the catalog item before rebind, but the referenced types are still on the + // default classpath. + // Will fallback to loading from classpath. + @Test + public void testRebindWithCatalogDeletedAndAppExisting() throws Exception { + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DELETE_CATALOG); + } + + // Upgrades the catalog item before rebind, deleting the old version. + // Will automatically upgrade. + @Test + public void testRebindWithCatalogUpgradedWithOldDeletedAndAppExisting() throws Exception { + BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND); + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.REPLACE_CATALOG_WITH_NEWER_VERSION); + } + + @SuppressWarnings("unused") + protected void runRebindWithCatalogAndApp(RebindWithCatalogTestMode mode) throws Exception { + String symbolicName = "my.catalog.app.id.load"; + String version = "0.1.2"; + String catalogFormat = Joiner.on("\n").join( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: %s", + " item:", + " type: "+ BasicEntity.class.getName(), + " brooklyn.enrichers:", + " - type: "+TestEnricher.class.getName(), + " brooklyn.policies:", + " - type: "+TestPolicy.class.getName()); + + // Create the catalog item + addCatalogItems(String.format(catalogFormat, version)); + + // Create an app, using that catalog item + String yaml = "name: simple-app-yaml\n" + + "location: localhost\n" + + "services: \n" + + "- type: "+CatalogUtils.getVersionedId(symbolicName, version); + origApp = (StartableApplication) createAndStartApplication(yaml); + BasicEntity origEntity = (BasicEntity) Iterables.getOnlyElement(origApp.getChildren()); + TestPolicy origPolicy = (TestPolicy) Iterables.getOnlyElement(origEntity.getPolicies()); + TestEnricher origEnricher = (TestEnricher) Iterables.tryFind(origEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get(); + assertEquals(origEntity.getCatalogItemId(), symbolicName+":"+version); + + // Depending on test-mode, delete the catalog item, and then rebind + switch (mode) { + case DELETE_CATALOG: + mgmt().getCatalog().deleteCatalogItem(symbolicName, version); + break; + case REPLACE_CATALOG_WITH_NEWER_VERSION: + mgmt().getCatalog().deleteCatalogItem(symbolicName, version); + version = "0.1.3"; + addCatalogItems(String.format(catalogFormat, version)); + break; + case NO_OP: + // no-op + } + + rebind(); + + // Ensure app is still there + BasicEntity newEntity = (BasicEntity) Iterables.getOnlyElement(newApp.getChildren()); + Policy newPolicy = Iterables.getOnlyElement(newEntity.getPolicies()); + Enricher newEnricher = Iterables.tryFind(newEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get(); + assertEquals(newEntity.getCatalogItemId(), symbolicName+":"+version); + + // Ensure app is still usable - e.g. "stop" effector functions as expected + newApp.stop(); + assertFalse(Entities.isManaged(newApp)); + assertFalse(Entities.isManaged(newEntity)); + } +}
