ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject [08/13] ambari git commit: AMBARI-12885: Dynamic stack extensions - install and upgrade support for custom services (tthorpe via dili)
Date Mon, 11 Jan 2016 19:15:44 GMT
http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryResourceProvider.java
new file mode 100644
index 0000000..dbd676e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryResourceProvider.java
@@ -0,0 +1,236 @@
+/**
+ * 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.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.resources.RepositoryResourceDefinition;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ExtensionRepositoryRequest;
+import org.apache.ambari.server.controller.ExtensionRepositoryResponse;
+import org.apache.ambari.server.controller.RepositoryRequest;
+import org.apache.ambari.server.controller.RepositoryResponse;
+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.Resource.Type;
+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.commons.lang.BooleanUtils;
+
+public class ExtensionRepositoryResourceProvider extends AbstractControllerResourceProvider {
+
+  public static final String REPOSITORY_REPO_NAME_PROPERTY_ID             = PropertyHelper.getPropertyId("Repositories", "repo_name");
+  public static final String REPOSITORY_EXTENSION_NAME_PROPERTY_ID        = PropertyHelper.getPropertyId("Repositories", "extension_name");
+  public static final String REPOSITORY_EXTENSION_VERSION_PROPERTY_ID     = PropertyHelper.getPropertyId("Repositories", "extension_version");
+  public static final String REPOSITORY_OS_TYPE_PROPERTY_ID               = PropertyHelper.getPropertyId("Repositories", "os_type");
+  public static final String REPOSITORY_BASE_URL_PROPERTY_ID              = PropertyHelper.getPropertyId("Repositories", "base_url");
+  public static final String REPOSITORY_REPO_ID_PROPERTY_ID               = PropertyHelper.getPropertyId("Repositories", "repo_id");
+  public static final String REPOSITORY_MIRRORS_LIST_PROPERTY_ID          = PropertyHelper.getPropertyId("Repositories", "mirrors_list");
+  public static final String REPOSITORY_DEFAULT_BASE_URL_PROPERTY_ID      = PropertyHelper.getPropertyId("Repositories", "default_base_url");
+  public static final String REPOSITORY_VERIFY_BASE_URL_PROPERTY_ID       = PropertyHelper.getPropertyId("Repositories", "verify_base_url");
+  public static final String REPOSITORY_LATEST_BASE_URL_PROPERTY_ID       = PropertyHelper.getPropertyId("Repositories", "latest_base_url");
+  public static final String REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Repositories", "repository_version_id");
+
+  @SuppressWarnings("serial")
+  private static Set<String> pkPropertyIds = new HashSet<String>() {
+    {
+      add(REPOSITORY_EXTENSION_NAME_PROPERTY_ID);
+      add(REPOSITORY_EXTENSION_VERSION_PROPERTY_ID);
+      add(REPOSITORY_OS_TYPE_PROPERTY_ID);
+      add(REPOSITORY_REPO_ID_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Set<String> propertyIds = new HashSet<String>() {
+    {
+      add(REPOSITORY_REPO_NAME_PROPERTY_ID);
+      add(REPOSITORY_EXTENSION_NAME_PROPERTY_ID);
+      add(REPOSITORY_EXTENSION_VERSION_PROPERTY_ID);
+      add(REPOSITORY_OS_TYPE_PROPERTY_ID);
+      add(REPOSITORY_BASE_URL_PROPERTY_ID);
+      add(REPOSITORY_REPO_ID_PROPERTY_ID);
+      add(REPOSITORY_MIRRORS_LIST_PROPERTY_ID);
+      add(REPOSITORY_DEFAULT_BASE_URL_PROPERTY_ID);
+      add(REPOSITORY_VERIFY_BASE_URL_PROPERTY_ID);
+      add(REPOSITORY_LATEST_BASE_URL_PROPERTY_ID);
+      add(REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() {
+    {
+      put(Resource.Type.Extension, REPOSITORY_EXTENSION_NAME_PROPERTY_ID);
+      put(Resource.Type.ExtensionVersion, REPOSITORY_EXTENSION_VERSION_PROPERTY_ID);
+      put(Resource.Type.OperatingSystem, REPOSITORY_OS_TYPE_PROPERTY_ID);
+      put(Resource.Type.Repository, REPOSITORY_REPO_ID_PROPERTY_ID);
+      put(Resource.Type.RepositoryVersion, REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID);
+    }
+  };
+
+  public ExtensionRepositoryResourceProvider(AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+  }
+
+  @Override
+  public RequestStatus updateResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<ExtensionRepositoryRequest> requests = new HashSet<ExtensionRepositoryRequest>();
+
+    Iterator<Map<String,Object>> iterator = request.getProperties().iterator();
+    if (iterator.hasNext()) {
+      for (Map<String, Object> propertyMap : getPropertyMaps(iterator.next(), predicate)) {
+        requests.add(getRequest(propertyMap));
+      }
+    }
+
+    modifyResources(new Command<Void>() {
+      @Override
+      public Void invoke() throws AmbariException {
+        getManagementController().updateExtensionRepositories(requests);
+        return null;
+      }
+    });
+
+    return getRequestStatus(null);
+  }
+
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<ExtensionRepositoryRequest> requests = new HashSet<ExtensionRepositoryRequest>();
+
+    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<ExtensionRepositoryResponse> responses = getResources(new Command<Set<ExtensionRepositoryResponse>>() {
+      @Override
+      public Set<ExtensionRepositoryResponse> invoke() throws AmbariException {
+        return getManagementController().getExtensionRepositories(requests);
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (ExtensionRepositoryResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.Repository);
+
+        setResourceProperty(resource, REPOSITORY_EXTENSION_NAME_PROPERTY_ID, response.getExtensionName(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_EXTENSION_VERSION_PROPERTY_ID, response.getExtensionVersion(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_REPO_NAME_PROPERTY_ID, response.getRepoName(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_BASE_URL_PROPERTY_ID, response.getBaseUrl(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_OS_TYPE_PROPERTY_ID, response.getOsType(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_REPO_ID_PROPERTY_ID, response.getRepoId(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_MIRRORS_LIST_PROPERTY_ID, response.getMirrorsList(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_DEFAULT_BASE_URL_PROPERTY_ID, response.getDefaultBaseUrl(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_LATEST_BASE_URL_PROPERTY_ID, response.getLatestBaseUrl(), requestedIds);
+        if (response.getRepositoryVersionId() != null) {
+          setResourceProperty(resource, REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID, response.getRepositoryVersionId(), requestedIds);
+        }
+
+        resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  @Override
+  public RequestStatus createResources(Request request) throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
+    final String validateOnlyProperty = request.getRequestInfoProperties().get(RepositoryResourceDefinition.VALIDATE_ONLY_DIRECTIVE);
+    if (BooleanUtils.toBoolean(validateOnlyProperty)) {
+      final Set<ExtensionRepositoryRequest> requests = new HashSet<ExtensionRepositoryRequest>();
+      final Iterator<Map<String,Object>> iterator = request.getProperties().iterator();
+      if (iterator.hasNext()) {
+        for (Map<String, Object> propertyMap : request.getProperties()) {
+          requests.add(getRequest(propertyMap));
+        }
+      }
+      createResources(new Command<Void>() {
+
+        @Override
+        public Void invoke() throws AmbariException {
+          getManagementController().verifyExtensionRepositories(requests);
+          return null;
+        }
+
+      });
+      return getRequestStatus(null);
+    } else {
+      throw new SystemException("Cannot create repositories.", null);
+    }
+  }
+
+  @Override
+  public RequestStatus deleteResources(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+    throw new SystemException("Cannot delete repositories.", null);
+  }
+
+  private ExtensionRepositoryRequest getRequest(Map<String, Object> properties) {
+    ExtensionRepositoryRequest request = new ExtensionRepositoryRequest(
+        (String) properties.get(REPOSITORY_EXTENSION_NAME_PROPERTY_ID),
+        (String) properties.get(REPOSITORY_EXTENSION_VERSION_PROPERTY_ID),
+        (String) properties.get(REPOSITORY_OS_TYPE_PROPERTY_ID),
+        (String) properties.get(REPOSITORY_REPO_ID_PROPERTY_ID));
+
+    if (properties.containsKey(REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID)) {
+      request.setRepositoryVersionId(Long.parseLong(properties.get(REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID).toString()));
+    }
+
+    if (properties.containsKey(REPOSITORY_BASE_URL_PROPERTY_ID)) {
+      request.setBaseUrl((String) properties.get(REPOSITORY_BASE_URL_PROPERTY_ID));
+
+      if (properties.containsKey(REPOSITORY_VERIFY_BASE_URL_PROPERTY_ID)) {
+        request.setVerifyBaseUrl("true".equalsIgnoreCase(properties.get(REPOSITORY_VERIFY_BASE_URL_PROPERTY_ID).toString()));
+      }
+    }
+
+    return request;
+  }
+
+  @Override
+  public 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/ExtensionRepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryVersionResourceProvider.java
new file mode 100644
index 0000000..5440c5e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionRepositoryVersionResourceProvider.java
@@ -0,0 +1,523 @@
+/**
+ * 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.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.inject.Provider;
+import com.google.inject.persist.Transactional;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.api.resources.ExtensionOperatingSystemResourceDefinition;
+import org.apache.ambari.server.api.resources.ExtensionRepositoryResourceDefinition;
+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.Resource.Type;
+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.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.ExtensionRepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.ExtensionDAO;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.ExtensionEntity;
+import org.apache.ambari.server.orm.entities.ExtensionRepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
+import org.apache.ambari.server.orm.entities.RepositoryEntity;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.OperatingSystemInfo;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.ExtensionId;
+import org.apache.ambari.server.state.ExtensionInfo;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.UpgradePack;
+import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+
+/**
+ * Resource provider for repository versions resources.
+ */
+public class ExtensionRepositoryVersionResourceProvider extends AbstractAuthorizedResourceProvider {
+
+  // ----- Property ID constants ---------------------------------------------
+
+  public static final String REPOSITORY_VERSION_ID_PROPERTY_ID                 = PropertyHelper.getPropertyId("RepositoryVersions", "id");
+  public static final String REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID     = PropertyHelper.getPropertyId("RepositoryVersions", "extension_name");
+  public static final String REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID  = PropertyHelper.getPropertyId("RepositoryVersions", "extension_version");
+  public static final String REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("RepositoryVersions", "repository_version");
+  public static final String REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID       = PropertyHelper.getPropertyId("RepositoryVersions", "display_name");
+  public static final String SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID         = new ExtensionOperatingSystemResourceDefinition().getPluralName();
+  public static final String SUBRESOURCE_REPOSITORIES_PROPERTY_ID              = new ExtensionRepositoryResourceDefinition().getPluralName();
+
+  @SuppressWarnings("serial")
+  private static Set<String> pkPropertyIds = new HashSet<String>() {
+    {
+      add(REPOSITORY_VERSION_ID_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Set<String> propertyIds = new HashSet<String>() {
+    {
+      add(REPOSITORY_VERSION_ID_PROPERTY_ID);
+      add(REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID);
+      add(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
+      add(REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID);
+      add(REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID);
+      add(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() {
+    {
+      put(Type.Extension, REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID);
+      put(Type.ExtensionVersion, REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID);
+      put(Type.ExtensionRepositoryVersion, REPOSITORY_VERSION_ID_PROPERTY_ID);
+    }
+  };
+
+  @Inject
+  private Gson gson;
+
+  @Inject
+  private ExtensionRepositoryVersionDAO repositoryVersionDAO;
+
+  @Inject
+  private ClusterVersionDAO clusterVersionDAO;
+
+  @Inject
+  private AmbariMetaInfo ambariMetaInfo;
+
+  @Inject
+  private RepositoryVersionHelper repositoryVersionHelper;
+
+  @Inject
+  private Provider<Clusters> clusters;
+
+  /**
+   * Data access object used for lookup up extensions.
+   */
+  @Inject
+  private ExtensionDAO extensionDAO;
+
+  /**
+   * Create a new resource provider.
+   *
+   */
+  public ExtensionRepositoryVersionResourceProvider() {
+    super(propertyIds, keyPropertyIds);
+    setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+    setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+    setRequiredUpdateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS, RoleAuthorization.AMBARI_EDIT_STACK_REPOS));
+
+    setRequiredGetAuthorizations(EnumSet.of(
+        RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS,
+        RoleAuthorization.AMBARI_EDIT_STACK_REPOS,
+        RoleAuthorization.CLUSTER_VIEW_STACK_DETAILS,
+        RoleAuthorization.CLUSTER_UPGRADE_DOWNGRADE_STACK));
+  }
+
+  @Override
+  protected RequestStatus createResourcesAuthorized(final Request request)
+      throws SystemException,
+      UnsupportedPropertyException,
+      ResourceAlreadyExistsException,
+      NoSuchParentResourceException {
+
+    for (final Map<String, Object> properties : request.getProperties()) {
+      createResources(new Command<Void>() {
+
+        @Override
+        public Void invoke() throws AmbariException {
+          final String[] requiredProperties = {
+              REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
+              SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
+              REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID,
+              REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID,
+              REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID
+          };
+          for (String propertyName: requiredProperties) {
+            if (properties.get(propertyName) == null) {
+              throw new AmbariException("Property " + propertyName + " should be provided");
+            }
+          }
+          final ExtensionRepositoryVersionEntity entity = toRepositoryVersionEntity(properties);
+
+          if (repositoryVersionDAO.findByDisplayName(entity.getDisplayName()) != null) {
+            throw new AmbariException("Repository version with name " + entity.getDisplayName() + " already exists");
+          }
+          if (repositoryVersionDAO.findByExtensionAndVersion(entity.getExtension(), entity.getVersion()) != null) {
+            throw new AmbariException("Repository version for extension " + entity.getExtension() + " and version " + entity.getVersion() + " already exists");
+          }
+          validateRepositoryVersion(entity);
+          repositoryVersionDAO.create(entity);
+          notifyCreate(Resource.Type.RepositoryVersion, request);
+          return null;
+        }
+      });
+    }
+
+    return getRequestStatus(null);
+  }
+
+  @Override
+  protected Set<Resource> getResourcesAuthorized(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<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+
+    List<ExtensionRepositoryVersionEntity> requestedEntities = new ArrayList<ExtensionRepositoryVersionEntity>();
+    for (Map<String, Object> propertyMap: propertyMaps) {
+      final ExtensionId extensionId = getExtensionInformationFromUrl(propertyMap);
+
+      if (extensionId != null && propertyMaps.size() == 1 && propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID) == null) {
+        requestedEntities.addAll(repositoryVersionDAO.findByExtension(extensionId));
+      } else {
+        final Long id;
+        try {
+          id = Long.parseLong(propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID).toString());
+        } catch (Exception ex) {
+          throw new SystemException("Repository version should have numerical id");
+        }
+        final ExtensionRepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id);
+        if (entity == null) {
+          throw new NoSuchResourceException("There is no repository version with id " + id);
+        } else {
+          requestedEntities.add(entity);
+        }
+      }
+    }
+
+    for (ExtensionRepositoryVersionEntity entity: requestedEntities) {
+      final Resource resource = new ResourceImpl(Resource.Type.RepositoryVersion);
+
+      setResourceProperty(resource, REPOSITORY_VERSION_ID_PROPERTY_ID, entity.getId(), requestedIds);
+      setResourceProperty(resource, REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID, entity.getExtensionName(), requestedIds);
+      setResourceProperty(resource, REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID, entity.getExtensionVersion(), requestedIds);
+      setResourceProperty(resource, REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, entity.getDisplayName(), requestedIds);
+      setResourceProperty(resource, REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, entity.getVersion(), requestedIds);
+
+      resources.add(resource);
+    }
+    return resources;
+  }
+
+  @Override
+  @Transactional
+  protected RequestStatus updateResourcesAuthorized(Request request, Predicate predicate)
+    throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    final Set<Map<String, Object>> propertyMaps = request.getProperties();
+
+    modifyResources(new Command<Void>() {
+      @Override
+      public Void invoke() throws AmbariException, AuthorizationException {
+        for (Map<String, Object> propertyMap : propertyMaps) {
+          final Long id;
+          try {
+            id = Long.parseLong(propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID).toString());
+          } catch (Exception ex) {
+            throw new AmbariException("Repository version should have numerical id");
+          }
+
+          final ExtensionRepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id);
+          if (entity == null) {
+            throw new ObjectNotFoundException("There is no repository version with id " + id);
+          }
+
+		  //TODO - Need to do a lookup based on the stack?
+          // Prevent changing repo version if there's already a cluster version that has performed some meaningful action on it.
+          /*ExtensionEntity extensionEntity = entity.getExtension();
+          String extensionName = extensionEntity.getExtensionName();
+          String extensionVersion = extensionEntity.getExtensionVersion();
+
+          final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByStackAndVersion(
+              extensionName, extensionVersion, entity.getVersion());
+
+          if (!clusterVersionEntities.isEmpty()) {
+            final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
+            throw new AmbariException("Upgrade pack can't be changed for repository version which has a state of " +
+              firstClusterVersion.getState().name() + " on cluster " + firstClusterVersion.getClusterEntity().getClusterName());
+          }*/
+
+          List<OperatingSystemEntity> operatingSystemEntities = null;
+
+          if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID)))) {
+            if(!AuthorizationHelper.isAuthorized(ResourceType.AMBARI,null, RoleAuthorization.AMBARI_EDIT_STACK_REPOS)) {
+              throw new AuthorizationException("The authenticated user does not have authorization to modify extension repositories");
+            }
+
+            final Object operatingSystems = propertyMap.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
+            final String operatingSystemsJson = gson.toJson(operatingSystems);
+            try {
+              operatingSystemEntities = repositoryVersionHelper.parseOperatingSystems(operatingSystemsJson);
+            } catch (Exception ex) {
+              throw new AmbariException("Json structure for operating systems is incorrect", ex);
+            }
+            entity.setOperatingSystems(operatingSystemsJson);
+          }
+
+          if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID)))) {
+            entity.setDisplayName(propertyMap.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID).toString());
+          }
+
+          validateRepositoryVersion(entity);
+          repositoryVersionDAO.merge(entity);
+
+          //
+          // Update metaInfo table as well
+          //
+          if (operatingSystemEntities != null) {
+		ExtensionEntity extensionEntity = entity.getExtension();
+            String extensionName = extensionEntity.getExtensionName();
+            String extensionVersion = extensionEntity.getExtensionVersion();
+            for (OperatingSystemEntity osEntity : operatingSystemEntities) {
+              List<RepositoryEntity> repositories = osEntity.getRepositories();
+              for (RepositoryEntity repository : repositories) {
+                ambariMetaInfo.updateExtensionRepoBaseURL(extensionName, extensionVersion, osEntity.getOsType(), repository.getRepositoryId(), repository.getBaseUrl());
+              }
+            }
+          }
+        }
+        return null;
+      }
+    });
+
+    return getRequestStatus(null);
+  }
+
+  @Override
+  protected RequestStatus deleteResourcesAuthorized(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+
+    final List<ExtensionRepositoryVersionEntity> entitiesToBeRemoved = new ArrayList<ExtensionRepositoryVersionEntity>();
+    for (Map<String, Object> propertyMap : propertyMaps) {
+      final Long id;
+      try {
+        id = Long.parseLong(propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID).toString());
+      } catch (Exception ex) {
+        throw new SystemException("Repository version should have numerical id");
+      }
+
+      final ExtensionRepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id);
+      if (entity == null) {
+        throw new NoSuchResourceException("There is no repository version with id " + id);
+      }
+
+      //TODO - Need to do a lookup based on the stack?
+      /*ExtensionEntity extensionEntity = entity.getExtension();
+      String extensionName = extensionEntity.getExtensionName();
+      String extensionVersion = extensionEntity.getExtensionVersion();
+
+      final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByExtensionAndVersion(
+          extensionName, extensionVersion, entity.getVersion());
+
+      final List<RepositoryVersionState> forbiddenToDeleteStates = Lists.newArrayList(
+          RepositoryVersionState.CURRENT,
+          RepositoryVersionState.INSTALLED,
+          RepositoryVersionState.INSTALLING,
+          RepositoryVersionState.UPGRADED,
+          RepositoryVersionState.UPGRADING);
+      for (ClusterVersionEntity clusterVersionEntity : clusterVersionEntities) {
+        if (clusterVersionEntity.getRepositoryVersion().getId().equals(id) && forbiddenToDeleteStates.contains(clusterVersionEntity.getState())) {
+          throw new SystemException("Repository version can't be deleted as it is " +
+              clusterVersionEntity.getState().name() + " on cluster " + clusterVersionEntity.getClusterEntity().getClusterName());
+        }
+      }*/
+
+      entitiesToBeRemoved.add(entity);
+    }
+
+    for (ExtensionRepositoryVersionEntity entity: entitiesToBeRemoved) {
+      repositoryVersionDAO.remove(entity);
+    }
+
+    return getRequestStatus(null);
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+  /**
+   * Validates newly created repository versions to contain actual information.
+   *
+   * @param repositoryVersion repository version
+   * @throws AmbariException exception with error message
+   */
+  protected void validateRepositoryVersion(ExtensionRepositoryVersionEntity repositoryVersion) throws AmbariException {
+    final ExtensionId requiredExtension = new ExtensionId(repositoryVersion.getExtension());
+
+    final String extensionName = requiredExtension.getExtensionName();
+    final String extensionMajorVersion = requiredExtension.getExtensionVersion();
+    final String extensionFullName = requiredExtension.getExtensionId();
+
+    // check that extension exists
+    final ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(extensionName, extensionMajorVersion);
+    if (extensionInfo == null) {
+      throw new AmbariException("Extension " + extensionFullName + " doesn't exist");
+    }
+
+    //TODO - do we need this check?  If so fix the code to look up based on extensions
+    /*if (!upgradePackExists(repositoryVersion.getVersion())) {
+      throw new AmbariException("Extension " + extensionFullName + " doesn't have upgrade packages");
+    }*/
+
+    // List of all repo urls that are already added at extension
+    Set<String> existingRepoUrls = new HashSet<String>();
+    List<ExtensionRepositoryVersionEntity> existingRepoVersions = repositoryVersionDAO.findByExtension(requiredExtension);
+    for (ExtensionRepositoryVersionEntity existingRepoVersion : existingRepoVersions) {
+      for (OperatingSystemEntity operatingSystemEntity : existingRepoVersion.getOperatingSystems()) {
+        for (RepositoryEntity repositoryEntity : operatingSystemEntity.getRepositories()) {
+          if (! existingRepoVersion.getId().equals(repositoryVersion.getId())) { // Allow modifying already defined repo version
+            existingRepoUrls.add(repositoryEntity.getBaseUrl());
+          }
+        }
+      }
+    }
+
+    // check that repositories contain only supported operating systems
+    final Set<String> osSupported = new HashSet<String>();
+    for (OperatingSystemInfo osInfo: ambariMetaInfo.getExtensionOperatingSystems(extensionName, extensionMajorVersion)) {
+      osSupported.add(osInfo.getOsType());
+    }
+    final Set<String> osRepositoryVersion = new HashSet<String>();
+    for (OperatingSystemEntity os: repositoryVersion.getOperatingSystems()) {
+      osRepositoryVersion.add(os.getOsType());
+
+      for (RepositoryEntity repositoryEntity : os.getRepositories()) {
+        String baseUrl = repositoryEntity.getBaseUrl();
+        if (existingRepoUrls.contains(baseUrl)) {
+          throw new AmbariException("Base url " + baseUrl + " is already defined for another repository version. " +
+                  "Setting up base urls that contain the same versions of components will cause upgrade to fail.");
+        }
+      }
+    }
+    if (osRepositoryVersion.isEmpty()) {
+      throw new AmbariException("At least one set of repositories for OS should be provided");
+    }
+    for (String os: osRepositoryVersion) {
+      if (!osSupported.isEmpty() && !osSupported.contains(os)) {
+        throw new AmbariException("Operating system type " + os + " is not supported by extension " + extensionFullName);
+      }
+    }
+
+    //TODO - Do we need this check?
+    /*if (!RepositoryVersionEntity.isVersionInStack(repositoryVersion.getStackId(), repositoryVersion.getVersion())) {
+        throw new AmbariException(MessageFormat.format("Version {0} needs to belong to stack {1}",
+            repositoryVersion.getVersion(), repositoryVersion.getStackName() + "-" + repositoryVersion.getStackVersion()));
+    }*/
+  }
+
+  /**
+   * Check for required upgrade pack across all stack definitions
+   * @param checkVersion version to check (e.g. 2.2.3.0-1111)
+   * @return existence flag
+   */
+  private boolean upgradePackExists(String checkVersion) throws AmbariException{
+    Collection<StackInfo> stacks = new ArrayList<StackInfo>();
+
+    // Search results only in the installed stacks
+    for (Cluster cluster : clusters.get().getClusters().values()){
+      stacks.add(ambariMetaInfo.getStack(cluster.getCurrentStackVersion().getStackName(),
+                                          cluster.getCurrentStackVersion().getStackVersion()));
+    }
+
+    for (StackInfo si : stacks){
+      Map<String, UpgradePack> upgradePacks = si.getUpgradePacks();
+      if (upgradePacks!=null) {
+        for (UpgradePack upgradePack: upgradePacks.values()){
+          if (upgradePack.canBeApplied(checkVersion)) {
+            // If we found at least one match, the rest could be skipped
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Transforms map of json properties to repository version entity.
+   *
+   * @param properties json map
+   * @return constructed entity
+   * @throws AmbariException if some properties are missing or json has incorrect structure
+   */
+  protected ExtensionRepositoryVersionEntity toRepositoryVersionEntity(Map<String, Object> properties) throws AmbariException {
+    final ExtensionRepositoryVersionEntity entity = new ExtensionRepositoryVersionEntity();
+    final String extensionName = properties.get(REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID).toString();
+    final String extensionVersion = properties.get(REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID).toString();
+
+    ExtensionEntity extensionEntity = extensionDAO.find(extensionName, extensionVersion);
+
+    entity.setDisplayName(properties.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID).toString());
+    entity.setExtension(extensionEntity);
+
+    entity.setVersion(properties.get(REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID).toString());
+    final Object operatingSystems = properties.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
+    final String operatingSystemsJson = gson.toJson(operatingSystems);
+    try {
+      repositoryVersionHelper.parseOperatingSystems(operatingSystemsJson);
+    } catch (Exception ex) {
+      throw new AmbariException("Json structure for operating systems is incorrect", ex);
+    }
+    entity.setOperatingSystems(operatingSystemsJson);
+    return entity;
+  }
+
+  protected ExtensionId getExtensionInformationFromUrl(Map<String, Object> propertyMap) {
+    if (propertyMap.containsKey(REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID) && propertyMap.containsKey(REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID)) {
+      return new ExtensionId(propertyMap.get(REPOSITORY_VERSION_EXTENSION_NAME_PROPERTY_ID).toString(), propertyMap.get(REPOSITORY_VERSION_EXTENSION_VERSION_PROPERTY_ID).toString());
+    }
+    return null;
+  }
+
+  @Override
+  protected ResourceType getResourceType(Request request, Predicate predicate) {
+    // This information is not associated with any particular resource
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionResourceProvider.java
new file mode 100644
index 0000000..b3703ba
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionResourceProvider.java
@@ -0,0 +1,116 @@
+/**
+ * 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.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.ExtensionRequest;
+import org.apache.ambari.server.controller.ExtensionResponse;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class ExtensionResourceProvider extends ReadOnlyResourceProvider {
+
+  public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("Extensions", "extension_name");
+
+  private static Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID }));
+
+  protected ExtensionResourceProvider(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<ExtensionRequest> requests = new HashSet<ExtensionRequest>();
+
+    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<ExtensionResponse> responses = getResources(new Command<Set<ExtensionResponse>>() {
+      @Override
+      public Set<ExtensionResponse> invoke() throws AmbariException {
+        return getManagementController().getExtensions(requests);
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (ExtensionResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.Extension);
+
+      setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+          response.getExtensionName(), requestedIds);
+
+      resource.setProperty(EXTENSION_NAME_PROPERTY_ID, response.getExtensionName());
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  @Override
+  public RequestStatus updateResources(Request request, Predicate predicate)
+    throws SystemException, UnsupportedPropertyException,
+    NoSuchResourceException, NoSuchParentResourceException {
+
+    RequestStatusResponse response = modifyResources(
+      new Command<RequestStatusResponse>() {
+
+      @Override
+      public RequestStatusResponse invoke() throws AmbariException {
+        //return getManagementController().updateExtensions();
+	    //TODO - do we need a separate method
+        return getManagementController().updateStacks();
+      }
+    });
+
+    notifyUpdate(Type.Extension, request, predicate);
+
+    return getRequestStatus(response);
+  }
+
+  private ExtensionRequest getRequest(Map<String, Object> properties) {
+    return new ExtensionRequest((String) properties.get(EXTENSION_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/ExtensionServiceComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceComponentResourceProvider.java
new file mode 100644
index 0000000..71bdfe2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceComponentResourceProvider.java
@@ -0,0 +1,206 @@
+/**
+ * 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.ExtensionServiceComponentRequest;
+import org.apache.ambari.server.controller.ExtensionServiceComponentResponse;
+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.state.AutoDeployInfo;
+
+import java.util.*;
+
+public class ExtensionServiceComponentResourceProvider extends
+    ReadOnlyResourceProvider {
+
+  private static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "extension_name");
+
+  private static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "extension_version");
+
+  private static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "service_name");
+
+  private static final String COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "component_name");
+
+  private static final String COMPONENT_DISPLAY_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+          "ExtensionServiceComponents", "display_name");
+
+  private static final String COMPONENT_CATEGORY_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "component_category");
+
+  private static final String IS_CLIENT_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "is_client");
+
+  private static final String IS_MASTER_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "is_master");
+
+  private static final String CARDINALITY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "cardinality");
+
+  private static final String ADVERTISE_VERSION_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "advertise_version");
+
+  private static final String NOT_PREFERABLE_ON_SERVER_COMPONENTS_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "not_preferable_on_server_components");
+
+  private static final String NOT_VALUABLE_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "not_valuable");
+
+  private static final String USE_CARDINALITY_FOR_LAYOUT_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "use_cardinality_for_layout");
+
+  private static final String LAYOUT_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "layout");
+
+  private static final String IDEAL_MINIMUM_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "ideal_minimum");
+
+  private static final String CUSTOM_COMMANDS_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServiceComponents", "custom_commands");
+
+  private static final String AUTO_DEPLOY_ENABLED_ID = PropertyHelper.getPropertyId(
+      "auto_deploy", "enabled");
+
+  private static final String AUTO_DEPLOY_LOCATION_ID = PropertyHelper.getPropertyId(
+      "auto_deploy", "location");
+
+  private static Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID,
+          EXTENSION_VERSION_PROPERTY_ID, SERVICE_NAME_PROPERTY_ID,
+          COMPONENT_NAME_PROPERTY_ID }));
+
+  protected ExtensionServiceComponentResourceProvider(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<ExtensionServiceComponentRequest> requests = new HashSet<ExtensionServiceComponentRequest>();
+
+    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<ExtensionServiceComponentResponse> responses = getResources(new Command<Set<ExtensionServiceComponentResponse>>() {
+      @Override
+      public Set<ExtensionServiceComponentResponse> invoke() throws AmbariException {
+        return getManagementController().getExtensionComponents(requests);
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (ExtensionServiceComponentResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.ExtensionServiceComponent);
+
+      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, COMPONENT_NAME_PROPERTY_ID,
+          response.getComponentName(), requestedIds);
+
+      setResourceProperty(resource, COMPONENT_DISPLAY_NAME_PROPERTY_ID,
+              response.getComponentDisplayName(), requestedIds);
+
+      setResourceProperty(resource, COMPONENT_CATEGORY_PROPERTY_ID,
+          response.getComponentCategory(), requestedIds);
+
+      setResourceProperty(resource, IS_CLIENT_PROPERTY_ID,
+          response.isClient(), requestedIds);
+
+      setResourceProperty(resource, IS_MASTER_PROPERTY_ID,
+          response.isMaster(), requestedIds);
+
+      setResourceProperty(resource, CARDINALITY_ID,
+          response.getCardinality(), requestedIds);
+
+      setResourceProperty(resource, ADVERTISE_VERSION_ID,
+          response.isVersionAdvertised(), requestedIds);
+
+      setResourceProperty(resource, NOT_PREFERABLE_ON_SERVER_COMPONENTS_ID,
+          response.isNotPreferableOnServerComponents(), requestedIds);
+
+      setResourceProperty(resource, NOT_VALUABLE_ID,
+          response.isNotValuable(), requestedIds);
+
+      setResourceProperty(resource, USE_CARDINALITY_FOR_LAYOUT_ID,
+          response.isUseCardinalityForLayout(), requestedIds);
+
+      setResourceProperty(resource, LAYOUT_ID,
+          response.getLayout(), requestedIds);
+
+      setResourceProperty(resource, IDEAL_MINIMUM_ID,
+          response.getIdealMinimum(), requestedIds);
+
+      setResourceProperty(resource, CUSTOM_COMMANDS_PROPERTY_ID,
+          response.getCustomCommands(), requestedIds);
+
+      AutoDeployInfo autoDeployInfo = response.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);
+        }
+      }
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  private ExtensionServiceComponentRequest getRequest(Map<String, Object> properties) {
+    return new ExtensionServiceComponentRequest(
+        (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+        (String) properties.get(EXTENSION_VERSION_PROPERTY_ID),
+        (String) properties.get(SERVICE_NAME_PROPERTY_ID),
+        (String) properties.get(COMPONENT_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/ExtensionServiceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceResourceProvider.java
new file mode 100644
index 0000000..2d19ffa
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionServiceResourceProvider.java
@@ -0,0 +1,170 @@
+/**
+ * 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.inject.Inject;
+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.ExtensionServiceRequest;
+import org.apache.ambari.server.controller.ExtensionServiceResponse;
+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.state.kerberos.KerberosServiceDescriptor;
+import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+@StaticallyInject
+public class ExtensionServiceResourceProvider extends ReadOnlyResourceProvider {
+
+  protected static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "service_name");
+
+  public static final String EXTENSION_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "extension_name");
+
+  public static final String EXTENSION_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "extension_version");
+
+  private static final String SERVICE_DISPLAY_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "display_name");
+
+  private static final String USER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "user_name");
+
+  private static final String COMMENTS_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "comments");
+
+  private static final String VERSION_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "service_version");
+
+  private static final String CONFIG_TYPES = PropertyHelper.getPropertyId(
+      "ExtensionServices", "config_types");
+
+  private static final String REQUIRED_SERVICES_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "required_services");
+
+  private static final String SERVICE_CHECK_SUPPORTED_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "service_check_supported");
+
+  private static final String CUSTOM_COMMANDS_PROPERTY_ID = PropertyHelper.getPropertyId(
+      "ExtensionServices", "custom_commands");
+
+  private static Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID,
+          EXTENSION_VERSION_PROPERTY_ID, SERVICE_NAME_PROPERTY_ID }));
+
+  /**
+   * KerberosServiceDescriptorFactory used to create KerberosServiceDescriptor instances
+   */
+  @Inject
+  private static KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory;
+
+  protected ExtensionServiceResourceProvider(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<ExtensionServiceRequest> requests = new HashSet<ExtensionServiceRequest>();
+
+    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<ExtensionServiceResponse> responses = getResources(new Command<Set<ExtensionServiceResponse>>() {
+      @Override
+      public Set<ExtensionServiceResponse> invoke() throws AmbariException {
+        return getManagementController().getExtensionServices(requests);
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (ExtensionServiceResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.ExtensionService);
+
+      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, SERVICE_DISPLAY_NAME_PROPERTY_ID,
+          response.getServiceDisplayName(), requestedIds);
+
+      setResourceProperty(resource, USER_NAME_PROPERTY_ID,
+          response.getUserName(), requestedIds);
+
+      setResourceProperty(resource, COMMENTS_PROPERTY_ID,
+          response.getComments(), requestedIds);
+
+      setResourceProperty(resource, VERSION_PROPERTY_ID,
+          response.getServiceVersion(), requestedIds);
+
+      setResourceProperty(resource, CONFIG_TYPES,
+          response.getConfigTypes(), requestedIds);
+
+      setResourceProperty(resource, REQUIRED_SERVICES_ID,
+          response.getRequiredServices(), requestedIds);
+
+      setResourceProperty(resource, SERVICE_CHECK_SUPPORTED_PROPERTY_ID,
+          response.isServiceCheckSupported(), requestedIds);
+
+      setResourceProperty(resource, CUSTOM_COMMANDS_PROPERTY_ID,
+          response.getCustomCommands(), requestedIds);
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  private ExtensionServiceRequest getRequest(Map<String, Object> properties) {
+    return new ExtensionServiceRequest(
+        (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+        (String) properties.get(EXTENSION_VERSION_PROPERTY_ID),
+        (String) properties.get(SERVICE_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/ExtensionVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionVersionResourceProvider.java
new file mode 100644
index 0000000..003063e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExtensionVersionResourceProvider.java
@@ -0,0 +1,203 @@
+/**
+ * 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.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.inject.Inject;
+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.ExtensionVersionRequest;
+import org.apache.ambari.server.controller.ExtensionVersionResponse;
+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.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;
+
+@StaticallyInject
+public class ExtensionVersionResourceProvider extends ReadOnlyResourceProvider {
+
+  public static final String EXTENSION_VERSION_PROPERTY_ID     = PropertyHelper.getPropertyId("Versions", "extension_version");
+  public static final String EXTENSION_NAME_PROPERTY_ID        = PropertyHelper.getPropertyId("Versions", "extension_name");
+  public static final String EXTENSION_MIN_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Versions", "min_upgrade_version");
+  public static final String EXTENSION_ACTIVE_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "active");
+  public static final String EXTENSION_VALID_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "valid");
+  public static final String EXTENSION_ERROR_SET      = PropertyHelper.getPropertyId("Versions", "extension-errors");
+  public static final String EXTENSION_CONFIG_TYPES            = PropertyHelper.getPropertyId("Versions", "config_types");
+  public static final String EXTENSION_PARENT_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "parent_extension_version");
+  public static final String UPGRADE_PACKS_PROPERTY_ID = PropertyHelper.getPropertyId("Versions", "upgrade_packs");
+
+  private static Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { EXTENSION_NAME_PROPERTY_ID, EXTENSION_VERSION_PROPERTY_ID }));
+
+  /**
+   * KerberosDescriptorFactory used to create KerberosDescriptor instances
+   */
+  @Inject
+  private static KerberosDescriptorFactory kerberosDescriptorFactory;
+
+  /**
+   * KerberosServiceDescriptorFactory used to create KerberosServiceDescriptor instances
+   */
+  @Inject
+  private static KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory;
+
+  protected ExtensionVersionResourceProvider(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<ExtensionVersionRequest> requests = new HashSet<ExtensionVersionRequest>();
+
+    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<ExtensionVersionResponse> responses = getResources(new Command<Set<ExtensionVersionResponse>>() {
+      @Override
+      public Set<ExtensionVersionResponse> invoke() throws AmbariException {
+        return getManagementController().getExtensionVersions(requests);
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (ExtensionVersionResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.ExtensionVersion);
+
+      setResourceProperty(resource, EXTENSION_NAME_PROPERTY_ID,
+          response.getExtensionName(), requestedIds);
+
+      setResourceProperty(resource, EXTENSION_VERSION_PROPERTY_ID,
+          response.getExtensionVersion(), requestedIds);
+
+      /*setResourceProperty(resource, EXTENSION_MIN_VERSION_PROPERTY_ID,
+          response.getMinUpgradeVersion(), requestedIds);
+
+      setResourceProperty(resource, EXTENSION_ACTIVE_PROPERTY_ID,
+          response.isActive(), requestedIds);*/
+
+      setResourceProperty(resource, EXTENSION_VALID_PROPERTY_ID,
+          response.isValid(), requestedIds);
+
+      setResourceProperty(resource, EXTENSION_ERROR_SET,
+          response.getErrors(), requestedIds);
+
+      setResourceProperty(resource, EXTENSION_PARENT_PROPERTY_ID,
+        response.getParentVersion(), requestedIds);
+
+      setResourceProperty(resource, EXTENSION_CONFIG_TYPES,
+          response.getConfigTypes(), requestedIds);
+
+      setResourceProperty(resource, UPGRADE_PACKS_PROPERTY_ID,
+          response.getUpgradePacks(), requestedIds);
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  /**
+   * Given data from a ExtensionVersionResponse build a complete Kerberos descriptor hierarchy.
+   *
+   * @param extensionVersionResponse the ExtensionVersionResponse instance containing the details of the
+   *                             extension and the relevant Kerberos descriptor files
+   * @return a KerberosDescriptor containing the complete hierarchy for the extension
+   * @throws IOException     if the specified File is not found or not a readable
+   * @throws AmbariException if the specified File does not contain valid JSON-encoded Kerberos
+   *                         descriptor
+   */
+  private KerberosDescriptor buildKerberosDescriptor(ExtensionVersionResponse extensionVersionResponse)
+      throws IOException {
+    KerberosDescriptor kerberosDescriptor = null;
+
+    // Process the extension-level Kerberos descriptor file
+    File extensionKerberosDescriptorFile = extensionVersionResponse.getExtensionKerberosDescriptorFile();
+    if (extensionKerberosDescriptorFile != null) {
+      kerberosDescriptor = kerberosDescriptorFactory.createInstance(extensionKerberosDescriptorFile);
+    }
+
+    // Process the service-level Kerberos descriptor files
+    Collection<File> serviceDescriptorFiles = extensionVersionResponse.getServiceKerberosDescriptorFiles();
+    if ((serviceDescriptorFiles != null) && !serviceDescriptorFiles.isEmpty()) {
+      // Make sure kerberosDescriptor is not null. This will be the case if there is no extension-level
+      // Kerberos descriptor file.
+      if (kerberosDescriptor == null) {
+        kerberosDescriptor = new KerberosDescriptor();
+      }
+
+      // For each service-level Kerberos descriptor file, parse into an array of KerberosServiceDescriptors
+      // and then append each to the KerberosDescriptor hierarchy.
+      for (File file : serviceDescriptorFiles) {
+        KerberosServiceDescriptor[] serviceDescriptors = kerberosServiceDescriptorFactory.createInstances(file);
+
+        if (serviceDescriptors != null) {
+          for (KerberosServiceDescriptor serviceDescriptor : serviceDescriptors) {
+            kerberosDescriptor.putService(serviceDescriptor);
+          }
+        }
+      }
+    }
+
+    return kerberosDescriptor;
+  }
+
+  private ExtensionVersionRequest getRequest(Map<String, Object> properties) {
+    return new ExtensionVersionRequest(
+        (String) properties.get(EXTENSION_NAME_PROPERTY_ID),
+        (String) properties.get(EXTENSION_VERSION_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/RequestImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
index f27f621..5d9ebff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
@@ -100,6 +100,7 @@ public class RequestImpl implements Request {
   public RequestImpl(Set<String> propertyIds, Set<Map<String, Object>> properties,
                      Map<String, String> requestInfoProperties, Map<String, TemporalInfo> mapTemporalInfo,
                      SortRequest sortRequest, PageRequest pageRequest) {
+
     this.propertyIds = propertyIds == null ?
         Collections.unmodifiableSet(new HashSet<String>()) :
         Collections.unmodifiableSet(propertyIds);

http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackServiceComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackServiceComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackServiceComponentResourceProvider.java
index bf5ad67..bd156d5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackServiceComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackServiceComponentResourceProvider.java
@@ -62,6 +62,21 @@ public class StackServiceComponentResourceProvider extends
   private static final String ADVERTISE_VERSION_ID = PropertyHelper.getPropertyId(
       "StackServiceComponents", "advertise_version");
 
+  private static final String NOT_PREFERABLE_ON_SERVER_COMPONENTS_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "not_preferable_on_server_components");
+
+  private static final String NOT_VALUABLE_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "not_valuable");
+
+  private static final String USE_CARDINALITY_FOR_LAYOUT_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "use_cardinality_for_layout");
+
+  private static final String LAYOUT_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "layout");
+
+  private static final String IDEAL_MINIMUM_ID = PropertyHelper.getPropertyId(
+      "StackServiceComponents", "ideal_minimum");
+
   private static final String CUSTOM_COMMANDS_PROPERTY_ID = PropertyHelper.getPropertyId(
       "StackServiceComponents", "custom_commands");
 
@@ -141,6 +156,21 @@ public class StackServiceComponentResourceProvider extends
       setResourceProperty(resource, ADVERTISE_VERSION_ID,
           response.isVersionAdvertised(), requestedIds);
 
+      setResourceProperty(resource, NOT_PREFERABLE_ON_SERVER_COMPONENTS_ID,
+          response.isNotPreferableOnServerComponents(), requestedIds);
+
+      setResourceProperty(resource, NOT_VALUABLE_ID,
+          response.isNotValuable(), requestedIds);
+
+      setResourceProperty(resource, USE_CARDINALITY_FOR_LAYOUT_ID,
+          response.isUseCardinalityForLayout(), requestedIds);
+
+      setResourceProperty(resource, LAYOUT_ID,
+          response.getLayout(), requestedIds);
+
+      setResourceProperty(resource, IDEAL_MINIMUM_ID,
+          response.getIdealMinimum(), requestedIds);
+
       setResourceProperty(resource, CUSTOM_COMMANDS_PROPERTY_ID,
           response.getCustomCommands(), requestedIds);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 55816a3..c3a9392 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -91,13 +91,23 @@ public interface Resource {
     Member,
     Stack,
     StackVersion,
+    ExtensionLink,
+    Extension,
+    ExtensionVersion,
+    ExtensionOperatingSystem,
+    ExtensionRepository,
     OperatingSystem,
     Repository,
     StackService,
+    ExtensionService,
     StackConfiguration,
     StackConfigurationDependency,
     StackServiceComponent,
     StackServiceComponentDependency,
+    ExtensionConfiguration,
+    ExtensionConfigurationDependency,
+    ExtensionServiceComponent,
+    ExtensionServiceComponentDependency,
     DRFeed,
     DRTargetCluster,
     DRInstance,
@@ -127,10 +137,13 @@ public interface Resource {
     ViewPermission,
     ClientConfig,
     StackLevelConfiguration,
+    ExtensionLevelConfiguration,
     LdapSyncEvent,
     UserPrivilege,
     RepositoryVersion,
     CompatibleRepositoryVersion,
+    ExtensionRepositoryVersion,
+    CompatibleExtensionRepositoryVersion,
     ClusterStackVersion,
     HostStackVersion,
     Upgrade,
@@ -139,6 +152,7 @@ public interface Resource {
     PreUpgradeCheck,
     Stage,
     StackArtifact,
+    ExtensionArtifact,
     Artifact,
     Widget,
     WidgetLayout,
@@ -200,6 +214,11 @@ public interface Resource {
     public static final Type Member = InternalType.Member.getType();
     public static final Type Stack = InternalType.Stack.getType();
     public static final Type StackVersion = InternalType.StackVersion.getType();
+    public static final Type ExtensionLink = InternalType.ExtensionLink.getType();
+    public static final Type Extension = InternalType.Extension.getType();
+    public static final Type ExtensionVersion = InternalType.ExtensionVersion.getType();
+    public static final Type ExtensionOperatingSystem = InternalType.ExtensionOperatingSystem.getType();
+    public static final Type ExtensionRepository = InternalType.ExtensionRepository.getType();
     public static final Type OperatingSystem = InternalType.OperatingSystem.getType();
     public static final Type Repository = InternalType.Repository.getType();
     public static final Type StackService = InternalType.StackService.getType();
@@ -207,6 +226,11 @@ public interface Resource {
     public static final Type StackConfigurationDependency = InternalType.StackConfigurationDependency.getType();
     public static final Type StackServiceComponent = InternalType.StackServiceComponent.getType();
     public static final Type StackServiceComponentDependency = InternalType.StackServiceComponentDependency.getType();
+    public static final Type ExtensionService = InternalType.ExtensionService.getType();
+    public static final Type ExtensionConfiguration = InternalType.ExtensionConfiguration.getType();
+    public static final Type ExtensionConfigurationDependency = InternalType.ExtensionConfigurationDependency.getType();
+    public static final Type ExtensionServiceComponent = InternalType.ExtensionServiceComponent.getType();
+    public static final Type ExtensionServiceComponentDependency = InternalType.ExtensionServiceComponentDependency.getType();
     public static final Type DRFeed = InternalType.DRFeed.getType();
     public static final Type DRTargetCluster = InternalType.DRTargetCluster.getType();
     public static final Type DRInstance = InternalType.DRInstance.getType();
@@ -236,10 +260,13 @@ public interface Resource {
     public static final Type ViewPermission = InternalType.ViewPermission.getType();
     public static final Type ClientConfig = InternalType.ClientConfig.getType();
     public static final Type StackLevelConfiguration = InternalType.StackLevelConfiguration.getType();
+    public static final Type ExtensionLevelConfiguration = InternalType.ExtensionLevelConfiguration.getType();
     public static final Type LdapSyncEvent = InternalType.LdapSyncEvent.getType();
     public static final Type UserPrivilege = InternalType.UserPrivilege.getType();
     public static final Type RepositoryVersion = InternalType.RepositoryVersion.getType();
     public static final Type CompatibleRepositoryVersion = InternalType.CompatibleRepositoryVersion.getType();
+    public static final Type ExtensionRepositoryVersion = InternalType.ExtensionRepositoryVersion.getType();
+    public static final Type CompatibleExtensionRepositoryVersion = InternalType.CompatibleExtensionRepositoryVersion.getType();
     public static final Type ClusterStackVersion = InternalType.ClusterStackVersion.getType();
     public static final Type HostStackVersion = InternalType.HostStackVersion.getType();
     public static final Type Upgrade = InternalType.Upgrade.getType();
@@ -248,6 +275,7 @@ public interface Resource {
     public static final Type PreUpgradeCheck = InternalType.PreUpgradeCheck.getType();
     public static final Type Stage = InternalType.Stage.getType();
     public static final Type StackArtifact = InternalType.StackArtifact.getType();
+    public static final Type ExtensionArtifact = InternalType.ExtensionArtifact.getType();
     public static final Type Artifact = InternalType.Artifact.getType();
     public static final Type Theme = InternalType.Theme.getType();
     public static final Type Widget = InternalType.Widget.getType();

http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
index cefe953..88d5d59 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
@@ -285,6 +285,9 @@ public class PropertyHelper {
    * @return true if the given property id contains any replacement arguments
    */
   public static boolean containsArguments(String propertyId) {
+    if (propertyId == null) {
+	return false;
+    }
     if (!propertyId.contains("$")) {
       return false;
     }
@@ -481,6 +484,8 @@ public class PropertyHelper {
           mapper.readValue(ClassLoader.getSystemResourceAsStream(filename),
               new TypeReference<Map<Resource.InternalType, Map<Resource.InternalType, String>>>() {});
 
+      printKeyPropertyIdsInternal(map, "internal");
+
       Map<Resource.InternalType, Map<Resource.Type, String>> returnMap =
           new HashMap<Resource.InternalType, Map<Resource.Type, String>>();
 
@@ -489,16 +494,41 @@ public class PropertyHelper {
         Map<Resource.Type, String> innerMap = new HashMap<Resource.Type, String>();
 
         for (Map.Entry<Resource.InternalType, String> entry1 : entry.getValue().entrySet()) {
-          innerMap.put(Resource.Type.values()[entry1.getKey().ordinal()], entry1.getValue());
+          innerMap.put(Resource.Type.valueOf(entry1.getKey().name()), entry1.getValue());
         }
         returnMap.put(entry.getKey(), innerMap);
       }
+      printKeyPropertyIds(returnMap, "final");
       return returnMap;
     } catch (IOException e) {
       throw new IllegalStateException("Can't read properties file " + filename, e);
     }
   }
 
+  public static void printKeyPropertyIdsInternal(Map<Resource.InternalType, Map<Resource.InternalType, String>> ids, String type) {
+      System.out.println("TIM PRINT START " + type);
+      for (Map.Entry<Resource.InternalType, Map<Resource.InternalType, String>> entry : ids.entrySet()) {
+        Map<Resource.InternalType, String> map = entry.getValue();
+        for (Map.Entry<Resource.InternalType, String> innerEntry : map.entrySet()) {
+          String value = innerEntry.getValue();
+          System.out.println(entry.getKey().name() + ": " + innerEntry.getKey().name() + "/" + value);
+        }
+      }
+      System.out.println("TIM PRINT END " + type);
+  }
+
+  public static void printKeyPropertyIds(Map<Resource.InternalType, Map<Resource.Type, String>> ids, String type) {
+      System.out.println("TIM PRINT START " + type);
+      for (Map.Entry<Resource.InternalType, Map<Resource.Type, String>> entry : ids.entrySet()) {
+        Map<Resource.Type, String> map = entry.getValue();
+        for (Map.Entry<Resource.Type, String> innerEntry : map.entrySet()) {
+          String value = innerEntry.getValue();
+          System.out.println(entry.getKey().name() + ": " + innerEntry.getKey().name() + "/" + value);
+        }
+      }
+      System.out.println("TIM PRINT END " + type);
+  }
+
   protected static class Metric {
     private String metric;
     private boolean pointInTime;

http://git-wip-us.apache.org/repos/asf/ambari/blob/647929db/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java
index 74d4f4b..1b83223 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java
@@ -23,6 +23,7 @@ import java.util.concurrent.locks.ReentrantLock;
 import org.apache.ambari.server.EagerSingleton;
 import org.apache.ambari.server.events.HostComponentVersionEvent;
 import org.apache.ambari.server.events.publishers.VersionEventPublisher;
+import org.apache.ambari.server.orm.entities.ExtensionRepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.ServiceComponentHost;
@@ -83,6 +84,10 @@ public class StackVersionListener {
       if (null != repoVersion) {
         cluster.recalculateClusterVersionState(repoVersion);
       }
+      ExtensionRepositoryVersionEntity extensionRepoVersion = sch.recalculateHostExtensionVersionState();
+      if (null != extensionRepoVersion) {
+        cluster.recalculateClusterExtensionVersionState(extensionRepoVersion);
+      }
     } catch (Exception e) {
       LOG.error(
           "Unable to propagate version for ServiceHostComponent on component: {}, host: {}. Error: {}",


Mime
View raw message