You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by di...@apache.org on 2016/01/11 20:15:45 UTC
[09/13] ambari git commit: AMBARI-12885: Dynamic stack extensions -
install and upgrade support for custom services (tthorpe via dili)
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionArtifactResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionArtifactResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionArtifactResourceProvider.java
new file mode 100644
index 0000000..2a0379b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionArtifactResourceProvider.java
@@ -0,0 +1,658 @@
+/**
+ * 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 com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.rits.cloning.Cloner;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StackAccessException;
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.ExtensionInfo;
+import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
+import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
+import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
+import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
+import org.apache.ambari.server.state.stack.Metric;
+import org.apache.ambari.server.state.stack.MetricDefinition;
+import org.apache.ambari.server.state.stack.WidgetLayout;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provider for extension and extension service artifacts.
+ * Artifacts contain an artifact name as the PK and artifact data in the form of
+ * a map which is the content of the artifact.
+ * <p>
+ * An example of an artifact is a kerberos descriptor.
+ * <p>
+ * Extension artifacts are part of the extension definition and therefore can't
+ * be created, updated or deleted.
+ */
+@StaticallyInject
+public class ExtensionArtifactResourceProvider extends AbstractControllerResourceProvider {
+ /**
+ * extension name
+ */
+ public static final String EXTENSION_NAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Artifacts", "extension_name");
+
+ /**
+ * extension version
+ */
+ public static final String EXTENSION_VERSION_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Artifacts", "extension_version");
+
+ /**
+ * extension service name
+ */
+ public static final String EXTENSION_SERVICE_NAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Artifacts", "service_name");
+
+ /**
+ * extension service name
+ */
+ public static final String EXTENSION_COMPONENT_NAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Artifacts", "component_name");
+
+ /**
+ * artifact name
+ */
+ public static final String ARTIFACT_NAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Artifacts", "artifact_name");
+
+ /**
+ * artifact data
+ */
+ public static final String ARTIFACT_DATA_PROPERTY_ID = "artifact_data";
+
+ /**
+ * primary key fields
+ */
+ public static Set<String> pkPropertyIds = new HashSet<String>();
+
+ /**
+ * map of resource type to fk field
+ */
+ public static Map<Resource.Type, String> keyPropertyIds =
+ new HashMap<Resource.Type, String>();
+
+ /**
+ * resource properties
+ */
+ public static Set<String> propertyIds = new HashSet<String>();
+
+ /**
+ * name of the kerberos descriptor artifact.
+ */
+ public static final String KERBEROS_DESCRIPTOR_NAME = "kerberos_descriptor";
+
+ /**
+ * name of the metrics descriptor artifact.
+ */
+ public static final String METRICS_DESCRIPTOR_NAME = "metrics_descriptor";
+
+ /**
+ * name of the widgets descriptor artifact.
+ */
+ public static final String WIDGETS_DESCRIPTOR_NAME = "widgets_descriptor";
+
+ /**
+ * KerberosDescriptorFactory used to create KerberosDescriptor instances
+ */
+ @Inject
+ private static KerberosDescriptorFactory kerberosDescriptorFactory;
+
+ /**
+ * KerberosServiceDescriptorFactory used to create KerberosServiceDescriptor instances
+ */
+ @Inject
+ private static KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory;
+
+ Type widgetLayoutType = new TypeToken<Map<String, List<WidgetLayout>>>(){}.getType();
+ Gson gson = new Gson();
+
+ /**
+ * set resource properties, pk and fk's
+ */
+ static {
+ // resource properties
+ propertyIds.add(EXTENSION_NAME_PROPERTY_ID);
+ propertyIds.add(EXTENSION_VERSION_PROPERTY_ID);
+ propertyIds.add(EXTENSION_SERVICE_NAME_PROPERTY_ID);
+ propertyIds.add(ARTIFACT_NAME_PROPERTY_ID);
+ propertyIds.add(ARTIFACT_DATA_PROPERTY_ID);
+
+ // pk property
+ pkPropertyIds.add(ARTIFACT_NAME_PROPERTY_ID);
+
+ // fk properties
+ keyPropertyIds.put(Resource.Type.ExtensionArtifact, ARTIFACT_NAME_PROPERTY_ID);
+ keyPropertyIds.put(Resource.Type.Extension, EXTENSION_NAME_PROPERTY_ID);
+ keyPropertyIds.put(Resource.Type.ExtensionVersion, EXTENSION_VERSION_PROPERTY_ID);
+ keyPropertyIds.put(Resource.Type.ExtensionService, EXTENSION_SERVICE_NAME_PROPERTY_ID);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param managementController ambari controller
+ */
+ protected ExtensionArtifactResourceProvider(AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException,
+ UnsupportedPropertyException,
+ NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ resources.addAll(getKerberosDescriptors(request, predicate));
+ resources.addAll(getMetricsDescriptors(request, predicate));
+ resources.addAll(getWidgetsDescriptors(request, predicate));
+ // add other artifacts types here
+
+ if (resources.isEmpty()) {
+ throw new NoSuchResourceException(
+ "The requested resource doesn't exist: Artifact not found, " + predicate);
+ }
+
+ return resources;
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException,
+ UnsupportedPropertyException,
+ ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException("Creating extension artifacts is not supported");
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException,
+ UnsupportedPropertyException,
+ NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException("Updating of extension artifacts is not supported");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException,
+ UnsupportedPropertyException,
+ NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException("Deletion of extension artifacts is not supported");
+ }
+
+ /**
+ * Get all extension and extension service kerberos descriptor resources.
+ *
+ * @param request user request
+ * @param predicate request predicate
+ *
+ * @return set of all extension related kerberos descriptor resources; will not return null
+ *
+ * @throws SystemException if an unexpected exception occurs
+ * @throws UnsupportedPropertyException if an unsupported property was requested
+ * @throws NoSuchParentResourceException if a specified parent resource doesn't exist
+ * @throws NoSuchResourceException if the requested resource doesn't exist
+ */
+ private Set<Resource> getKerberosDescriptors(Request request, Predicate predicate)
+ throws SystemException,
+ UnsupportedPropertyException,
+ NoSuchParentResourceException,
+ NoSuchResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (Map<String, Object> properties : getPropertyMaps(predicate)) {
+ String artifactName = (String) properties.get(ARTIFACT_NAME_PROPERTY_ID);
+ if (artifactName == null || artifactName.equals(KERBEROS_DESCRIPTOR_NAME)) {
+ String extensionName = (String) properties.get(EXTENSION_NAME_PROPERTY_ID);
+ String extensionVersion = (String) properties.get(EXTENSION_VERSION_PROPERTY_ID);
+ String extensionService = (String) properties.get(EXTENSION_SERVICE_NAME_PROPERTY_ID);
+
+ Map<String, Object> descriptor;
+ try {
+ descriptor = getKerberosDescriptor(extensionName, extensionVersion, extensionService);
+ } catch (IOException e) {
+ LOG.error("Unable to process Kerberos Descriptor. Properties: " + properties, e);
+ throw new SystemException("An internal exception occurred while attempting to build a Kerberos Descriptor " +
+ "artifact. See ambari server logs for more information", e);
+ }
+
+ if (descriptor != null) {
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionArtifact);
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ setResourceProperty(resource, ARTIFACT_NAME_PROPERTY_ID, KERBEROS_DESCRIPTOR_NAME, requestedIds);
+ setResourceProperty(resource, ARTIFACT_DATA_PROPERTY_ID, descriptor, requestedIds);
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID, extensionName, requestedIds);
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID, extensionVersion, requestedIds);
+ if (extensionService != null) {
+ setResourceProperty(resource, EXTENSION_SERVICE_NAME_PROPERTY_ID, extensionService, requestedIds);
+ }
+ resources.add(resource);
+ }
+ }
+ }
+ return resources;
+ }
+
+ /**
+ * Get all extension and extension service metrics descriptor resources.
+ *
+ * @param request user request
+ * @param predicate request predicate
+ *
+ * @return set of all extension related kerberos descriptor resources; will not return null
+ *
+ * @throws SystemException if an unexpected exception occurs
+ * @throws UnsupportedPropertyException if an unsupported property was requested
+ * @throws NoSuchParentResourceException if a specified parent resource doesn't exist
+ * @throws NoSuchResourceException if the requested resource doesn't exist
+ */
+ private Set<Resource> getMetricsDescriptors(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchParentResourceException, NoSuchResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (Map<String, Object> properties : getPropertyMaps(predicate)) {
+ String artifactName = (String) properties.get(ARTIFACT_NAME_PROPERTY_ID);
+ if (artifactName == null || artifactName.equals(METRICS_DESCRIPTOR_NAME)) {
+ String extensionName = (String) properties.get(EXTENSION_NAME_PROPERTY_ID);
+ String extensionVersion = (String) properties.get(EXTENSION_VERSION_PROPERTY_ID);
+ String extensionService = (String) properties.get(EXTENSION_SERVICE_NAME_PROPERTY_ID);
+ String componentName = (String) properties.get(EXTENSION_COMPONENT_NAME_PROPERTY_ID);
+
+ Map<String, Object> descriptor;
+ AmbariMetaInfo metaInfo = getManagementController().getAmbariMetaInfo();
+
+ try {
+ List<MetricDefinition> componentMetrics;
+ Map<String, Map<String, List<MetricDefinition>>> serviceMetrics;
+ if (extensionService != null) {
+ if (componentName == null) {
+ // Service
+ serviceMetrics = removeAggregateFunctions(metaInfo.getExtensionServiceMetrics(extensionName,
+ extensionVersion, extensionService));
+ descriptor = Collections.singletonMap(extensionService, (Object) serviceMetrics);
+ } else {
+ // Component
+ componentMetrics = removeAggregateFunctions(metaInfo.getExtensionMetrics(extensionName,
+ extensionVersion, extensionService, componentName, Resource.Type.Component.name()));
+ descriptor = Collections.singletonMap(componentName, (Object) componentMetrics);
+ }
+ } else {
+ // Cluster
+ Map<String, Map<String, PropertyInfo>> clusterMetrics =
+ PropertyHelper.getMetricPropertyIds(Resource.Type.Cluster);
+ // Host
+ Map<String, Map<String, PropertyInfo>> hostMetrics =
+ PropertyHelper.getMetricPropertyIds(Resource.Type.Host);
+
+ descriptor = new HashMap<String, Object>();
+ descriptor.put(Resource.Type.Cluster.name(), clusterMetrics);
+ descriptor.put(Resource.Type.Host.name(), hostMetrics);
+ }
+
+
+ } catch (IOException e) {
+ LOG.error("Unable to process Metrics Descriptor. Properties: " + properties, e);
+ throw new SystemException("An internal exception occurred while attempting to build a Metrics Descriptor " +
+ "artifact. See ambari server logs for more information", e);
+ }
+
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionArtifact);
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ setResourceProperty(resource, ARTIFACT_NAME_PROPERTY_ID, METRICS_DESCRIPTOR_NAME, requestedIds);
+ setResourceProperty(resource, ARTIFACT_DATA_PROPERTY_ID, descriptor, requestedIds);
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID, extensionName, requestedIds);
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID, extensionVersion, requestedIds);
+ if (extensionService != null) {
+ setResourceProperty(resource, EXTENSION_SERVICE_NAME_PROPERTY_ID, extensionService, requestedIds);
+ }
+ resources.add(resource);
+ }
+ }
+ return resources;
+ }
+
+ private Set<Resource> getWidgetsDescriptors(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchParentResourceException, NoSuchResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (Map<String, Object> properties : getPropertyMaps(predicate)) {
+ String artifactName = (String) properties.get(ARTIFACT_NAME_PROPERTY_ID);
+ if (artifactName == null || artifactName.equals(WIDGETS_DESCRIPTOR_NAME)) {
+ String extensionName = (String) properties.get(EXTENSION_NAME_PROPERTY_ID);
+ String extensionVersion = (String) properties.get(EXTENSION_VERSION_PROPERTY_ID);
+ String extensionService = (String) properties.get(EXTENSION_SERVICE_NAME_PROPERTY_ID);
+
+ Map<String, Object> descriptor;
+ try {
+ descriptor = getWidgetsDescriptor(extensionName, extensionVersion, extensionService);
+ } catch (IOException e) {
+ LOG.error("Unable to process Widgets Descriptor. Properties: " + properties, e);
+ throw new SystemException("An internal exception occurred while attempting to build a Widgets Descriptor " +
+ "artifact. See ambari server logs for more information", e);
+ }
+
+ if (descriptor != null) {
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionArtifact);
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ setResourceProperty(resource, ARTIFACT_NAME_PROPERTY_ID, WIDGETS_DESCRIPTOR_NAME, requestedIds);
+ setResourceProperty(resource, ARTIFACT_DATA_PROPERTY_ID, descriptor, requestedIds);
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID, extensionName, requestedIds);
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID, extensionVersion, requestedIds);
+ if (extensionService != null) {
+ setResourceProperty(resource, EXTENSION_SERVICE_NAME_PROPERTY_ID, extensionService, requestedIds);
+ }
+ resources.add(resource);
+ }
+ }
+ }
+ return resources;
+ }
+
+ private Map<String, Object> getWidgetsDescriptor(String extensionName,
+ String extensionVersion, String serviceName)
+ throws NoSuchParentResourceException, IOException {
+
+ AmbariManagementController controller = getManagementController();
+ ExtensionInfo extensionInfo;
+ try {
+ extensionInfo = controller.getAmbariMetaInfo().getExtension(extensionName, extensionVersion);
+ } catch (StackAccessException e) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent extension resource doesn't exist: extensionName='%s', extensionVersion='%s'", extensionName, extensionVersion));
+ }
+
+ if (StringUtils.isEmpty(serviceName)) {
+ return getWidgetsDescriptorForCluster(extensionInfo);
+ } else {
+ return getWidgetsDescriptorForService(extensionInfo, serviceName);
+ }
+ }
+
+ public Map<String, Object> getWidgetsDescriptorForService(ExtensionInfo extensionInfo, String serviceName)
+ throws NoSuchParentResourceException, IOException {
+
+ Map<String, Object> widgetDescriptor = null;
+
+ ServiceInfo serviceInfo = extensionInfo.getService(serviceName);
+ if (serviceInfo == null) {
+ throw new NoSuchParentResourceException("Service not found. serviceName" + " = " + serviceName);
+ }
+
+ File widgetDescriptorFile = serviceInfo.getWidgetsDescriptorFile();
+ if (widgetDescriptorFile != null && widgetDescriptorFile.exists()) {
+ widgetDescriptor = gson.fromJson(new FileReader(widgetDescriptorFile), widgetLayoutType);
+ }
+
+ return widgetDescriptor;
+ }
+
+ public Map<String, Object> getWidgetsDescriptorForCluster(ExtensionInfo extensionInfo)
+ throws NoSuchParentResourceException, IOException {
+
+ Map<String, Object> widgetDescriptor = null;
+
+ String widgetDescriptorFileLocation = extensionInfo.getWidgetsDescriptorFileLocation();
+ if (widgetDescriptorFileLocation != null) {
+ File widgetDescriptorFile = new File(widgetDescriptorFileLocation);
+ if (widgetDescriptorFile.exists()) {
+ widgetDescriptor = gson.fromJson(new FileReader(widgetDescriptorFile), widgetLayoutType);
+ }
+ }
+
+ return widgetDescriptor;
+ }
+
+ /**
+ * Get a kerberos descriptor.
+ *
+ * @param extensionName extension name
+ * @param extensionVersion extension version
+ * @param serviceName service name
+ *
+ * @return map of kerberos descriptor data or null if no descriptor exists
+ *
+ * @throws IOException if unable to parse the associated kerberos descriptor file
+ * @throws NoSuchParentResourceException if the parent extension or extension service doesn't exist
+ */
+ private Map<String, Object> getKerberosDescriptor(String extensionName, String extensionVersion, String serviceName)
+ throws NoSuchParentResourceException, IOException {
+
+ return serviceName == null ?
+ buildExtensionDescriptor(extensionName, extensionVersion) :
+ getServiceDescriptor(extensionName, extensionVersion, serviceName);
+ }
+
+ /**
+ * Build a kerberos descriptor for the specified extension. This descriptor is for the entire extension version
+ * and will contain both the extension descriptor as well as all service descriptors.
+ *
+ * @return map of kerberos descriptor data or null if no descriptor exists
+ *
+ * @throws IOException if unable to read the kerberos descriptor file
+ * @throws AmbariException if unable to parse the kerberos descriptor file json
+ * @throws NoSuchParentResourceException if the parent extension doesn't exist
+ */
+ private Map<String, Object> buildExtensionDescriptor(String extensionName, String extensionVersion)
+ throws NoSuchParentResourceException, IOException {
+
+ KerberosDescriptor kerberosDescriptor = null;
+
+ AmbariManagementController controller = getManagementController();
+ ExtensionInfo extensionInfo;
+ try {
+ extensionInfo = controller.getAmbariMetaInfo().getExtension(extensionName, extensionVersion);
+ } catch (StackAccessException e) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent extension resource doesn't exist: extensionName='%s', extensionVersion='%s'", extensionName, extensionVersion));
+ }
+
+ Collection<KerberosServiceDescriptor> serviceDescriptors = getServiceDescriptors(extensionInfo);
+
+ String kerberosFileLocation = extensionInfo.getKerberosDescriptorFileLocation();
+ if (kerberosFileLocation != null) {
+ kerberosDescriptor = kerberosDescriptorFactory.createInstance(new File(kerberosFileLocation));
+ } else if (! serviceDescriptors.isEmpty()) {
+ // service descriptors present with no extension descriptor,
+ // create an empty extension descriptor to hold services
+ kerberosDescriptor = new KerberosDescriptor();
+ }
+
+ if (kerberosDescriptor != null) {
+ for (KerberosServiceDescriptor descriptor : serviceDescriptors) {
+ kerberosDescriptor.putService(descriptor);
+ }
+ return kerberosDescriptor.toMap();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the kerberos descriptor for the specified extension service.
+ *
+ * @param extensionName extension name
+ * @param extensionVersion extension version
+ * @param serviceName service name
+ *
+ * @return map of kerberos descriptor data or null if no descriptor exists
+ *
+ * @throws IOException if unable to read or parse the kerberos descriptor file
+ * @throws NoSuchParentResourceException if the parent extension or extension service doesn't exist
+ */
+ private Map<String, Object> getServiceDescriptor(
+ String extensionName, String extensionVersion, String serviceName) throws NoSuchParentResourceException, IOException {
+
+ AmbariManagementController controller = getManagementController();
+
+ ServiceInfo serviceInfo;
+ try {
+ serviceInfo = controller.getAmbariMetaInfo().getExtensionService(extensionName, extensionVersion, serviceName);
+ } catch (StackAccessException e) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent extension/service resource doesn't exist: extensionName='%s', extensionVersion='%s', serviceName='%s'",
+ extensionName, extensionVersion, serviceName));
+ }
+ File kerberosFile = serviceInfo.getKerberosDescriptorFile();
+
+ if (kerberosFile != null) {
+ KerberosServiceDescriptor serviceDescriptor =
+ kerberosServiceDescriptorFactory.createInstance(kerberosFile, serviceName);
+
+ if (serviceDescriptor != null) {
+ return serviceDescriptor.toMap();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get a collection of all service descriptors for the specified extension.
+ *
+ * @param extension extension name
+ *
+ * @return collection of all service descriptors for the extension; will not return null
+ *
+ * @throws IOException if unable to read or parse a descriptor file
+ */
+ private Collection<KerberosServiceDescriptor> getServiceDescriptors(ExtensionInfo extension) throws IOException {
+ Collection<KerberosServiceDescriptor> serviceDescriptors = new ArrayList<KerberosServiceDescriptor>();
+ for (ServiceInfo service : extension.getServices()) {
+ File descriptorFile = service.getKerberosDescriptorFile();
+ if (descriptorFile != null) {
+ KerberosServiceDescriptor descriptor =
+ kerberosServiceDescriptorFactory.createInstance(descriptorFile, service.getName());
+
+ if (descriptor != null) {
+ serviceDescriptors.add(descriptor);
+ }
+ }
+ }
+ return serviceDescriptors;
+ }
+
+ private Map<String, Map<String, List<MetricDefinition>>> removeAggregateFunctions(
+ Map<String, Map<String, List<MetricDefinition>>> serviceMetrics ) {
+ Map<String, Map<String, List<MetricDefinition>>> filteredServiceMetrics = null;
+ if (serviceMetrics != null) {
+ Cloner cloner = new Cloner();
+ filteredServiceMetrics = cloner.deepClone(serviceMetrics);
+ // For every Component
+ for (Map<String, List<MetricDefinition>> componentMetricDef : filteredServiceMetrics.values()) {
+ // For every Component / HostComponent category
+ for (Map.Entry<String, List<MetricDefinition>> metricDefEntry : componentMetricDef.entrySet()) {
+ //For every metric definition
+ for (MetricDefinition metricDefinition : metricDefEntry.getValue()) {
+ // Metrics System metrics only
+ if (metricDefinition.getType().equals("ganglia")) {
+ // Create a new map for each category
+ for (Map<String, Metric> metricByCategory : metricDefinition.getMetricsByCategory().values()) {
+ Iterator<Map.Entry<String, Metric>> iterator = metricByCategory.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String, Metric> entry = iterator.next();
+ String metricName = entry.getKey();
+ if (PropertyHelper.hasAggregateFunctionSuffix(metricName)) {
+ iterator.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return filteredServiceMetrics;
+ }
+
+ private List<MetricDefinition> removeAggregateFunctions(List<MetricDefinition> componentMetrics) {
+ List<MetricDefinition> filteredComponentMetrics = null;
+ if (componentMetrics != null) {
+ Cloner cloner = new Cloner();
+ filteredComponentMetrics = cloner.deepClone(componentMetrics);
+ // For every metric definition
+ for (MetricDefinition metricDefinition : filteredComponentMetrics) {
+ // Metrics System metrics only
+ if (metricDefinition.getType().equals("ganglia")) {
+ // Create a new map for each category
+ for (Map<String, Metric> metricByCategory : metricDefinition.getMetricsByCategory().values()) {
+ Iterator<Map.Entry<String, Metric>> iterator = metricByCategory.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String, Metric> entry = iterator.next();
+ String metricName = entry.getKey();
+ if (PropertyHelper.hasAggregateFunctionSuffix(metricName)) {
+ iterator.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+ return filteredComponentMetrics;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationDependencyResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationDependencyResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationDependencyResourceProvider.java
new file mode 100644
index 0000000..e26a7cc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationDependencyResourceProvider.java
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ExtensionConfigurationDependencyRequest;
+import org.apache.ambari.server.controller.ExtensionConfigurationDependencyResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ExtensionConfigurationDependencyResourceProvider extends
+ ReadOnlyResourceProvider {
+
+ public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "extension_name");
+
+ public static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "extension_version");
+
+ public static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "service_name");
+
+ public static final String PROPERTY_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "property_name");
+
+ public static final String DEPENDENCY_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "dependency_name");
+
+ public static final String DEPENDENCY_TYPE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurationDependency", "dependency_type");
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID,
+ EXTENSION_VERSION_PROPERTY_ID, SERVICE_NAME_PROPERTY_ID,
+ PROPERTY_NAME_PROPERTY_ID, DEPENDENCY_NAME_PROPERTY_ID }));
+
+ protected ExtensionConfigurationDependencyResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public Set<Resource> getResources(final Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ExtensionConfigurationDependencyRequest> requests =
+ new HashSet<ExtensionConfigurationDependencyRequest>();
+
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<ExtensionConfigurationDependencyResponse> responses = getResources(new Command<Set<ExtensionConfigurationDependencyResponse>>() {
+ @Override
+ public Set<ExtensionConfigurationDependencyResponse> invoke() throws AmbariException {
+ return getManagementController().getExtensionConfigurationDependencies(requests);
+ }
+ });
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ExtensionConfigurationDependencyResponse response : responses) {
+ Resource resource = new ResourceImpl(Type.ExtensionConfigurationDependency);
+
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+ response.getExtensionName(), requestedIds);
+
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID,
+ response.getExtensionVersion(), requestedIds);
+
+ setResourceProperty(resource, SERVICE_NAME_PROPERTY_ID,
+ response.getServiceName(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_NAME_PROPERTY_ID,
+ response.getPropertyName(), requestedIds);
+
+ setResourceProperty(resource, DEPENDENCY_NAME_PROPERTY_ID,
+ response.getDependencyName(), requestedIds);
+
+ setResourceProperty(resource, DEPENDENCY_TYPE_PROPERTY_ID,
+ response.getDependencyType(), requestedIds);
+
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ private ExtensionConfigurationDependencyRequest getRequest(Map<String, Object> properties) {
+ return new ExtensionConfigurationDependencyRequest(
+ (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+ (String) properties.get(EXTENSION_VERSION_PROPERTY_ID),
+ (String) properties.get(SERVICE_NAME_PROPERTY_ID),
+ (String) properties.get(PROPERTY_NAME_PROPERTY_ID),
+ (String) properties.get(DEPENDENCY_NAME_PROPERTY_ID));
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationResourceProvider.java
new file mode 100644
index 0000000..d3107cb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionConfigurationResourceProvider.java
@@ -0,0 +1,194 @@
+/**
+ * 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.Arrays;
+import java.util.Collections;
+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.controller.ExtensionConfigurationRequest;
+import org.apache.ambari.server.controller.ExtensionConfigurationResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.commons.lang.StringUtils;
+
+public class ExtensionConfigurationResourceProvider extends
+ ReadOnlyResourceProvider {
+
+ public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "extension_name");
+
+ public static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "extension_version");
+
+ public static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "service_name");
+
+ public static final String PROPERTY_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_name");
+
+ public static final String PROPERTY_VALUE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_value");
+
+ public static final String PROPERTY_VALUE_ATTRIBUTES_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_value_attributes");
+
+ public static final String PROPERTY_DEPENDS_ON_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_depends_on");
+
+ public static final String PROPERTY_DESCRIPTION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_description");
+
+ public static final String PROPERTY_DISPLAY_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_display_name");
+
+ public static final String PROPERTY_PROPERTY_TYPE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "property_type");
+
+ public static final String PROPERTY_TYPE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "type");
+
+ public static final String PROPERTY_FINAL_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionConfigurations", "final");
+
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID,
+ EXTENSION_VERSION_PROPERTY_ID, SERVICE_NAME_PROPERTY_ID, PROPERTY_NAME_PROPERTY_ID }));
+
+ protected ExtensionConfigurationResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ExtensionConfigurationRequest> requests = new HashSet<ExtensionConfigurationRequest>();
+
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<ExtensionConfigurationResponse> responses = getResources(new Command<Set<ExtensionConfigurationResponse>>() {
+ @Override
+ public Set<ExtensionConfigurationResponse> invoke() throws AmbariException {
+ return getManagementController().getExtensionConfigurations(requests);
+ }
+ });
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ExtensionConfigurationResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionConfiguration);
+
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+ response.getExtensionName(), requestedIds);
+
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID,
+ response.getExtensionVersion(), requestedIds);
+
+ setResourceProperty(resource, SERVICE_NAME_PROPERTY_ID,
+ response.getServiceName(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_NAME_PROPERTY_ID,
+ response.getPropertyName(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_VALUE_PROPERTY_ID,
+ response.getPropertyValue(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_VALUE_ATTRIBUTES_PROPERTY_ID,
+ response.getPropertyValueAttributes(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_DEPENDS_ON_PROPERTY_ID,
+ response.getDependsOnProperties(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_DESCRIPTION_PROPERTY_ID,
+ response.getPropertyDescription(), requestedIds);
+
+ //should not be returned if empty
+ if (StringUtils.isNotEmpty(response.getPropertyDisplayName())) {
+ setResourceProperty(resource, PROPERTY_DISPLAY_NAME_PROPERTY_ID,
+ response.getPropertyDisplayName(), requestedIds);
+ }
+
+ setResourceProperty(resource, PROPERTY_PROPERTY_TYPE_PROPERTY_ID,
+ response.getPropertyType(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_TYPE_PROPERTY_ID,
+ response.getType(), requestedIds);
+
+ setDefaultPropertiesAttributes(resource, requestedIds);
+
+ for (Map.Entry<String, String> attribute : response.getPropertyAttributes().entrySet()) {
+ setResourceProperty(resource, PropertyHelper.getPropertyId("ExtensionConfigurations", attribute.getKey()),
+ attribute.getValue(), requestedIds);
+ }
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ /**
+ * Set default values for properties attributes before applying original ones
+ * to prevent absence in case of empty attributes map
+ */
+ private void setDefaultPropertiesAttributes(Resource resource, Set<String> requestedIds) {
+ setResourceProperty(resource, PROPERTY_FINAL_PROPERTY_ID,
+ "false", requestedIds);
+ }
+
+ private ExtensionConfigurationRequest getRequest(Map<String, Object> properties) {
+ return new ExtensionConfigurationRequest(
+ (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+ (String) properties.get(EXTENSION_VERSION_PROPERTY_ID),
+ (String) properties.get(SERVICE_NAME_PROPERTY_ID),
+ (String) properties.get(PROPERTY_NAME_PROPERTY_ID));
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionDependencyResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionDependencyResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionDependencyResourceProvider.java
new file mode 100644
index 0000000..c1fb27d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionDependencyResourceProvider.java
@@ -0,0 +1,254 @@
+/**
+ * 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 org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.DependencyInfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Resource provider for Extension Dependency resource.
+ */
+public class ExtensionDependencyResourceProvider extends AbstractResourceProvider {
+
+ // ----- Property ID constants ---------------------------------------------
+
+ protected static final String EXTENSION_NAME_ID =
+ PropertyHelper.getPropertyId("Dependencies", "extension_name");
+ protected static final String EXTENSION_VERSION_ID =
+ PropertyHelper.getPropertyId("Dependencies", "extension_version");
+ protected static final String DEPENDENT_SERVICE_NAME_ID =
+ PropertyHelper.getPropertyId("Dependencies", "dependent_service_name");
+ protected static final String DEPENDENT_COMPONENT_NAME_ID =
+ PropertyHelper.getPropertyId("Dependencies", "dependent_component_name");
+ protected static final String SERVICE_NAME_ID =
+ PropertyHelper.getPropertyId("Dependencies", "service_name");
+ protected static final String COMPONENT_NAME_ID =
+ PropertyHelper.getPropertyId("Dependencies", "component_name");
+ protected static final String SCOPE_ID =
+ PropertyHelper.getPropertyId("Dependencies", "scope");
+ protected static final String AUTO_DEPLOY_ENABLED_ID = PropertyHelper
+ .getPropertyId("auto_deploy", "enabled");
+ protected static final String AUTO_DEPLOY_LOCATION_ID = PropertyHelper
+ .getPropertyId("auto_deploy", "location");
+
+ // Primary Key Fields
+ private static Set<String> pkPropertyIds =
+ new HashSet<String>(Arrays.asList(new String[]{
+ SERVICE_NAME_ID, COMPONENT_NAME_ID}));
+
+ /**
+ * Provides extension information
+ */
+ private static AmbariMetaInfo ambariMetaInfo;
+
+
+ // ----- Constructors ----------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param propertyIds the property ids
+ * @param keyPropertyIds the key property ids
+ */
+ protected ExtensionDependencyResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds) {
+ super(propertyIds, keyPropertyIds);
+ }
+
+ /**
+ * Static initialization.
+ *
+ * @param metaInfo meta info instance
+ */
+ public static void init(AmbariMetaInfo metaInfo) {
+ ambariMetaInfo = metaInfo;
+ }
+
+
+ // ----- ResourceProvider ------------------------------------------------
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+ Set<Map<String, Object>> requestProps = getPropertyMaps(predicate);
+
+ for (Map<String, Object> properties : requestProps) {
+ try {
+ resources.addAll(getDependencyResources(properties,
+ getRequestPropertyIds(request, predicate)));
+ } catch (NoSuchResourceException e) {
+ if (requestProps.size() == 1) {
+ throw e;
+ }
+ } catch (NoSuchParentResourceException e) {
+ if (requestProps.size() == 1) {
+ throw e;
+ }
+ }
+ }
+ return resources;
+ }
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException, UnsupportedPropertyException,
+ ResourceAlreadyExistsException, NoSuchParentResourceException {
+
+ // should not get here as service doesn't allow POST and should return 405
+ throw new SystemException("Extension resources are read only");
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ // should not get here as service doesn't allow PUT and should return 405
+ throw new SystemException("Extension resources are read only");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ // should not get here as service doesn't allow DELETE and should return 405
+ throw new SystemException("Extension resources are read only");
+ }
+
+
+ // ----- Instance Methods ------------------------------------------------
+
+ /**
+ * Get dependencies resources.
+ *
+ * @param properties request properties
+ * @param requestedIds requested id's
+ *
+ * @return collection of dependency resources
+ *
+ * @throws SystemException an internal error occurred
+ * @throws NoSuchParentResourceException parent resource not found
+ * @throws NoSuchResourceException dependency resource not found
+ */
+ private Collection<Resource> getDependencyResources(Map<String, Object> properties, Set<String> requestedIds)
+ throws SystemException, NoSuchParentResourceException, NoSuchResourceException {
+
+ final String extensionName = (String) properties.get(EXTENSION_NAME_ID);
+ final String version = (String) properties.get(EXTENSION_VERSION_ID);
+ final String dependentService = (String) properties.get(DEPENDENT_SERVICE_NAME_ID);
+ final String dependentComponent = (String) properties.get(DEPENDENT_COMPONENT_NAME_ID);
+ final String dependencyName = (String) properties.get(COMPONENT_NAME_ID);
+
+ List<DependencyInfo> dependencies = new ArrayList<DependencyInfo>();
+ if (dependencyName != null) {
+ dependencies.add(getResources(new Command<DependencyInfo>() {
+ @Override
+ public DependencyInfo invoke() throws AmbariException {
+ return ambariMetaInfo.getExtensionComponentDependency(extensionName, version, dependentService,
+ dependentComponent, dependencyName);
+ }
+ }));
+ } else {
+ dependencies.addAll(getResources(new Command<List<DependencyInfo>>() {
+ @Override
+ public List<DependencyInfo> invoke() throws AmbariException {
+ return ambariMetaInfo.getExtensionComponentDependencies(extensionName, version,
+ dependentService, dependentComponent);
+ }
+ }));
+ }
+
+ Collection<Resource> resources = new ArrayList<Resource>();
+ for (DependencyInfo dependency : dependencies) {
+ if (dependency != null) {
+ resources.add(toResource(dependency, extensionName, version, dependentService,
+ dependentComponent, requestedIds));
+ }
+ }
+ return resources;
+ }
+
+ /**
+ * Create a resource instance with dependency information.
+ *
+ * @param dependency dependency name
+ * @param extensionName extension name
+ * @param version extension version
+ * @param dependentService dependent service
+ * @param dependentComponent dependent component
+ * @param requestedIds requested id's
+ *
+ * @return a new Resource instance for the dependency
+ */
+ private Resource toResource(DependencyInfo dependency, String extensionName,
+ String version, String dependentService,
+ String dependentComponent, Set<String> requestedIds) {
+
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionServiceComponentDependency);
+
+ setResourceProperty(resource, SERVICE_NAME_ID, dependency.getServiceName(), requestedIds);
+ setResourceProperty(resource, COMPONENT_NAME_ID, dependency.getComponentName(), requestedIds);
+ setResourceProperty(resource, EXTENSION_NAME_ID, extensionName, requestedIds);
+ setResourceProperty(resource, EXTENSION_VERSION_ID, version, requestedIds);
+ setResourceProperty(resource, DEPENDENT_SERVICE_NAME_ID, dependentService, requestedIds);
+ setResourceProperty(resource, DEPENDENT_COMPONENT_NAME_ID, dependentComponent, requestedIds);
+ setResourceProperty(resource, SCOPE_ID, dependency.getScope(), requestedIds);
+
+ AutoDeployInfo autoDeployInfo = dependency.getAutoDeploy();
+ if (autoDeployInfo != null) {
+ setResourceProperty(resource, AUTO_DEPLOY_ENABLED_ID,
+ autoDeployInfo.isEnabled(), requestedIds);
+
+ if (autoDeployInfo.getCoLocate() != null) {
+ setResourceProperty(resource, AUTO_DEPLOY_LOCATION_ID,
+ autoDeployInfo.getCoLocate(), requestedIds);
+ }
+ }
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLevelConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLevelConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLevelConfigurationResourceProvider.java
new file mode 100644
index 0000000..97afc9f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLevelConfigurationResourceProvider.java
@@ -0,0 +1,177 @@
+/**
+ * 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.Arrays;
+import java.util.Collections;
+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.controller.ExtensionConfigurationResponse;
+import org.apache.ambari.server.controller.ExtensionLevelConfigurationRequest;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class ExtensionLevelConfigurationResourceProvider extends
+ ReadOnlyResourceProvider {
+
+ public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "extension_name");
+
+ public static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "extension_version");
+
+ public static final String PROPERTY_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_name");
+
+ public static final String PROPERTY_VALUE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_value");
+
+ public static final String PROPERTY_VALUE_ATTRIBUTES_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_value_attributes");
+
+ public static final String DEPENDS_ON_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_depends_on");
+
+ public static final String PROPERTY_DESCRIPTION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_description");
+
+ public static final String PROPERTY_PROPERTY_TYPE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "property_type");
+
+ public static final String PROPERTY_TYPE_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "type");
+
+ public static final String PROPERTY_FINAL_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLevelConfigurations", "final");
+
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID,
+ EXTENSION_VERSION_PROPERTY_ID, PROPERTY_NAME_PROPERTY_ID }));
+
+ protected ExtensionLevelConfigurationResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ExtensionLevelConfigurationRequest> requests = new HashSet<ExtensionLevelConfigurationRequest>();
+
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<ExtensionConfigurationResponse> responses = getResources(new Command<Set<ExtensionConfigurationResponse>>() {
+ @Override
+ public Set<ExtensionConfigurationResponse> invoke() throws AmbariException {
+ return getManagementController().getExtensionLevelConfigurations(requests);
+ }
+ });
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ExtensionConfigurationResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionLevelConfiguration);
+
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+ response.getExtensionName(), requestedIds);
+
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID,
+ response.getExtensionVersion(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_NAME_PROPERTY_ID,
+ response.getPropertyName(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_VALUE_PROPERTY_ID,
+ response.getPropertyValue(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_VALUE_ATTRIBUTES_PROPERTY_ID,
+ response.getPropertyValueAttributes(), requestedIds);
+
+ setResourceProperty(resource, DEPENDS_ON_PROPERTY_ID,
+ response.getDependsOnProperties(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_DESCRIPTION_PROPERTY_ID,
+ response.getPropertyDescription(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_PROPERTY_TYPE_PROPERTY_ID,
+ response.getPropertyType(), requestedIds);
+
+ setResourceProperty(resource, PROPERTY_TYPE_PROPERTY_ID,
+ response.getType(), requestedIds);
+
+ setDefaultPropertiesAttributes(resource, requestedIds);
+
+ for (Map.Entry<String, String> attribute : response.getPropertyAttributes().entrySet()) {
+ setResourceProperty(resource, PropertyHelper.getPropertyId("ExtensionLevelConfigurations", attribute.getKey()),
+ attribute.getValue(), requestedIds);
+ }
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ /**
+ * Set default values for properties attributes before applying original ones
+ * to prevent absence in case of empty attributes map
+ */
+ private void setDefaultPropertiesAttributes(Resource resource, Set<String> requestedIds) {
+ setResourceProperty(resource, PROPERTY_FINAL_PROPERTY_ID,
+ "false", requestedIds);
+ }
+
+ private ExtensionLevelConfigurationRequest getRequest(Map<String, Object> properties) {
+ return new ExtensionLevelConfigurationRequest(
+ (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+ (String) properties.get(EXTENSION_VERSION_PROPERTY_ID),
+ (String) properties.get(PROPERTY_NAME_PROPERTY_ID));
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLinkResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLinkResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLinkResourceProvider.java
new file mode 100644
index 0000000..f65b331
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionLinkResourceProvider.java
@@ -0,0 +1,261 @@
+/**
+ * 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.*;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ExtensionLinkRequest;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.ExtensionLinkDAO;
+import org.apache.ambari.server.orm.entities.ExtensionLinkEntity;
+
+import com.google.inject.Inject;
+
+@StaticallyInject
+public class ExtensionLinkResourceProvider extends AbstractControllerResourceProvider {
+
+ public static final String LINK_ID_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLink", "link_id");
+
+ public static final String STACK_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLink", "stack_name");
+
+ public static final String STACK_VERSION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLink", "stack_version");
+
+ public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLink", "extension_name");
+
+ public static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ExtensionLink", "extension_version");
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(new String[] { LINK_ID_PROPERTY_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID, EXTENSION_NAME_PROPERTY_ID, EXTENSION_VERSION_PROPERTY_ID }));
+
+ @Inject
+ private static ExtensionLinkDAO dao;
+
+ protected ExtensionLinkResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchParentResourceException, ResourceAlreadyExistsException {
+
+ final Set<ExtensionLinkRequest> requests = new HashSet<ExtensionLinkRequest>();
+ for (Map<String, Object> propertyMap : request.getProperties()) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ for (ExtensionLinkRequest extensionLinkRequest : requests) {
+ getManagementController().createExtensionLink(extensionLinkRequest);
+ }
+ return null;
+ }
+ });
+
+ if (requests.size() > 0) {
+ //Need to reread the stacks/extensions directories so the latest information is available
+ try {
+ getManagementController().updateStacks();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+
+ notifyCreate(Resource.Type.ExtensionLink, request);
+ }
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ExtensionLinkRequest> requests = new HashSet<ExtensionLinkRequest>();
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
+ @Override
+ public RequestStatusResponse invoke() throws AmbariException {
+ for (ExtensionLinkRequest extensionLinkRequest : requests) {
+ getManagementController().deleteExtensionLink(extensionLinkRequest);
+ }
+ return null;
+ }
+ });
+
+ //Need to reread the stacks/extensions directories so the latest information is available
+ try {
+ getManagementController().updateStacks();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+
+ notifyDelete(Resource.Type.ExtensionLink, predicate);
+
+ return getRequestStatus(response);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<Resource> resources = new HashSet<Resource>();
+ final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ final Set<ExtensionLinkRequest> requests = new HashSet<ExtensionLinkRequest>();
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<ExtensionLinkEntity> entities = new HashSet<ExtensionLinkEntity>();
+
+ for (ExtensionLinkRequest extensionLinkRequest : requests) {
+ verifyStackAndExtensionExist(extensionLinkRequest);
+ entities.addAll(dao.find(extensionLinkRequest));
+ }
+
+ for (ExtensionLinkEntity entity : entities) {
+ Resource resource = new ResourceImpl(Resource.Type.ExtensionLink);
+ setResourceProperty(resource, LINK_ID_PROPERTY_ID,
+ entity.getLinkId(), requestedIds);
+ setResourceProperty(resource, STACK_NAME_PROPERTY_ID,
+ entity.getStack().getStackName(), requestedIds);
+ setResourceProperty(resource, STACK_VERSION_PROPERTY_ID,
+ entity.getStack().getStackVersion(), requestedIds);
+ setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+ entity.getExtension().getExtensionName(), requestedIds);
+ setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID,
+ entity.getExtension().getExtensionVersion(), requestedIds);
+
+ resources.add(resource);
+ }
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ /*boolean updated = false;
+
+ if (predicate == null) {
+ List<ExtensionLinkEntity> entities = dao.findAll();
+ for (ExtensionLinkEntity entity : entities) {
+ try {
+ getManagementController().updateExtensionLink(entity);
+ updated = true;
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+ }
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ ExtensionLinkRequest extensionLinkRequest = getRequest(propertyMap);
+ try {
+ getManagementController().updateExtensionLink(extensionLinkRequest);
+ updated = true;
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+ }
+ }*/
+
+ //if (updated) {
+
+ //Need to reread the stacks/extensions directories so the latest information is available
+ //This also regenerates the stacks' services folders for extension services
+ try {
+ getManagementController().updateStacks();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+
+ notifyUpdate(Resource.Type.ExtensionLink, request, predicate);
+ //}
+ return getRequestStatus(null);
+ }
+
+ private void verifyStackAndExtensionExist(ExtensionLinkRequest request) throws NoSuchParentResourceException {
+ try {
+ if (request.getStackName() != null && request.getStackVersion() != null) {
+ getManagementController().getAmbariMetaInfo().getStack(request.getStackName(), request.getStackVersion());
+ }
+ if (request.getExtensionName() != null && request.getExtensionVersion() != null) {
+ getManagementController().getAmbariMetaInfo().getExtension(request.getExtensionName(), request.getExtensionVersion());
+ }
+ }
+ catch (AmbariException ambariException) {
+ throw new NoSuchParentResourceException(ambariException.getMessage());
+ }
+ }
+
+ private ExtensionLinkRequest getRequest(Map<String, Object> properties) {
+ return new ExtensionLinkRequest(
+ (String) properties.get(LINK_ID_PROPERTY_ID),
+ (String) properties.get(STACK_NAME_PROPERTY_ID),
+ (String) properties.get(STACK_VERSION_PROPERTY_ID),
+ (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+ (String) properties.get(EXTENSION_VERSION_PROPERTY_ID));
+ }
+
+ private ExtensionLinkRequest createExtensionLinkRequest(ExtensionLinkEntity entity) {
+ if (entity == null) {
+ return null;
+ }
+
+ return new ExtensionLinkRequest(String.valueOf(entity.getLinkId()),
+ entity.getStack().getStackName(),
+ entity.getStack().getStackVersion(),
+ entity.getExtension().getExtensionName(),
+ entity.getExtension().getExtensionVersion());
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionOperatingSystemResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionOperatingSystemResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionOperatingSystemResourceProvider.java
new file mode 100644
index 0000000..b2ae0c7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionOperatingSystemResourceProvider.java
@@ -0,0 +1,147 @@
+/**
+ * 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.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.controller.ExtensionOperatingSystemRequest;
+import org.apache.ambari.server.controller.ExtensionOperatingSystemResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class ExtensionOperatingSystemResourceProvider extends ReadOnlyResourceProvider {
+
+ public static final String OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("OperatingSystems", "extension_name");
+ public static final String OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("OperatingSystems", "extension_version");
+ public static final String OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("OperatingSystems", "os_type");
+ public static final String OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID = PropertyHelper.getPropertyId("OperatingSystems", "repository_version_id");
+
+ @SuppressWarnings("serial")
+ private static Set<String> pkPropertyIds = new HashSet<String>() {
+ {
+ add(OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID);
+ add(OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID);
+ add(OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID);
+ }
+ };
+
+ @SuppressWarnings("serial")
+ public static Set<String> propertyIds = new HashSet<String>() {
+ {
+ add(OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID);
+ add(OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID);
+ add(OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID);
+ add(OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID);
+ }
+ };
+
+ @SuppressWarnings("serial")
+ public static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() {
+ {
+ put(Resource.Type.OperatingSystem, OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID);
+ put(Resource.Type.Extension, OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID);
+ put(Resource.Type.ExtensionVersion, OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID);
+ put(Resource.Type.RepositoryVersion, OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID);
+ put(Resource.Type.CompatibleRepositoryVersion, OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID);
+ }
+ };
+
+ protected ExtensionOperatingSystemResourceProvider(AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ExtensionOperatingSystemRequest> requests = new HashSet<ExtensionOperatingSystemRequest>();
+
+ if (predicate == null) {
+ requests.add(getRequest(Collections.<String, Object>emptyMap()));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<ExtensionOperatingSystemResponse> responses = getResources(new Command<Set<ExtensionOperatingSystemResponse>>() {
+ @Override
+ public Set<ExtensionOperatingSystemResponse> invoke() throws AmbariException {
+ return getManagementController().getExtensionOperatingSystems(requests);
+ }
+ });
+
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ExtensionOperatingSystemResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.OperatingSystem);
+
+ setResourceProperty(resource, OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID,
+ response.getExtensionName(), requestedIds);
+
+ setResourceProperty(resource, OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID,
+ response.getExtensionVersion(), requestedIds);
+
+ setResourceProperty(resource, OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID,
+ response.getOsType(), requestedIds);
+
+ if (response.getRepositoryVersionId() != null) {
+ setResourceProperty(resource, OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID,
+ response.getRepositoryVersionId(), requestedIds);
+ }
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ private ExtensionOperatingSystemRequest getRequest(Map<String, Object> properties) {
+ final ExtensionOperatingSystemRequest request = new ExtensionOperatingSystemRequest(
+ (String) properties.get(OPERATING_SYSTEM_EXTENSION_NAME_PROPERTY_ID),
+ (String) properties.get(OPERATING_SYSTEM_EXTENSION_VERSION_PROPERTY_ID),
+ (String) properties.get(OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID));
+ if (properties.containsKey(OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID)) {
+ request.setRepositoryVersionId(Long.parseLong(properties.get(OPERATING_SYSTEM_REPOSITORY_VERSION_ID_PROPERTY_ID).toString()));
+ }
+ return request;
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+}