AMBARI-12885. Dynamic stack extensions - install and upgrade support for custom services (Tim Thorpe via alejandro)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/300a7e21 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/300a7e21 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/300a7e21 Branch: refs/heads/trunk Commit: 300a7e21d109ef731af65dc8652e057065081bb2 Parents: 31dfc56 Author: Alejandro Fernandez <[email protected]> Authored: Mon Jun 20 12:19:40 2016 -0700 Committer: Alejandro Fernandez <[email protected]> Committed: Mon Jun 20 14:36:26 2016 -0700 ---------------------------------------------------------------------- ambari-server/conf/unix/ambari.properties | 1 + ambari-server/src/main/assemblies/server.xml | 4 + .../ExtensionLinkResourceDefinition.java | 58 ++ .../resources/ExtensionResourceDefinition.java | 59 ++ .../ExtensionVersionResourceDefinition.java | 54 ++ .../resources/ResourceInstanceFactoryImpl.java | 12 + .../server/api/services/AmbariMetaInfo.java | 42 +- .../api/services/ExtensionLinksService.java | 101 ++++ .../server/api/services/ExtensionsService.java | 127 +++++ .../server/api/services/StacksService.java | 23 + .../server/configuration/Configuration.java | 9 + .../controller/AmbariManagementController.java | 49 +- .../AmbariManagementControllerImpl.java | 270 ++++++++++ .../server/controller/ExtensionLinkRequest.java | 86 +++ .../controller/ExtensionLinkResponse.java | 124 +++++ .../server/controller/ExtensionRequest.java | 43 ++ .../server/controller/ExtensionResponse.java | 61 +++ .../controller/ExtensionVersionRequest.java | 44 ++ .../controller/ExtensionVersionResponse.java | 101 ++++ .../AbstractControllerResourceProvider.java | 6 + .../server/controller/internal/Extension.java | 282 ++++++++++ .../internal/ExtensionLinkResourceProvider.java | 241 +++++++++ .../internal/ExtensionResourceProvider.java | 121 +++++ .../ExtensionVersionResourceProvider.java | 131 +++++ .../ambari/server/controller/spi/Resource.java | 6 + .../ambari/server/orm/dao/ExtensionDAO.java | 168 ++++++ .../ambari/server/orm/dao/ExtensionLinkDAO.java | 240 +++++++++ .../server/orm/entities/ExtensionEntity.java | 156 ++++++ .../orm/entities/ExtensionLinkEntity.java | 139 +++++ .../apache/ambari/server/stack/BaseModule.java | 4 +- .../server/stack/CommonServiceDirectory.java | 7 +- .../ambari/server/stack/ComponentModule.java | 3 +- .../server/stack/ConfigurationModule.java | 3 +- .../ambari/server/stack/ExtensionDirectory.java | 196 +++++++ .../ambari/server/stack/ExtensionHelper.java | 167 ++++++ .../ambari/server/stack/ExtensionModule.java | 540 +++++++++++++++++++ .../server/stack/ModuleFileUnmarshaller.java | 4 + .../stack/QuickLinksConfigurationModule.java | 2 +- .../ambari/server/stack/ServiceDirectory.java | 114 +++- .../ambari/server/stack/ServiceModule.java | 57 +- .../server/stack/StackDefinitionModule.java | 3 +- .../ambari/server/stack/StackDirectory.java | 32 -- .../ambari/server/stack/StackManager.java | 223 +++++++- .../server/stack/StackManagerFactory.java | 3 + .../apache/ambari/server/stack/StackModule.java | 211 +++++++- .../server/stack/StackServiceDirectory.java | 6 +- .../apache/ambari/server/stack/ThemeModule.java | 3 +- .../apache/ambari/server/state/ExtensionId.java | 160 ++++++ .../ambari/server/state/ExtensionInfo.java | 208 +++++++ .../apache/ambari/server/state/ServiceInfo.java | 11 + .../apache/ambari/server/state/StackInfo.java | 29 + .../state/stack/ExtensionMetainfoXml.java | 204 +++++++ .../server/state/stack/ServiceMetainfoXml.java | 4 + .../server/upgrade/UpgradeCatalog240.java | 53 +- .../main/resources/Ambari-DDL-Derby-CREATE.sql | 26 +- .../main/resources/Ambari-DDL-MySQL-CREATE.sql | 24 +- .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 24 +- .../resources/Ambari-DDL-Postgres-CREATE.sql | 24 +- .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 26 +- .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 24 +- .../resources/Ambari-DDL-SQLServer-CREATE.sql | 24 +- .../src/main/resources/META-INF/persistence.xml | 2 + .../src/main/resources/extensions/README.txt | 31 ++ .../src/main/resources/key_properties.json | 16 +- .../src/main/resources/properties.json | 30 +- .../api/services/ExtensionsServiceTest.java | 119 ++++ .../internal/ExtensionResourceProviderTest.java | 91 ++++ .../server/stack/ComponentModuleTest.java | 2 +- .../QuickLinksConfigurationModuleTest.java | 4 +- .../ambari/server/stack/ServiceModuleTest.java | 2 +- .../stack/StackManagerCommonServicesTest.java | 32 +- .../server/stack/StackManagerExtensionTest.java | 131 +++++ .../server/stack/StackManagerMiscTest.java | 47 +- .../ambari/server/stack/StackManagerTest.java | 123 ++++- .../ambari/server/stack/ThemeModuleTest.java | 2 +- .../server/upgrade/UpgradeCatalog240Test.java | 43 +- .../resources/extensions/EXT/0.1/metainfo.xml | 30 ++ .../OOZIE2/configuration/oozie2-site.xml | 245 +++++++++ .../EXT/0.1/services/OOZIE2/metainfo.xml | 110 ++++ .../0.1/services/OOZIE2/package/dummy-script.py | 20 + .../EXT/0.1/services/PIG2/metainfo.xml | 26 + .../resources/extensions/EXT/0.2/metainfo.xml | 31 ++ .../EXT/0.2/services/OOZIE2/metainfo.xml | 110 ++++ .../stacks/OTHER/1.0/services/PIG2/metainfo.xml | 30 ++ .../stacks_with_extensions/HDP/0.1/metainfo.xml | 22 + .../HDP/0.1/repos/repoinfo.xml | 57 ++ .../HDP/0.1/services/HDFS/metainfo.xml | 46 ++ .../HDP/0.1/services/MAPREDUCE/metainfo.xml | 23 + .../HDP/0.1/services/PIG/metainfo.xml | 26 + .../stacks_with_extensions/HDP/0.2/metainfo.xml | 22 + .../HDP/0.2/repos/repoinfo.xml | 57 ++ .../HDP/0.2/services/HBASE/metainfo.xml | 26 + .../0.2/services/HDFS/configuration/global.xml | 145 +++++ .../services/HDFS/configuration/hadoop-env.xml | 223 ++++++++ .../services/HDFS/configuration/hbase-site.xml | 137 +++++ .../services/HDFS/configuration/hdfs-log4j.xml | 199 +++++++ .../services/HDFS/configuration/hdfs-site.xml | 396 ++++++++++++++ .../HDP/0.2/services/HDFS/metainfo.xml | 30 ++ .../0.2/services/HDFS/package/dummy-script.py | 20 + .../HDP/0.2/services/HIVE/metainfo.xml | 26 + .../HDP/0.2/services/MAPREDUCE/metainfo.xml | 23 + .../HDP/0.2/services/ZOOKEEPER/metainfo.xml | 26 + 102 files changed, 7755 insertions(+), 203 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/conf/unix/ambari.properties ---------------------------------------------------------------------- diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties index a88a025..abd72ad 100644 --- a/ambari-server/conf/unix/ambari.properties +++ b/ambari-server/conf/unix/ambari.properties @@ -43,6 +43,7 @@ jce.download.supported=true metadata.path=$ROOT/var/lib/ambari-server/resources/stacks common.services.path=$ROOT/var/lib/ambari-server/resources/common-services +extensions.path=/var/lib/ambari-server/resources/extensions server.version.file=$ROOT/var/lib/ambari-server/resources/version webapp.dir=$ROOT/usr/lib/ambari-server/web pid.dir=$ROOT/var/run/ambari-server http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/assemblies/server.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/assemblies/server.xml b/ambari-server/src/main/assemblies/server.xml index 1560d8d..2439e17 100644 --- a/ambari-server/src/main/assemblies/server.xml +++ b/ambari-server/src/main/assemblies/server.xml @@ -155,6 +155,10 @@ <outputDirectory>/var/lib/ambari-server/resources/stacks/${stack.distribution}</outputDirectory> </fileSet> <fileSet> + <directory>src/main/resources/extensions</directory> + <outputDirectory>/var/lib/ambari-server/resources/extensions</outputDirectory> + </fileSet> + <fileSet> <directory>src/main/python/ambari_server</directory> <outputDirectory>/usr/lib/python2.6/site-packages/ambari_server</outputDirectory> </fileSet> http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionLinkResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionLinkResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionLinkResourceDefinition.java new file mode 100644 index 0000000..f03f4f7 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionLinkResourceDefinition.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.ambari.server.api.resources; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.Resource.Type; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionLinkResourceDefinition extends BaseResourceDefinition { + + public ExtensionLinkResourceDefinition(Type resourceType) { + super(Resource.Type.ExtensionLink); + } + + public ExtensionLinkResourceDefinition() { + super(Resource.Type.ExtensionLink); + } + + @Override + public String getPluralName() { + return "links"; + } + + @Override + public String getSingularName() { + return "link"; + } + + @Override + public Set<SubResourceDefinition> getSubResourceDefinitions() { + Set<SubResourceDefinition> setChildren = new HashSet<SubResourceDefinition>(); + return setChildren; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionResourceDefinition.java new file mode 100644 index 0000000..bad78b9 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionResourceDefinition.java @@ -0,0 +1,59 @@ +/** + * 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.ambari.server.api.resources; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.Resource.Type; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionResourceDefinition extends BaseResourceDefinition { + + public ExtensionResourceDefinition(Type resourceType) { + super(Resource.Type.Extension); + } + + public ExtensionResourceDefinition() { + super(Resource.Type.Extension); + } + + @Override + public String getPluralName() { + return "extensions"; + } + + @Override + public String getSingularName() { + return "extension"; + } + + @Override + public Set<SubResourceDefinition> getSubResourceDefinitions() { + Set<SubResourceDefinition> setChildren = new HashSet<SubResourceDefinition>(); + setChildren.add(new SubResourceDefinition(Resource.Type.ExtensionVersion)); + return setChildren; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionVersionResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionVersionResourceDefinition.java new file mode 100644 index 0000000..824640a --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ExtensionVersionResourceDefinition.java @@ -0,0 +1,54 @@ +/** + * 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.ambari.server.api.resources; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.ambari.server.controller.spi.Resource; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionVersionResourceDefinition extends BaseResourceDefinition { + + public ExtensionVersionResourceDefinition() { + super(Resource.Type.ExtensionVersion); + } + + @Override + public String getPluralName() { + return "versions"; + } + + @Override + public String getSingularName() { + return "version"; + } + + @Override + public Set<SubResourceDefinition> getSubResourceDefinitions() { + + Set<SubResourceDefinition> children = new HashSet<SubResourceDefinition>(); + + return children; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java index cf7c391..a2aeffa 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java @@ -187,6 +187,18 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory { resourceDefinition = new StackConfigurationDependencyResourceDefinition(); break; + case Extension: + resourceDefinition = new ExtensionResourceDefinition(); + break; + + case ExtensionVersion: + resourceDefinition = new ExtensionVersionResourceDefinition(); + break; + + case ExtensionLink: + resourceDefinition = new ExtensionLinkResourceDefinition(); + break; + case OperatingSystem: resourceDefinition = new OperatingSystemResourceDefinition(); break; http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java index f0928cf..92d47df 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java @@ -63,6 +63,7 @@ import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.ComponentInfo; import org.apache.ambari.server.state.DependencyInfo; +import org.apache.ambari.server.state.ExtensionInfo; import org.apache.ambari.server.state.OperatingSystemInfo; import org.apache.ambari.server.state.PropertyInfo; import org.apache.ambari.server.state.RepositoryInfo; @@ -108,12 +109,12 @@ public class AmbariMetaInfo { public static final String SERVICE_ADVISOR_FILE_NAME = "service_advisor.py"; /** - * The filename name for a Kerberos descriptor file at either the stack or service level + * The filename for a Kerberos descriptor file at either the stack or service level */ public static final String KERBEROS_DESCRIPTOR_FILE_NAME = "kerberos.json"; /** - * The filename name for a Widgets descriptor file at either the stack or service level + * The filename for a Widgets descriptor file at either the stack or service level */ public static final String WIDGETS_DESCRIPTOR_FILE_NAME = "widgets.json"; @@ -156,6 +157,7 @@ public class AmbariMetaInfo { private File stackRoot; private File commonServicesRoot; + private File extensionsRoot; private File serverVersionFile; private File customActionRoot; private Map<String, VersionDefinitionXml> versionDefinitions = null; @@ -237,6 +239,11 @@ public class AmbariMetaInfo { commonServicesRoot = new File(commonServicesPath); } + String extensionsPath = conf.getExtensionsPath(); + if (extensionsPath != null && !extensionsPath.isEmpty()) { + extensionsRoot = new File(extensionsPath); + } + String serverVersionFilePath = conf.getServerVersionFilePath(); serverVersionFile = new File(serverVersionFilePath); @@ -255,7 +262,7 @@ public class AmbariMetaInfo { readServerVersion(); - stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, + stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, extensionsRoot, osFamily, false); getCustomActionDefinitions(customActionRoot); @@ -629,6 +636,30 @@ public class AmbariMetaInfo { return parents; } + public Collection<ExtensionInfo> getExtensions() { + return stackManager.getExtensions(); + } + + public Collection<ExtensionInfo> getExtensions(String extensionName) throws AmbariException { + Collection<ExtensionInfo> extensions = stackManager.getExtensions(extensionName); + + if (extensions.isEmpty()) { + throw new StackAccessException("extensionName=" + extensionName); + } + + return extensions; + } + + public ExtensionInfo getExtension(String extensionName, String version) throws AmbariException { + ExtensionInfo result = stackManager.getExtension(extensionName, version); + + if (result == null) { + throw new StackAccessException("Extension " + extensionName + " " + version + " is not found in Ambari metainfo"); + } + + return result; + } + public Set<PropertyInfo> getServiceProperties(String stackName, String version, String serviceName) throws AmbariException { @@ -700,7 +731,6 @@ public class AmbariMetaInfo { return propertyResult; } - /** * Lists operatingsystems supported by stack */ @@ -862,6 +892,10 @@ public class AmbariMetaInfo { return stackRoot; } + public File getExtensionsRoot() { + return extensionsRoot; + } + /** * Return metrics for a stack service. */ http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionLinksService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionLinksService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionLinksService.java new file mode 100644 index 0000000..4bacfbf --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionLinksService.java @@ -0,0 +1,101 @@ +/** + * 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.ambari.server.api.services; + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.ambari.server.api.resources.ResourceInstance; +import org.apache.ambari.server.controller.spi.Resource; + +/** + * Service for extension link management. + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +@Path("/links/") +public class ExtensionLinksService extends BaseService { + + @GET + @Produces("text/plain") + public Response getExtensionLinks(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.GET, createExtensionLinkResource(null)); + } + + @GET + @Path("{linkId}") + @Produces("text/plain") + public Response getExtensionLink(String body, @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("linkId") String linkId) { + + return handleRequest(headers, body, ui, Request.Type.GET, createExtensionLinkResource(linkId)); + } + + @POST + @Produces("text/plain") + public Response createExtensionLink(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(headers, body, ui, Request.Type.POST, createExtensionLinkResource(null)); + } + + @DELETE + @Path("{linkId}") + @Produces("text/plain") + public Response deleteExtensionLink(@Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("linkId") String linkId) { + + return handleRequest(headers, null, ui, Request.Type.DELETE, createExtensionLinkResource(linkId)); + } + + @PUT + @Produces("text/plain") + public Response updateExtensionLink(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(headers, body, ui, Request.Type.PUT, createExtensionLinkResource(null)); + } + + @PUT + @Path("{linkId}") + @Produces("text/plain") + public Response updateExtensionLink(String body, @Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("linkId") String linkId) { + + return handleRequest(headers, body, ui, Request.Type.PUT, createExtensionLinkResource(linkId)); + } + + ResourceInstance createExtensionLinkResource(String linkId) { + Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.ExtensionLink, linkId); + return createResource(Resource.Type.ExtensionLink, mapIds); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionsService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionsService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionsService.java new file mode 100644 index 0000000..176c259 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ExtensionsService.java @@ -0,0 +1,127 @@ +/** + * 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.ambari.server.api.services; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.ambari.server.api.resources.ResourceInstance; +import org.apache.ambari.server.controller.spi.Resource; + +/** + * Service for extensions management. + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +@Path("/extensions/") +public class ExtensionsService extends BaseService { + + @GET + @Produces("text/plain") + public Response getExtensions(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionResource(null)); + } + + @GET + @Path("{extensionName}") + @Produces("text/plain") + public Response getExtension(String body, @Context HttpHeaders headers, + @Context UriInfo ui, + @PathParam("extensionName") String extensionName) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionResource(extensionName)); + } + + @GET + @Path("{extensionName}/versions") + @Produces("text/plain") + public Response getExtensionVersions(String body, + @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("extensionName") String extensionName) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionVersionResource(extensionName, null)); + } + + @GET + @Path("{extensionName}/versions/{extensionVersion}") + @Produces("text/plain") + public Response getExtensionVersion(String body, + @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("extensionName") String extensionName, + @PathParam("extensionVersion") String extensionVersion) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionVersionResource(extensionName, extensionVersion)); + } + + @GET + @Path("{extensionName}/versions/{extensionVersion}/links") + @Produces("text/plain") + public Response getExtensionVersionLinks(String body, + @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("extensionName") String extensionName, + @PathParam("extensionVersion") String extensionVersion) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionLinkResource(null, null, extensionName, extensionVersion)); + } + + ResourceInstance createExtensionVersionResource(String extensionName, + String extensionVersion) { + Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.Extension, extensionName); + mapIds.put(Resource.Type.ExtensionVersion, extensionVersion); + + return createResource(Resource.Type.ExtensionVersion, mapIds); + } + + ResourceInstance createExtensionLinkResource(String stackName, String stackVersion, + String extensionName, String extensionVersion) { + Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.Stack, stackName); + mapIds.put(Resource.Type.StackVersion, stackVersion); + mapIds.put(Resource.Type.Extension, extensionName); + mapIds.put(Resource.Type.ExtensionVersion, extensionVersion); + + return createResource(Resource.Type.ExtensionLink, mapIds); + } + + ResourceInstance createExtensionResource(String extensionName) { + + return createResource(Resource.Type.Extension, + Collections.singletonMap(Resource.Type.Extension, extensionName)); + + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java index 557ce98..2c85e01 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java @@ -83,6 +83,18 @@ public class StacksService extends BaseService { } @GET + @Path("{stackName}/versions/{stackVersion}/links") + @Produces("text/plain") + public Response getStackVersionLinks(String body, + @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("stackName") String stackName, + @PathParam("stackVersion") String stackVersion) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createExtensionLinkResource(stackName, stackVersion, null, null)); + } + + @GET @Path("{stackName}/versions/{stackVersion}/configurations") @Produces("text/plain") public Response getStackLevelConfigurations(String body, @Context HttpHeaders headers, @@ -491,6 +503,17 @@ public class StacksService extends BaseService { return createResource(Resource.Type.QuickLink, mapIds); } + ResourceInstance createExtensionLinkResource(String stackName, String stackVersion, + String extensionName, String extensionVersion) { + Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.Stack, stackName); + mapIds.put(Resource.Type.StackVersion, stackVersion); + mapIds.put(Resource.Type.Extension, extensionName); + mapIds.put(Resource.Type.ExtensionVersion, extensionVersion); + + return createResource(Resource.Type.ExtensionLink, mapIds); + } + ResourceInstance createStackResource(String stackName) { return createResource(Resource.Type.Stack, http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java index 2b7fca0..d736303 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java @@ -137,6 +137,7 @@ public class Configuration { public static final String RESOURCES_DIR_KEY = "resources.dir"; public static final String METADATA_DIR_PATH = "metadata.path"; public static final String COMMON_SERVICES_DIR_PATH = "common.services.path"; + public static final String EXTENSIONS_DIR_PATH = "extensions.path"; public static final String MPACKS_STAGING_DIR_PATH = "mpacks.staging.path"; public static final String SERVER_VERSION_FILE = "server.version.file"; public static final String SERVER_VERSION_KEY = "version"; @@ -1479,6 +1480,14 @@ public class Configuration { } /** + * Gets ambari extensions-path + * @return String + */ + public String getExtensionsPath() { + return properties.getProperty(EXTENSIONS_DIR_PATH); + } + + /** * Gets ambari management packs staging directory * @return String */ http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java index b488af3..947a9f4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java @@ -34,6 +34,7 @@ import org.apache.ambari.server.controller.metrics.timeline.cache.TimelineMetric import org.apache.ambari.server.events.AmbariEvent; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; import org.apache.ambari.server.metadata.RoleCommandOrder; +import org.apache.ambari.server.orm.entities.ExtensionLinkEntity; import org.apache.ambari.server.scheduler.ExecutionScheduleManager; import org.apache.ambari.server.security.authorization.AuthorizationException; import org.apache.ambari.server.security.encryption.CredentialStoreService; @@ -356,6 +357,52 @@ public interface AmbariManagementController { RequestStatusResponse updateStacks() throws AmbariException; /** + * Create a link between an extension and a stack + * + * @throws AmbariException if we fail to link the extension to the stack + */ + public void createExtensionLink(ExtensionLinkRequest request) throws AmbariException; + + /** + * Update a link between an extension and a stack + * + * @throws AmbariException if we fail to link the extension to the stack + */ + public void updateExtensionLink(ExtensionLinkRequest request) throws AmbariException; + + /** + * Update a link between an extension and a stack + * + * @throws AmbariException if we fail to link the extension to the stack + */ + public void updateExtensionLink(ExtensionLinkEntity linkEntity) throws AmbariException; + + /** + * Delete a link between an extension and a stack + * + * @throws AmbariException if we fail to unlink the extension from the stack + */ + public void deleteExtensionLink(ExtensionLinkRequest request) throws AmbariException; + + /** + * Get supported extensions. + * + * @param requests the extensions + * @return a set of extensions responses + * @throws AmbariException if the resources cannot be read + */ + public Set<ExtensionResponse> getExtensions(Set<ExtensionRequest> requests) throws AmbariException; + + /** + * Get supported extension versions. + * + * @param requests the extension versions + * @return a set of extension versions responses + * @throws AmbariException if the resources cannot be read + */ + public Set<ExtensionVersionResponse> getExtensionVersions(Set<ExtensionVersionRequest> requests) throws AmbariException; + + /** * Get supported stacks versions. * * @param requests the stacks versions @@ -366,7 +413,6 @@ public interface AmbariManagementController { */ Set<StackVersionResponse> getStackVersions(Set<StackVersionRequest> requests) throws AmbariException; - /** * Get repositories by stack name, version and operating system. * @@ -431,7 +477,6 @@ public interface AmbariManagementController { */ Set<StackServiceComponentResponse> getStackComponents(Set<StackServiceComponentRequest> requests) throws AmbariException; - /** * Get operating systems by stack name, version. * http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java index b5c6fc2..7dbb1ad 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java @@ -65,6 +65,8 @@ import java.util.TreeMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; +import javax.persistence.RollbackException; + import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.ClusterNotFoundException; import org.apache.ambari.server.DuplicateResourceException; @@ -102,14 +104,20 @@ import org.apache.ambari.server.metadata.ActionMetadata; import org.apache.ambari.server.metadata.RoleCommandOrder; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.dao.ClusterVersionDAO; +import org.apache.ambari.server.orm.dao.ExtensionDAO; +import org.apache.ambari.server.orm.dao.ExtensionLinkDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; +import org.apache.ambari.server.orm.dao.StackDAO; import org.apache.ambari.server.orm.dao.WidgetDAO; import org.apache.ambari.server.orm.dao.WidgetLayoutDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.ClusterVersionEntity; +import org.apache.ambari.server.orm.entities.ExtensionEntity; +import org.apache.ambari.server.orm.entities.ExtensionLinkEntity; import org.apache.ambari.server.orm.entities.OperatingSystemEntity; import org.apache.ambari.server.orm.entities.RepositoryEntity; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.orm.entities.StackEntity; import org.apache.ambari.server.orm.entities.WidgetEntity; import org.apache.ambari.server.orm.entities.WidgetLayoutEntity; import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity; @@ -129,6 +137,8 @@ import org.apache.ambari.server.security.ldap.LdapBatchDto; import org.apache.ambari.server.security.ldap.LdapSyncDto; import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException; import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException; +import org.apache.ambari.server.stack.ExtensionHelper; +import org.apache.ambari.server.stack.StackManager; import org.apache.ambari.server.stageplanner.RoleGraph; import org.apache.ambari.server.stageplanner.RoleGraphFactory; import org.apache.ambari.server.state.Cluster; @@ -139,6 +149,7 @@ import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigFactory; import org.apache.ambari.server.state.ConfigHelper; import org.apache.ambari.server.state.DesiredConfig; +import org.apache.ambari.server.state.ExtensionInfo; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.HostComponentAdminState; import org.apache.ambari.server.state.HostState; @@ -166,6 +177,7 @@ import org.apache.ambari.server.state.configgroup.ConfigGroupFactory; import org.apache.ambari.server.state.repository.VersionDefinitionXml; import org.apache.ambari.server.state.scheduler.RequestExecutionFactory; import org.apache.ambari.server.state.stack.RepositoryXml; +import org.apache.ambari.server.state.stack.ServiceMetainfoXml; import org.apache.ambari.server.state.stack.WidgetLayout; import org.apache.ambari.server.state.stack.WidgetLayoutInfo; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent; @@ -271,6 +283,13 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle private MaintenanceStateHelper maintenanceStateHelper; + @Inject + private ExtensionLinkDAO linkDAO; + @Inject + private ExtensionDAO extensionDAO; + @Inject + private StackDAO stackDAO; + /** * The KerberosHelper to help setup for enabling for disabling Kerberos */ @@ -3783,6 +3802,94 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle } @Override + public Set<ExtensionResponse> getExtensions(Set<ExtensionRequest> requests) + throws AmbariException { + Set<ExtensionResponse> response = new HashSet<ExtensionResponse>(); + for (ExtensionRequest request : requests) { + try { + response.addAll(getExtensions(request)); + } catch (StackAccessException e) { + if (requests.size() == 1) { + // only throw exception if 1 request. + // there will be > 1 request in case of OR predicate + throw e; + } + } + } + return response; + + } + + + private Set<ExtensionResponse> getExtensions(ExtensionRequest request) + throws AmbariException { + Set<ExtensionResponse> response; + + String extensionName = request.getExtensionName(); + + if (extensionName != null) { + // this will throw an exception if the extension doesn't exist + ambariMetaInfo.getExtensions(extensionName); + response = Collections.singleton(new ExtensionResponse(extensionName)); + } else { + Collection<ExtensionInfo> supportedExtensions = ambariMetaInfo.getExtensions(); + response = new HashSet<ExtensionResponse>(); + for (ExtensionInfo extension: supportedExtensions) { + response.add(new ExtensionResponse(extension.getName())); + } + } + return response; + } + + @Override + public Set<ExtensionVersionResponse> getExtensionVersions( + Set<ExtensionVersionRequest> requests) throws AmbariException { + Set<ExtensionVersionResponse> response = new HashSet<ExtensionVersionResponse>(); + for (ExtensionVersionRequest request : requests) { + String extensionName = request.getExtensionName(); + try { + Set<ExtensionVersionResponse> stackVersions = getExtensionVersions(request); + for (ExtensionVersionResponse stackVersionResponse : stackVersions) { + stackVersionResponse.setExtensionName(extensionName); + } + response.addAll(stackVersions); + } catch (StackAccessException e) { + if (requests.size() == 1) { + // only throw exception if 1 request. + // there will be > 1 request in case of OR predicate + throw e; + } + } + } + + return response; + } + + private Set<ExtensionVersionResponse> getExtensionVersions(ExtensionVersionRequest request) throws AmbariException { + Set<ExtensionVersionResponse> response; + + String extensionName = request.getExtensionName(); + String extensionVersion = request.getExtensionVersion(); + + if (extensionVersion != null) { + ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(extensionName, extensionVersion); + response = Collections.singleton(extensionInfo.convertToResponse()); + } else { + try { + Collection<ExtensionInfo> extensionInfos = ambariMetaInfo.getExtensions(extensionName); + response = new HashSet<ExtensionVersionResponse>(); + for (ExtensionInfo extensionInfo: extensionInfos) { + response.add(extensionInfo.convertToResponse()); + } + } catch (StackAccessException e) { + response = Collections.emptySet(); + } + } + + return response; + } + + @Override public Set<RepositoryResponse> getRepositories(Set<RepositoryRequest> requests) throws AmbariException { Set<RepositoryResponse> response = new HashSet<RepositoryResponse>(); @@ -4848,4 +4955,167 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle } } } + + /** + * This method will delete a link between an extension version and a stack version (Extension Link). + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ + @Override + public void deleteExtensionLink(ExtensionLinkRequest request) throws AmbariException { + if (request.getLinkId() == null) { + throw new IllegalArgumentException("Link ID should be provided"); + } + ExtensionLinkEntity linkEntity = null; + try { + linkEntity = linkDAO.findById(new Long(request.getLinkId())); + } catch (RollbackException e) { + throw new AmbariException("Unable to find extension link" + + ", linkId=" + request.getLinkId(), e); + } + + StackInfo stackInfo = ambariMetaInfo.getStack(linkEntity.getStack().getStackName(), linkEntity.getStack().getStackVersion()); + + if (stackInfo == null) + throw new StackAccessException("stackName=" + linkEntity.getStack().getStackName() + ", stackVersion=" + linkEntity.getStack().getStackVersion()); + + ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(linkEntity.getExtension().getExtensionName(), linkEntity.getExtension().getExtensionVersion()); + + if (extensionInfo == null) + throw new StackAccessException("extensionName=" + linkEntity.getExtension().getExtensionName() + ", extensionVersion=" + linkEntity.getExtension().getExtensionVersion()); + + ExtensionHelper.validateDeleteLink(getClusters(), stackInfo, extensionInfo); + ambariMetaInfo.getStackManager().unlinkStackAndExtension(stackInfo, extensionInfo); + + try { + linkDAO.remove(linkEntity); + } catch (RollbackException e) { + throw new AmbariException("Unable to delete extension link" + + ", linkId=" + request.getLinkId() + + ", stackName=" + request.getStackName() + + ", stackVersion=" + request.getStackVersion() + + ", extensionName=" + request.getExtensionName() + + ", extensionVersion=" + request.getExtensionVersion(), e); + } + } + + /** + * This method will create a link between an extension version and a stack version (Extension Link). + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ + @Override + public void createExtensionLink(ExtensionLinkRequest request) throws AmbariException { + validateCreateExtensionLinkRequest(request); + + StackInfo stackInfo = ambariMetaInfo.getStack(request.getStackName(), request.getStackVersion()); + + if (stackInfo == null) + throw new StackAccessException("stackName=" + request.getStackName() + ", stackVersion=" + request.getStackVersion()); + + ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(request.getExtensionName(), request.getExtensionVersion()); + + if (extensionInfo == null) + throw new StackAccessException("extensionName=" + request.getExtensionName() + ", extensionVersion=" + request.getExtensionVersion()); + + ExtensionHelper.validateCreateLink(stackInfo, extensionInfo); + ExtensionLinkEntity linkEntity = createExtensionLinkEntity(request); + ambariMetaInfo.getStackManager().linkStackToExtension(stackInfo, extensionInfo); + + try { + linkDAO.create(linkEntity); + linkEntity = linkDAO.merge(linkEntity); + } catch (RollbackException e) { + String message = "Unable to create extension link"; + LOG.debug(message, e); + String errorMessage = message + + ", stackName=" + request.getStackName() + + ", stackVersion=" + request.getStackVersion() + + ", extensionName=" + request.getExtensionName() + + ", extensionVersion=" + request.getExtensionVersion(); + LOG.warn(errorMessage); + throw new AmbariException(errorMessage, e); + } + } + + /** + * This method will update a link between an extension version and a stack version (Extension Link). + * Updating will only force ambari server to reread the stack and extension directories. + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ + @Override + public void updateExtensionLink(ExtensionLinkRequest request) throws AmbariException { + if (request.getLinkId() == null) { + throw new AmbariException("Link ID should be provided"); + } + ExtensionLinkEntity linkEntity = null; + try { + linkEntity = linkDAO.findById(new Long(request.getLinkId())); + } catch (RollbackException e) { + throw new AmbariException("Unable to find extension link" + + ", linkId=" + request.getLinkId(), e); + } + updateExtensionLink(linkEntity); + } + + /** + * This method will update a link between an extension version and a stack version (Extension Link). + * Updating will only force ambari server to reread the stack and extension directories. + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ + @Override + public void updateExtensionLink(ExtensionLinkEntity linkEntity) throws AmbariException { + StackInfo stackInfo = ambariMetaInfo.getStack(linkEntity.getStack().getStackName(), linkEntity.getStack().getStackVersion()); + + if (stackInfo == null) + throw new StackAccessException("stackName=" + linkEntity.getStack().getStackName() + ", stackVersion=" + linkEntity.getStack().getStackVersion()); + + ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(linkEntity.getExtension().getExtensionName(), linkEntity.getExtension().getExtensionVersion()); + + if (extensionInfo == null) + throw new StackAccessException("extensionName=" + linkEntity.getExtension().getExtensionName() + ", extensionVersion=" + linkEntity.getExtension().getExtensionVersion()); + + ambariMetaInfo.getStackManager().linkStackToExtension(stackInfo, extensionInfo); + } + + private void validateCreateExtensionLinkRequest(ExtensionLinkRequest request) throws AmbariException { + if (request.getStackName() == null + || request.getStackVersion() == null + || request.getExtensionName() == null + || request.getExtensionVersion() == null) { + + throw new IllegalArgumentException("Stack name, stack version, extension name and extension version should be provided"); + } + + ExtensionLinkEntity entity = linkDAO.findByStackAndExtension(request.getStackName(), request.getStackVersion(), + request.getExtensionName(), request.getExtensionVersion()); + + if (entity != null) { + throw new AmbariException("The stack and extension are already linked" + + ", stackName=" + request.getStackName() + + ", stackVersion=" + request.getStackVersion() + + ", extensionName=" + request.getExtensionName() + + ", extensionVersion=" + request.getExtensionVersion()); + } + } + + private ExtensionLinkEntity createExtensionLinkEntity(ExtensionLinkRequest request) throws AmbariException { + StackEntity stack = stackDAO.find(request.getStackName(), request.getStackVersion()); + ExtensionEntity extension = extensionDAO.find(request.getExtensionName(), request.getExtensionVersion()); + + ExtensionLinkEntity linkEntity = new ExtensionLinkEntity(); + linkEntity.setStack(stack); + linkEntity.setExtension(extension); + return linkEntity; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkRequest.java new file mode 100644 index 0000000..2c61de0 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkRequest.java @@ -0,0 +1,86 @@ +/** + * 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.ambari.server.controller; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionLinkRequest { + + private String linkId; + + private String stackName; + + private String stackVersion; + + private String extensionName; + + private String extensionVersion; + + public ExtensionLinkRequest(String linkId, String stackName, String stackVersion, String extensionName, String extensionVersion) { + this.setLinkId(linkId); + this.setStackName(stackName); + this.setStackVersion(stackVersion); + this.setExtensionName(extensionName); + this.setExtensionVersion(extensionVersion); + } + + public String getLinkId() { + return linkId; + } + + public void setLinkId(String linkId) { + this.linkId = linkId; + } + + public String getStackName() { + return stackName; + } + + public void setStackName(String stackName) { + this.stackName = stackName; + } + + public String getStackVersion() { + return stackVersion; + } + + public void setStackVersion(String stackVersion) { + this.stackVersion = stackVersion; + } + + public String getExtensionName() { + return extensionName; + } + + public void setExtensionName(String extensionName) { + this.extensionName = extensionName; + } + + public String getExtensionVersion() { + return extensionVersion; + } + + public void setExtensionVersion(String extensionVersion) { + this.extensionVersion = extensionVersion; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkResponse.java new file mode 100644 index 0000000..df262b8 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionLinkResponse.java @@ -0,0 +1,124 @@ +/** + * 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.ambari.server.controller; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.apache.ambari.server.stack.Validable; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionLinkResponse implements Validable { + + private String linkId; + + private String stackName; + + private String stackVersion; + + private String extensionName; + + private String extensionVersion; + + private boolean valid; + + private Set<String> errorSet = new HashSet<String>(); + + public ExtensionLinkResponse(String linkId, String stackName, String stackVersion, String extensionName, + String extensionVersion, boolean valid, Collection errorSet) { + + setLinkId(linkId); + setStackName(stackName); + setStackVersion(stackVersion); + setExtensionName(extensionName); + setExtensionVersion(extensionVersion); + setValid(valid); + addErrors(errorSet); + } + + public String getLinkId() { + return linkId; + } + + public void setLinkId(String linkId) { + this.linkId = linkId; + } + + public String getStackName() { + return stackName; + } + + public void setStackName(String stackName) { + this.stackName = stackName; + } + + public String getStackVersion() { + return stackVersion; + } + + public void setStackVersion(String stackVersion) { + this.stackVersion = stackVersion; + } + + public String getExtensionName() { + return extensionName; + } + + public void setExtensionName(String extensionName) { + this.extensionName = extensionName; + } + + public String getExtensionVersion() { + return extensionVersion; + } + + public void setExtensionVersion(String extensionVersion) { + this.extensionVersion = extensionVersion; + } + + @Override + public boolean isValid() { + return valid; + } + + @Override + public void setValid(boolean valid) { + this.valid = valid; + } + + @Override + public void addError(String error) { + errorSet.add(error); + } + + @Override + public Collection<String> getErrors() { + return errorSet; + } + + @Override + public void addErrors(Collection<String> errors) { + this.errorSet.addAll(errors); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionRequest.java new file mode 100644 index 0000000..f825c7b --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionRequest.java @@ -0,0 +1,43 @@ +/** + * 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.ambari.server.controller; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionRequest { + + public ExtensionRequest(String extensionName) { + this.setExtensionName(extensionName); + + } + + public String getExtensionName() { + return extensionName; + } + + public void setExtensionName(String extensionName) { + this.extensionName = extensionName; + } + + private String extensionName; + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionResponse.java new file mode 100644 index 0000000..50ab439 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionResponse.java @@ -0,0 +1,61 @@ +/** + * 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.ambari.server.controller; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionResponse { + + private String extensionName; + + public ExtensionResponse(String extensionName) { + setExtensionName(extensionName); + } + + public String getExtensionName() { + return extensionName; + } + + public void setExtensionName(String extensionName) { + this.extensionName = extensionName; + } + + @Override + public int hashCode() { + int result = 1; + result = 31 + getExtensionName().hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ExtensionResponse)) { + return false; + } + if (this == obj) { + return true; + } + ExtensionResponse extensionResponse = (ExtensionResponse) obj; + return getExtensionName().equals(extensionResponse.getExtensionName()); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionRequest.java new file mode 100644 index 0000000..32228f7 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionRequest.java @@ -0,0 +1,44 @@ +/** + * 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.ambari.server.controller; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionVersionRequest extends ExtensionRequest { + + public ExtensionVersionRequest(String extensionName, String extensionVersion) { + super(extensionName); + setExtensionVersion(extensionVersion); + } + + public String getExtensionVersion() { + return extensionVersion; + } + + public void setExtensionVersion(String extensionVersion) { + this.extensionVersion = extensionVersion; + } + + private String extensionVersion; + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionResponse.java new file mode 100644 index 0000000..bf2db5c --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExtensionVersionResponse.java @@ -0,0 +1,101 @@ +/** + * 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.ambari.server.controller; + +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.stack.Validable; + +/** + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class ExtensionVersionResponse implements Validable{ + + private String extensionName; + private String extensionVersion; + private boolean valid; + private String parentVersion; + + public ExtensionVersionResponse(String extensionVersion, String parentVersion, + boolean valid, Collection errorSet) { + setExtensionVersion(extensionVersion); + setParentVersion(parentVersion); + setValid(valid); + addErrors(errorSet); + } + + @Override + public boolean isValid() { + return valid; + } + + @Override + public void setValid(boolean valid) { + this.valid = valid; + } + + private Set<String> errorSet = new HashSet<String>(); + + @Override + public void addError(String error) { + errorSet.add(error); + } + + @Override + public Collection<String> getErrors() { + return errorSet; + } + + @Override + public void addErrors(Collection<String> errors) { + this.errorSet.addAll(errors); + } + + + public String getExtensionName() { + return extensionName; + } + + public void setExtensionName(String extensionName) { + this.extensionName = extensionName; + } + + public String getExtensionVersion() { + return extensionVersion; + } + + public void setExtensionVersion(String extensionVersion) { + this.extensionVersion = extensionVersion; + } + + public String getParentVersion() { + return parentVersion; + } + + public void setParentVersion(String parentVersion) { + this.parentVersion = parentVersion; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java index 3721113..b26814a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java @@ -173,6 +173,12 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori return new StackConfigurationDependencyResourceProvider(propertyIds, keyPropertyIds, managementController); case StackLevelConfiguration: return new StackLevelConfigurationResourceProvider(propertyIds, keyPropertyIds, managementController); + case ExtensionLink: + return new ExtensionLinkResourceProvider(propertyIds, keyPropertyIds, managementController); + case Extension: + return new ExtensionResourceProvider(propertyIds, keyPropertyIds, managementController); + case ExtensionVersion: + return new ExtensionVersionResourceProvider(propertyIds, keyPropertyIds, managementController); case RootService: return new RootServiceResourceProvider(propertyIds, keyPropertyIds, managementController); case RootServiceComponent: http://git-wip-us.apache.org/repos/asf/ambari/blob/300a7e21/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Extension.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Extension.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Extension.java new file mode 100644 index 0000000..682adb8 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Extension.java @@ -0,0 +1,282 @@ +/** + * 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.ambari.server.controller.internal; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.orm.entities.ExtensionEntity; +import org.apache.ambari.server.state.AutoDeployInfo; +import org.apache.ambari.server.state.ComponentInfo; +import org.apache.ambari.server.state.DependencyInfo; +import org.apache.ambari.server.state.PropertyInfo; +import org.apache.ambari.server.topology.Cardinality; +import org.apache.ambari.server.topology.Configuration; + +/** + * Encapsulates extension information. + * + * An extension version is like a stack version but it contains custom services. Linking an extension + * version to the current stack version allows the cluster to install the custom services contained in + * the extension version. + */ +public class Extension { + /** + * Extension name + */ + private String name; + + /** + * Extension version + */ + private String version; + + /** + * Map of service name to components + */ + private Map<String, Collection<String>> serviceComponents = + new HashMap<String, Collection<String>>(); + + /** + * Map of component to service + */ + private Map<String, String> componentService = new HashMap<String, String>(); + + /** + * Map of component to dependencies + */ + private Map<String, Collection<DependencyInfo>> dependencies = + new HashMap<String, Collection<DependencyInfo>>(); + + /** + * Map of dependency to conditional service + */ + private Map<DependencyInfo, String> dependencyConditionalServiceMap = + new HashMap<DependencyInfo, String>(); + + /** + * Map of database component name to configuration property which indicates whether + * the database in to be managed or if it is an external non-managed instance. + * If the value of the config property starts with 'New', the database is determined + * to be managed, otherwise it is non-managed. + */ + private Map<String, String> dbDependencyInfo = new HashMap<String, String>(); + + /** + * Map of component to required cardinality + */ + private Map<String, String> cardinalityRequirements = new HashMap<String, String>(); + + /** + * Map of component to auto-deploy information + */ + private Map<String, AutoDeployInfo> componentAutoDeployInfo = + new HashMap<String, AutoDeployInfo>(); + + /** + * Ambari Management Controller, used to obtain Extension definitions + */ + private final AmbariManagementController controller; + + + /** + * Constructor. + * + * @param extension + * the extension (not {@code null}). + * @param ambariManagementController + * the management controller (not {@code null}). + * @throws AmbariException + */ + public Extension(ExtensionEntity extension, AmbariManagementController ambariManagementController) throws AmbariException { + this(extension.getExtensionName(), extension.getExtensionVersion(), ambariManagementController); + } + + /** + * Constructor. + * + * @param name extension name + * @param version extension version + * + * @throws AmbariException an exception occurred getting extension information + * for the specified name and version + */ + //todo: don't pass management controller in constructor + public Extension(String name, String version, AmbariManagementController controller) throws AmbariException { + this.name = name; + this.version = version; + this.controller = controller; + } + + /** + * Obtain extension name. + * + * @return extension name + */ + public String getName() { + return name; + } + + /** + * Obtain extension version. + * + * @return extension version + */ + public String getVersion() { + return version; + } + + + Map<DependencyInfo, String> getDependencyConditionalServiceMap() { + return dependencyConditionalServiceMap; + } + + /** + * Get services contained in the extension. + * + * @return collection of all services for the extension + */ + public Collection<String> getServices() { + return serviceComponents.keySet(); + } + + /** + * Get components contained in the extension for the specified service. + * + * @param service service name + * + * @return collection of component names for the specified service + */ + public Collection<String> getComponents(String service) { + return serviceComponents.get(service); + } + + /** + * Get all service components + * + * @return map of service to associated components + */ + public Map<String, Collection<String>> getComponents() { + Map<String, Collection<String>> serviceComponents = new HashMap<String, Collection<String>>(); + for (String service : getServices()) { + Collection<String> components = new HashSet<String>(); + components.addAll(getComponents(service)); + serviceComponents.put(service, components); + } + return serviceComponents; + } + + /** + * Get info for the specified component. + * + * @param component component name + * + * @return component information for the requested component + * or null if the component doesn't exist in the extension + */ + public ComponentInfo getComponentInfo(String component) { + ComponentInfo componentInfo = null; + String service = getServiceForComponent(component); + if (service != null) { + try { + componentInfo = controller.getAmbariMetaInfo().getComponent( + getName(), getVersion(), service, component); + } catch (AmbariException e) { + // just return null if component doesn't exist + } + } + return componentInfo; + } + + /** + * Get the service for the specified component. + * + * @param component component name + * + * @return service name that contains tha specified component + */ + public String getServiceForComponent(String component) { + return componentService.get(component); + } + + /** + * Get the names of the services which contains the specified components. + * + * @param components collection of components + * + * @return collection of services which contain the specified components + */ + public Collection<String> getServicesForComponents(Collection<String> components) { + Set<String> services = new HashSet<String>(); + for (String component : components) { + services.add(getServiceForComponent(component)); + } + + return services; + } + + /** + * Return the dependencies specified for the given component. + * + * @param component component to get dependency information for + * + * @return collection of dependency information for the specified component + */ + //todo: full dependency graph + public Collection<DependencyInfo> getDependenciesForComponent(String component) { + return dependencies.containsKey(component) ? dependencies.get(component) : + Collections.<DependencyInfo>emptySet(); + } + + /** + * Get the service, if any, that a component dependency is conditional on. + * + * @param dependency dependency to get conditional service for + * + * @return conditional service for provided component or null if dependency + * is not conditional on a service + */ + public String getConditionalServiceForDependency(DependencyInfo dependency) { + return dependencyConditionalServiceMap.get(dependency); + } + + public String getExternalComponentConfig(String component) { + return dbDependencyInfo.get(component); + } + + /** + * Obtain the required cardinality for the specified component. + */ + public Cardinality getCardinality(String component) { + return new Cardinality(cardinalityRequirements.get(component)); + } + + /** + * Obtain auto-deploy information for the specified component. + */ + public AutoDeployInfo getAutoDeployInfo(String component) { + return componentAutoDeployInfo.get(component); + } +}
