diff --git a/a4c-brooklyn-plugin/pom.xml b/a4c-brooklyn-plugin/pom.xml index 9b654cd..7811035 100644 --- a/a4c-brooklyn-plugin/pom.xml +++ b/a4c-brooklyn-plugin/pom.xml @@ -52,6 +52,22 @@ brooklyn-rest-client ${brooklyn.version} + + javax.servlet + javax.servlet-api + 3.1.0 + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + org.projectlombok @@ -59,6 +75,7 @@ ${lombok.version} provided + junit @@ -91,19 +108,10 @@ test - javax.servlet - javax.servlet-api - 3.1.0 - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - org.apache.httpcomponents - httpmime - ${httpclient.version} + org.apache.brooklyn + brooklyn-software-database + ${brooklyn.version} + test diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynCatalogMapper.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynCatalogMapper.java index 53efe8a..a1eb082 100644 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynCatalogMapper.java +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynCatalogMapper.java @@ -1,28 +1,10 @@ package alien4cloud.brooklyn; import java.nio.file.Path; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; -import alien4cloud.brooklyn.metadata.AbstractToscaMetadataProvider; -import alien4cloud.model.components.AttributeDefinition; -import alien4cloud.model.components.CSARDependency; -import alien4cloud.model.components.Csar; -import alien4cloud.model.components.IValue; -import alien4cloud.model.components.IndexedNodeType; -import alien4cloud.model.components.Interface; -import alien4cloud.model.components.Operation; -import alien4cloud.model.components.PropertyDefinition; -import alien4cloud.plugin.model.ManagedPlugin; -import alien4cloud.tosca.ArchiveParser; -import alien4cloud.tosca.normative.ToscaType; -import alien4cloud.tosca.parser.ParsingException; -import alien4cloud.tosca.parser.ParsingResult; -import com.google.common.collect.ImmutableList; -import lombok.extern.slf4j.Slf4j; - import org.apache.brooklyn.rest.client.BrooklynApi; import org.apache.brooklyn.rest.domain.CatalogEntitySummary; import org.apache.brooklyn.rest.domain.EffectorSummary; @@ -32,14 +14,32 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import alien4cloud.brooklyn.metadata.ToscaMetadataProvider; +import alien4cloud.brooklyn.metadata.ToscaTypeProvider; import alien4cloud.component.repository.ICsarRepositry; import alien4cloud.csar.services.CsarService; +import alien4cloud.model.components.AttributeDefinition; +import alien4cloud.model.components.CSARDependency; +import alien4cloud.model.components.Csar; +import alien4cloud.model.components.IValue; +import alien4cloud.model.components.IndexedNodeType; +import alien4cloud.model.components.Interface; +import alien4cloud.model.components.Operation; +import alien4cloud.model.components.PropertyDefinition; +import alien4cloud.plugin.model.ManagedPlugin; import alien4cloud.tosca.ArchiveImageLoader; import alien4cloud.tosca.ArchiveIndexer; +import alien4cloud.tosca.ArchiveParser; import alien4cloud.tosca.model.ArchiveRoot; +import alien4cloud.tosca.normative.ToscaType; +import alien4cloud.tosca.parser.ParsingException; +import alien4cloud.tosca.parser.ParsingResult; +import lombok.extern.slf4j.Slf4j; /** * This component is used to map components out of brooklyn to a4c. @@ -50,6 +50,7 @@ @Slf4j public class BrooklynCatalogMapper { private final static Map TYPE_MAPPING = Maps.newHashMap(); + static { TYPE_MAPPING.put(Boolean.class.getName(), ToscaType.BOOLEAN); TYPE_MAPPING.put(String.class.getName(), ToscaType.STRING); @@ -95,7 +96,7 @@ public void addBaseTypes(){ } } - public void mapBrooklynEntities(BrooklynApi brooklynApi, AbstractToscaMetadataProvider metadataProvider) { + public void mapBrooklynEntities(BrooklynApi brooklynApi, ToscaMetadataProvider metadataProvider) { ArchiveRoot archiveRoot = new ArchiveRoot(); // Brooklyn actually depends on normative types and alien types archiveRoot.getArchive().setToscaDefinitionsVersion("tosca_simple_yaml_1_0_0_wd03"); @@ -129,7 +130,7 @@ public void mapBrooklynEntities(BrooklynApi brooklynApi, AbstractToscaMetadataPr archiveIndexer.indexArchive(archiveRoot.getArchive().getName(), archiveRoot.getArchive().getVersion(), archiveRoot, true); } - public void mapBrooklynEntity(BrooklynApi brooklynApi, ArchiveRoot archiveRoot, String entityName, String entityVersion, AbstractToscaMetadataProvider metadataProvider) { + public void mapBrooklynEntity(BrooklynApi brooklynApi, ArchiveRoot archiveRoot, String entityName, String entityVersion, ToscaMetadataProvider metadataProvider) { try { IndexedNodeType toscaType = new IndexedNodeType(); CatalogEntitySummary brooklynEntity = loadEntity(brooklynApi, entityName); @@ -148,10 +149,11 @@ public void mapBrooklynEntity(BrooklynApi brooklynApi, ArchiveRoot archiveRoot, addPropertyDefinitions(brooklynEntity, toscaType); addAttributeDefinitions(brooklynEntity, toscaType); addInterfaces(brooklynEntity, toscaType); - toscaType.setDerivedFrom(ImmutableList.of( - metadataProvider.findToscaType(brooklynEntity.getType()) - )); + Optional derivedFrom = metadataProvider.getToscaType(brooklynEntity.getType()); + if (derivedFrom.isPresent()) { + toscaType.setDerivedFrom(ImmutableList.of(derivedFrom.get())); + } // TODO override the host requirement in order to say that none is required. // or say it requires some type of cloud/server/location/etc diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynLocationConfigurerFactory.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynLocationConfigurerFactory.java index 3b20abf..2d3c861 100644 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynLocationConfigurerFactory.java +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynLocationConfigurerFactory.java @@ -1,8 +1,6 @@ package alien4cloud.brooklyn; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynOrchestratorFactory.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynOrchestratorFactory.java index 1eaf65c..a177146 100644 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynOrchestratorFactory.java +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynOrchestratorFactory.java @@ -1,8 +1,11 @@ package alien4cloud.brooklyn; import java.util.Collections; +import java.util.List; import java.util.Map; +import alien4cloud.brooklyn.metadata.BrooklynToscaTypeProvider; +import alien4cloud.brooklyn.metadata.DefaultToscaTypeProvider; import lombok.extern.slf4j.Slf4j; import org.apache.brooklyn.util.collections.MutableList; @@ -43,12 +46,15 @@ public Class getConfigurationType() { @Override public Configuration getDefaultConfiguration() { + // List ordered lowest to highest priority. + List metadataProviders = MutableList.of( + DefaultToscaTypeProvider.class.getName(), + BrooklynToscaTypeProvider.class.getName()); return new Configuration("http://localhost:8081/", "brooklyn", "brooklyn", "localhost", - MutableList.of("alien4cloud.brooklyn.metadata.DefaultToscaMetadataProvider") - ); + metadataProviders); } @Override diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynProvider.java index e64991a..f5198ed 100644 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynProvider.java +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/BrooklynProvider.java @@ -2,20 +2,12 @@ import java.util.Collection; import java.util.Date; -import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; - import javax.ws.rs.core.Response; -import alien4cloud.brooklyn.metadata.AbstractToscaMetadataProvider; -import alien4cloud.dao.IGenericSearchDAO; -import alien4cloud.orchestrators.locations.services.LocationService; -import alien4cloud.paas.model.InstanceStatus; -import alien4cloud.paas.model.PaaSMessageMonitorEvent; -import lombok.SneakyThrows; - import org.apache.brooklyn.rest.client.BrooklynApi; import org.apache.brooklyn.rest.domain.ApplicationSummary; import org.apache.brooklyn.rest.domain.EntitySummary; @@ -33,6 +25,9 @@ import com.google.common.collect.Sets; import alien4cloud.application.ApplicationService; +import alien4cloud.brooklyn.metadata.ToscaMetadataProvider; +import alien4cloud.brooklyn.metadata.ToscaTypeProvider; +import alien4cloud.dao.IGenericSearchDAO; import alien4cloud.exception.NotFoundException; import alien4cloud.model.application.Application; import alien4cloud.model.common.Tag; @@ -40,6 +35,7 @@ import alien4cloud.model.components.ScalarPropertyValue; import alien4cloud.model.topology.NodeTemplate; import alien4cloud.model.topology.Topology; +import alien4cloud.orchestrators.locations.services.LocationService; import alien4cloud.paas.IConfigurablePaaSProvider; import alien4cloud.paas.IPaaSCallback; import alien4cloud.paas.exception.MaintenanceModeException; @@ -48,9 +44,12 @@ import alien4cloud.paas.model.AbstractMonitorEvent; import alien4cloud.paas.model.DeploymentStatus; import alien4cloud.paas.model.InstanceInformation; +import alien4cloud.paas.model.InstanceStatus; import alien4cloud.paas.model.NodeOperationExecRequest; import alien4cloud.paas.model.PaaSDeploymentContext; +import alien4cloud.paas.model.PaaSMessageMonitorEvent; import alien4cloud.paas.model.PaaSTopologyDeploymentContext; +import lombok.SneakyThrows; /** * @@ -109,23 +108,22 @@ public void init(Map activeDeployments) { // TODO synchronise locations catalogMapper.addBaseTypes(); - AbstractToscaMetadataProvider metadataProvider = null; - for (String provider : configuration.getProviders()) { + List metadataProviders = new LinkedList<>(); + for (String providerClass : configuration.getProviders()) { try { - AbstractToscaMetadataProvider next = (AbstractToscaMetadataProvider)Class.forName(provider).newInstance(); - if(metadataProvider == null) {metadataProvider = next;} - else { - next.setNext(metadataProvider); - metadataProvider = next; - } + Object provider = Class.forName(providerClass).newInstance(); + // Alien UI has higher priority items at the end of the list. + // Reverse the order here. + metadataProviders.add(0, ToscaTypeProvider.class.cast(provider)); } catch (IllegalAccessException| InstantiationException | ClassNotFoundException e) { - log.warn("no such metadata provider {}", provider); + log.warn("Could not load metadata provider " + providerClass, e); } } - catalogMapper.mapBrooklynEntities(getNewBrooklynApi(), metadataProvider); - - - } finally { revertContextClassLoader(); } + catalogMapper.mapBrooklynEntities(getNewBrooklynApi(), new ToscaMetadataProvider(metadataProviders)); + + } finally { + revertContextClassLoader(); + } } @Override diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/AbstractToscaMetadataProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/AbstractToscaMetadataProvider.java deleted file mode 100644 index 32f5f10..0000000 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/AbstractToscaMetadataProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -package alien4cloud.brooklyn.metadata; - -public abstract class AbstractToscaMetadataProvider{ - - private AbstractToscaMetadataProvider next; - - public void setNext(AbstractToscaMetadataProvider next){ - this.next = next; - }; - - public AbstractToscaMetadataProvider next(){ - return this.next; - } - - public boolean hasNext(){ - return next != null; - } - - public abstract String findToscaType(String type); - -} diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/BrooklynToscaTypeProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/BrooklynToscaTypeProvider.java new file mode 100644 index 0000000..9c4e4f7 --- /dev/null +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/BrooklynToscaTypeProvider.java @@ -0,0 +1,19 @@ +package alien4cloud.brooklyn.metadata; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + +public class BrooklynToscaTypeProvider implements ToscaTypeProvider { + + private Map typeMapping = ImmutableMap.of( + "org.apache.brooklyn.entity.database.mysql.MySqlNode", "brooklyn.nodes.Database" + ); + + @Override + public Optional getToscaType(String type) { + return Optional.fromNullable(typeMapping.get(type)); + } + +} diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaMetadataProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaMetadataProvider.java deleted file mode 100644 index 2a8c2b4..0000000 --- a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaMetadataProvider.java +++ /dev/null @@ -1,25 +0,0 @@ -package alien4cloud.brooklyn.metadata; - -import com.google.common.collect.ImmutableMap; - -import java.util.Map; - -public class DefaultToscaMetadataProvider extends AbstractToscaMetadataProvider { - - private Map typeMapping = ImmutableMap.of( - "org.apache.brooklyn.entity.database.mysql.MySqlNode", "brooklyn.nodes.Database" - ); - - @Override - public String findToscaType(String type) { - if(!typeMapping.containsKey(type) && !hasNext()) { - return "brooklyn.nodes.SoftwareProcess"; - } - - if(!typeMapping.containsKey(type)){ - return next().findToscaType(type); - } - - return typeMapping.get(type); - } -} diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaTypeProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaTypeProvider.java new file mode 100644 index 0000000..4302187 --- /dev/null +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/DefaultToscaTypeProvider.java @@ -0,0 +1,15 @@ +package alien4cloud.brooklyn.metadata; + +import com.google.common.base.Optional; + +/** + * A {@link ToscaTypeProvider} that always returns "brooklyn.nodes.SoftwareProcess". + */ +public class DefaultToscaTypeProvider implements ToscaTypeProvider { + + @Override + public Optional getToscaType(String type) { + return Optional.of("brooklyn.nodes.SoftwareProcess"); + } + +} diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaMetadataProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaMetadataProvider.java new file mode 100644 index 0000000..8554276 --- /dev/null +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaMetadataProvider.java @@ -0,0 +1,28 @@ +package alien4cloud.brooklyn.metadata; + +import java.util.List; + +import com.google.common.base.Optional; + +public class ToscaMetadataProvider { + + private final List providers; + + public ToscaMetadataProvider(List providers) { + this.providers = providers; + } + + /** + * @see alien4cloud.brooklyn.metadata.ToscaTypeProvider#getToscaType(String) + */ + public Optional getToscaType(String type) { + for (ToscaTypeProvider provider : providers) { + Optional providedType = provider.getToscaType(type); + if (providedType.isPresent()) { + return providedType; + } + } + return Optional.absent(); + } + +} diff --git a/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaTypeProvider.java b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaTypeProvider.java new file mode 100644 index 0000000..a35574f --- /dev/null +++ b/a4c-brooklyn-plugin/src/main/java/alien4cloud/brooklyn/metadata/ToscaTypeProvider.java @@ -0,0 +1,13 @@ +package alien4cloud.brooklyn.metadata; + +import com.google.common.base.Optional; + +public interface ToscaTypeProvider { + + /** + * @return A TOSCA type to use for the given input, or {@link Optional#absent absent} if + * no such type can be chosen. + */ + Optional getToscaType(String type); + +} diff --git a/a4c-brooklyn-plugin/src/test/java/alien4cloud/brooklyn/metadata/ToscaMetadataProviderTest.java b/a4c-brooklyn-plugin/src/test/java/alien4cloud/brooklyn/metadata/ToscaMetadataProviderTest.java new file mode 100644 index 0000000..42c5766 --- /dev/null +++ b/a4c-brooklyn-plugin/src/test/java/alien4cloud/brooklyn/metadata/ToscaMetadataProviderTest.java @@ -0,0 +1,50 @@ +package alien4cloud.brooklyn.metadata; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; + +import org.apache.brooklyn.entity.database.mysql.MySqlNode; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; + +public class ToscaMetadataProviderTest { + + @Test + public void testOrdering() { + ToscaMetadataProvider tmp = new ToscaMetadataProvider(ImmutableList.of( + new AlwaysBobTypeProvider(), + new BrooklynToscaTypeProvider(), + new AlwaysAbsentTypeProvider())); + assertEquals(tmp.getToscaType("bib").get(), "bob"); + } + + @Test + public void testNoGoodType() { + ToscaMetadataProvider tmp = new ToscaMetadataProvider(ImmutableList.of( + new AlwaysAbsentTypeProvider())); + assertFalse(tmp.getToscaType("xyz").isPresent()); + } + + @Test + public void testBrooklynTypeProvider() { + ToscaMetadataProvider tmp = new ToscaMetadataProvider(ImmutableList.of( + new BrooklynToscaTypeProvider())); + assertEquals(tmp.getToscaType(MySqlNode.class.getName()).get(), "brooklyn.nodes.Database"); + } + + private static class AlwaysBobTypeProvider implements ToscaTypeProvider { + @Override + public Optional getToscaType(String type) { + return Optional.of("bob"); + } + } + + private static class AlwaysAbsentTypeProvider implements ToscaTypeProvider { + @Override + public Optional getToscaType(String type) { + return Optional.absent(); + } + } +}