You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/02/24 16:07:54 UTC

[07/50] [abbrv] ambari git commit: AMBARI-14804. Move Version Definition to its own endpoint (ncole)

AMBARI-14804. Move Version Definition to its own endpoint (ncole)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/986a5188
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/986a5188
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/986a5188

Branch: refs/heads/trunk
Commit: 986a5188334b51cf5728b4b54c2aefc48866558e
Parents: c7be26a
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Jan 26 15:30:06 2016 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Jan 27 09:36:31 2016 -0500

----------------------------------------------------------------------
 .../resources/ResourceInstanceFactoryImpl.java  |   4 +
 .../VersionDefinitionResourceDefinition.java    |  93 ++++++
 .../api/services/VersionDefinitionService.java  |  70 ++++
 .../AbstractControllerResourceProvider.java     |   3 +-
 .../RepositoryVersionResourceProvider.java      |  93 ++----
 .../VersionDefinitionResourceProvider.java      | 331 +++++++++++++++++++
 .../ambari/server/controller/spi/Resource.java  |   4 +-
 .../server/orm/dao/RepositoryVersionDAO.java    |  16 +-
 .../orm/entities/RepositoryVersionEntity.java   |  17 +-
 .../ambari/server/state/repository/Release.java |  20 ++
 .../src/main/resources/version_definition.xsd   |   1 +
 .../RepositoryVersionResourceProviderTest.java  |  39 ++-
 12 files changed, 601 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 070a505..987c11b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -412,6 +412,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
         resourceDefinition = new SimpleResourceDefinition(Resource.Type.AdminSetting, "admin-setting", "admin-settings");
         break;
 
+      case VersionDefinition:
+        resourceDefinition = new VersionDefinitionResourceDefinition();
+        break;
+
       default:
         throw new IllegalArgumentException("Unsupported resource type: " + type);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/api/resources/VersionDefinitionResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/VersionDefinitionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/VersionDefinitionResourceDefinition.java
new file mode 100644
index 0000000..67d9439
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/VersionDefinitionResourceDefinition.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.api.resources;
+
+import java.util.List;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.internal.RepositoryVersionResourceProvider;
+import org.apache.ambari.server.controller.internal.VersionDefinitionResourceProvider;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import com.google.common.collect.Lists;
+
+/**
+ * The Resource Definition used for Version Definition files.
+ */
+public class VersionDefinitionResourceDefinition extends BaseResourceDefinition {
+  private static final String STACKS_NAME = new StackResourceDefinition().getPluralName();
+  private static final String STACK_VERSIONS_NAME = new StackVersionResourceDefinition().getPluralName();
+  private static final String REPO_VERSIONS_NAME = new RepositoryVersionResourceDefinition().getPluralName();
+
+  private static final String HREF_TEMPLATE =
+      STACKS_NAME + "/%s/" + STACK_VERSIONS_NAME + "/%s/" + REPO_VERSIONS_NAME;
+
+
+  public VersionDefinitionResourceDefinition() {
+    super(Resource.Type.VersionDefinition);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "version_definitions";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "version_definition";
+  }
+
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    List<PostProcessor> list = Lists.newArrayList();
+
+    list.add(new HrefPostProcessor());
+
+    return list;
+  }
+
+
+  class HrefPostProcessor extends BaseHrefPostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      super.process(request, resultNode, href);
+
+      Object stackNameObj = resultNode.getObject().getPropertyValue(
+          VersionDefinitionResourceProvider.VERSION_DEF_STACK_NAME);
+      Object stackVersionObj = resultNode.getObject().getPropertyValue(
+          VersionDefinitionResourceProvider.VERSION_DEF_STACK_VERSION);
+
+      if (resultNode.getObject().getType() == Resource.Type.VersionDefinition &&
+          null != stackNameObj && null != stackVersionObj &&
+          null != resultNode.getProperty("href")) {
+
+        String oldHref = resultNode.getProperty("href").toString();
+
+        String newPath = String.format(HREF_TEMPLATE, stackNameObj, stackVersionObj);
+
+        String newHref = oldHref.replace(getPluralName(), newPath);
+        newHref = newHref.replace(VersionDefinitionResourceProvider.VERSION_DEF,
+            RepositoryVersionResourceProvider.REPOSITORY_VERSION);
+
+        resultNode.setProperty("href", newHref);
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/api/services/VersionDefinitionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/VersionDefinitionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/VersionDefinitionService.java
new file mode 100644
index 0000000..43eb424
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/VersionDefinitionService.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import java.util.Collections;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+@Path("/version_definitions/")
+public class VersionDefinitionService extends BaseService {
+
+  @GET
+  @Produces("text/plain")
+  public Response getServices(@Context HttpHeaders headers, @Context UriInfo ui) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createResource(null));
+  }
+
+  @GET
+  @Path("{versionId}")
+  @Produces("text/plain")
+  public Response getService(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("versionId") Long versionId) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createResource(versionId));
+  }
+
+  @POST
+  @Produces("text/plain")
+  public Response createVersion(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, body, ui, Request.Type.POST,
+        createResource(null));
+  }
+
+  protected ResourceInstance createResource(Long versionId) {
+    return createResource(Resource.Type.VersionDefinition,
+        Collections.singletonMap(Resource.Type.VersionDefinition,
+            null == versionId ? null : versionId.toString()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 61fbd8a..586924b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -219,7 +219,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
         return new RoleAuthorizationResourceProvider(managementController);
       case UserAuthorization:
         return new UserAuthorizationResourceProvider(managementController);
-
+      case VersionDefinition:
+        return new VersionDefinitionResourceProvider();
       default:
         throw new IllegalArgumentException("Unknown type " + type);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
index 92b14b7..873733d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
@@ -17,7 +17,6 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import java.net.URL;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -65,7 +64,6 @@ import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 
@@ -82,7 +80,7 @@ import com.google.inject.persist.Transactional;
 public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourceProvider {
 
   // ----- Property ID constants ---------------------------------------------
-
+  public static final String REPOSITORY_VERSION                                = "RepositoryVersions";
   public static final String REPOSITORY_VERSION_ID_PROPERTY_ID                 = PropertyHelper.getPropertyId("RepositoryVersions", "id");
   public static final String REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID         = PropertyHelper.getPropertyId("RepositoryVersions", "stack_name");
   public static final String REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID      = PropertyHelper.getPropertyId("RepositoryVersions", "stack_version");
@@ -92,7 +90,6 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
   public static final String SUBRESOURCE_REPOSITORIES_PROPERTY_ID              = new RepositoryResourceDefinition().getPluralName();
 
   public static final String REPOSITORY_VERSION_TYPE_PROPERTY_ID               = "RepositoryVersions/type";
-  public static final String REPOSITORY_VERSION_DEFINITION_URL                 = "RepositoryVersions/version_url";
   public static final String REPOSITORY_VERSION_RELEASE_VERSION                = "RepositoryVersions/release/version";
   public static final String REPOSITORY_VERSION_RELEASE_BUILD                  = "RepositoryVersions/release/build";
   public static final String REPOSITORY_VERSION_RELEASE_NOTES                  = "RepositoryVersions/release/notes";
@@ -113,7 +110,6 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
       REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
       REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID,
       REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID,
-      REPOSITORY_VERSION_DEFINITION_URL,
       SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
       REPOSITORY_VERSION_TYPE_PROPERTY_ID,
       REPOSITORY_VERSION_RELEASE_BUILD,
@@ -192,20 +188,14 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
             REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID
           };
 
-          final RepositoryVersionEntity entity;
-          if (properties.containsKey(REPOSITORY_VERSION_DEFINITION_URL)) {
-            String definitionUrl = (String) properties.get(REPOSITORY_VERSION_DEFINITION_URL);
-
-            entity = toRepositoryVersionEntity(definitionUrl);
-          } else {
-            for (String propertyName : requiredProperties) {
-              if (properties.get(propertyName) == null) {
-                throw new AmbariException("Property " + propertyName + " should be provided");
-              }
+          for (String propertyName : requiredProperties) {
+            if (properties.get(propertyName) == null) {
+              throw new AmbariException("Property " + propertyName + " should be provided");
             }
-            entity = toRepositoryVersionEntity(properties);
           }
 
+          RepositoryVersionEntity entity = toRepositoryVersionEntity(properties);
+
           if (repositoryVersionDAO.findByDisplayName(entity.getDisplayName()) != null) {
             throw new AmbariException("Repository version with name " + entity.getDisplayName() + " already exists");
           }
@@ -213,7 +203,12 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
             throw new AmbariException("Repository version for stack " + entity.getStack() + " and version " + entity.getVersion() + " already exists");
           }
 
-          validateRepositoryVersion(entity);
+          if (!upgradePackExists(entity.getVersion())) {
+            throw new AmbariException("Stack " + entity.getStackId() + " doesn't have upgrade packages");
+          }
+
+          validateRepositoryVersion(repositoryVersionDAO, ambariMetaInfo, entity);
+
           repositoryVersionDAO.create(entity);
           notifyCreate(Resource.Type.RepositoryVersion, request);
           return null;
@@ -336,7 +331,12 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
             entity.setDisplayName(propertyMap.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID).toString());
           }
 
-          validateRepositoryVersion(entity);
+          if (!upgradePackExists(entity.getVersion())) {
+            throw new AmbariException("Stack " + entity.getStackId() + " doesn't have upgrade packages");
+          }
+
+          validateRepositoryVersion(repositoryVersionDAO, ambariMetaInfo, entity);
+
           repositoryVersionDAO.merge(entity);
 
           //
@@ -420,20 +420,17 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
    * @param repositoryVersion repository version
    * @throws AmbariException exception with error message
    */
-  protected void validateRepositoryVersion(RepositoryVersionEntity repositoryVersion) throws AmbariException {
+  protected static void validateRepositoryVersion(RepositoryVersionDAO dao,
+      AmbariMetaInfo metaInfo, RepositoryVersionEntity repositoryVersion) throws AmbariException {
     final StackId requiredStack = new StackId(repositoryVersion.getStack());
 
     final String requiredStackName = requiredStack.getStackName();
     final String requiredStackVersion = requiredStack.getStackVersion();
     final String requiredStackId = requiredStack.getStackId();
 
-    if (!upgradePackExists(repositoryVersion.getVersion())) {
-      throw new AmbariException("Stack " + requiredStackId + " doesn't have upgrade packages");
-    }
-
     // List of all repo urls that are already added at stack
     Set<String> existingRepoUrls = new HashSet<String>();
-    List<RepositoryVersionEntity> existingRepoVersions = repositoryVersionDAO.findByStack(requiredStack);
+    List<RepositoryVersionEntity> existingRepoVersions = dao.findByStack(requiredStack);
     for (RepositoryVersionEntity existingRepoVersion : existingRepoVersions) {
       for (OperatingSystemEntity operatingSystemEntity : existingRepoVersion.getOperatingSystems()) {
         for (RepositoryEntity repositoryEntity : operatingSystemEntity.getRepositories()) {
@@ -447,9 +444,10 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
 
     // check that repositories contain only supported operating systems
     final Set<String> osSupported = new HashSet<String>();
-    for (OperatingSystemInfo osInfo: ambariMetaInfo.getOperatingSystems(requiredStackName, requiredStackVersion)) {
+    for (OperatingSystemInfo osInfo: metaInfo.getOperatingSystems(requiredStackName, requiredStackVersion)) {
       osSupported.add(osInfo.getOsType());
     }
+
     final Set<String> osRepositoryVersion = new HashSet<String>();
     for (OperatingSystemEntity os: repositoryVersion.getOperatingSystems()) {
       osRepositoryVersion.add(os.getOsType());
@@ -486,7 +484,7 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
     Collection<StackInfo> stacks = new ArrayList<StackInfo>();
 
     // Search results only in the installed stacks
-    for (Cluster cluster:clusters.get().getClusters().values()){
+    for (Cluster cluster : clusters.get().getClusters().values()){
       stacks.add(ambariMetaInfo.getStack(cluster.getCurrentStackVersion().getStackName(),
                                           cluster.getCurrentStackVersion().getStackVersion()));
     }
@@ -537,49 +535,6 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc
     return entity;
   }
 
-  /**
-   * Transforms a XML version defintion to an entity
-   *
-   * @param definitionUrl the String URL for loading
-   * @return constructed entity
-   * @throws AmbariException if some properties are missing or json has incorrect structure
-   */
-  protected RepositoryVersionEntity toRepositoryVersionEntity(String definitionUrl) throws AmbariException {
-    final VersionDefinitionXml xml;
-    final String xmlString;
-    try {
-      URL url = new URL(definitionUrl);
-
-      xmlString = IOUtils.toString(url.openStream(), "UTF-8");
-
-      xml = VersionDefinitionXml.load(xmlString);
-    } catch (Exception e) {
-      String err = String.format("Could not load url from %s.  %s",
-          definitionUrl, e.getMessage());
-      throw new AmbariException(err, e);
-    }
-
-    // !!! TODO validate parsed object graph
-
-    RepositoryVersionEntity entity = new RepositoryVersionEntity();
-
-    StackId stackId = new StackId(xml.release.stackId);
-
-    StackEntity stackEntity = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
-
-    entity.setStack(stackEntity);
-    entity.setOperatingSystems(repositoryVersionHelper.serializeOperatingSystems(
-        xml.repositoryInfo.getRepositories()));
-    entity.setVersion(xml.release.version + "-" + StringUtils.stripToEmpty(xml.release.build));
-    entity.setDisplayName(stackId.getStackName() + "-" + entity.getVersion());
-    entity.setType(xml.release.repositoryType);
-    entity.setVersionUrl(definitionUrl);
-    entity.setVersionXml(xmlString);
-    entity.setVersionXsd(xml.xsdLocation);
-
-    return entity;
-  }
-
   protected StackId getStackInformationFromUrl(Map<String, Object> propertyMap) {
     if (propertyMap.containsKey(REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID) && propertyMap.containsKey(REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID)) {
       return new StackId(propertyMap.get(REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).toString(), propertyMap.get(REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID).toString());

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
new file mode 100644
index 0000000..4b0d3cc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
@@ -0,0 +1,331 @@
+/*
+ * 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.net.URL;
+import java.util.Collections;
+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 org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StaticallyInject;
+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.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
+import org.apache.commons.io.IOUtils;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+/**
+ * The {@link VersionDefinitionResourceProvider} class deals with managing Version Definition
+ * files.
+ */
+@StaticallyInject
+public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourceProvider {
+
+  public static final String VERSION_DEF                             = "VersionDefinition";
+  protected static final String VERSION_DEF_ID                       = "VersionDefinition/id";
+
+  public static final String VERSION_DEF_STACK_NAME                  = "VersionDefinition/stack_name";
+  public static final String VERSION_DEF_STACK_VERSION               = "VersionDefinition/stack_version";
+
+  protected static final String VERSION_DEF_TYPE_PROPERTY_ID         = "VersionDefinition/type";
+  protected static final String VERSION_DEF_DEFINITION_URL           = "VersionDefinition/version_url";
+  protected static final String VERSION_DEF_FULL_VERSION             = "VersionDefinition/repository_version";
+  protected static final String VERSION_DEF_RELEASE_VERSION          = "VersionDefinition/release/version";
+  protected static final String VERSION_DEF_RELEASE_BUILD            = "VersionDefinition/release/build";
+  protected static final String VERSION_DEF_RELEASE_NOTES            = "VersionDefinition/release/notes";
+  protected static final String VERSION_DEF_RELEASE_COMPATIBLE_WITH  = "VersionDefinition/release/compatible_with";
+    protected static final String VERSION_DEF_AVAILABLE_SERVICES     = "VersionDefinition/services";
+
+  @Inject
+  private static RepositoryVersionDAO s_repoVersionDAO;
+
+  @Inject
+  private static Provider<AmbariMetaInfo> s_metaInfo;
+
+  @Inject
+  private static Provider<RepositoryVersionHelper> s_repoVersionHelper;
+
+  @Inject
+  private static StackDAO s_stackDAO;
+
+  /**
+   * Key property ids
+   */
+  private static final Set<String> PK_PROPERTY_IDS = Sets.newHashSet(
+      VERSION_DEF_ID,
+      VERSION_DEF_STACK_NAME,
+      VERSION_DEF_STACK_VERSION,
+      VERSION_DEF_FULL_VERSION);
+
+  /**
+   * The property ids for an version definition resource.
+   */
+  private static final Set<String> PROPERTY_IDS = Sets.newHashSet(
+      VERSION_DEF_ID,
+      VERSION_DEF_TYPE_PROPERTY_ID,
+      VERSION_DEF_DEFINITION_URL,
+      VERSION_DEF_FULL_VERSION,
+      VERSION_DEF_RELEASE_NOTES,
+      VERSION_DEF_RELEASE_COMPATIBLE_WITH,
+      VERSION_DEF_RELEASE_VERSION,
+      VERSION_DEF_RELEASE_BUILD,
+      VERSION_DEF_AVAILABLE_SERVICES);
+
+  /**
+   * The key property ids for an version definition resource.
+   */
+  private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>();
+
+  static {
+    KEY_PROPERTY_IDS.put(Resource.Type.VersionDefinition, VERSION_DEF_ID);
+  }
+
+  /**
+   * Constructor.
+   */
+  VersionDefinitionResourceProvider() {
+    super(PROPERTY_IDS, KEY_PROPERTY_IDS);
+
+    setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+
+    setRequiredGetAuthorizations(EnumSet.of(
+        RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+  }
+
+  @Override
+  protected RequestStatus createResourcesAuthorized(final Request request)
+      throws SystemException,
+      UnsupportedPropertyException, ResourceAlreadyExistsException,
+      NoSuchParentResourceException {
+
+    Set<Map<String, Object>> requestProperties = request.getProperties();
+
+    if (requestProperties.size() > 1) {
+      throw new SystemException("Cannot process more than one file per request");
+    }
+
+    final Map<String, Object> properties = requestProperties.iterator().next();
+    if (!properties.containsKey(VERSION_DEF_DEFINITION_URL)) {
+      throw new SystemException(String.format("%s is required", VERSION_DEF_DEFINITION_URL));
+    }
+
+    RepositoryVersionEntity entity = createResources(new Command<RepositoryVersionEntity>() {
+      @Override
+      public RepositoryVersionEntity invoke() throws AmbariException {
+
+        String definitionUrl = (String) properties.get(VERSION_DEF_DEFINITION_URL);
+
+        RepositoryVersionEntity entity = toRepositoryVersionEntity(definitionUrl);
+
+        RepositoryVersionResourceProvider.validateRepositoryVersion(s_repoVersionDAO,
+            s_metaInfo.get(), entity);
+
+        s_repoVersionDAO.create(entity);
+
+        return entity;
+      }
+    });
+
+    notifyCreate(Resource.Type.VersionDefinition, request);
+
+    RequestStatusImpl status = new RequestStatusImpl(null,
+        Collections.singleton(toResource(entity, Collections.<String>emptySet())));
+
+    return status;
+  }
+
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    Set<Resource> results = new HashSet<Resource>();
+    Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+    if (null == predicate){
+      List<RepositoryVersionEntity> versions = s_repoVersionDAO.findAllDefinitions();
+
+      for (RepositoryVersionEntity entity : versions) {
+        results.add(toResource(entity, requestPropertyIds));
+      }
+
+    } else {
+      for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+        String id = (String) propertyMap.get(VERSION_DEF_ID);
+        if (null == id) {
+          continue;
+        }
+
+        RepositoryVersionEntity entity = s_repoVersionDAO.findByPK(Long.parseLong(id));
+        if (null != entity) {
+          results.add(toResource(entity, requestPropertyIds));
+        }
+      }
+    }
+    return results;
+  }
+
+  @Override
+  protected RequestStatus updateResourcesAuthorized(final Request request, Predicate predicate)
+    throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    throw new SystemException("Cannot update Version Definitions");
+  }
+
+  @Override
+  protected RequestStatus deleteResourcesAuthorized(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+    throw new SystemException("Cannot delete Version Definitions");
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return PK_PROPERTY_IDS;
+  }
+
+  @Override
+  protected ResourceType getResourceType(Request request, Predicate predicate) {
+    return ResourceType.AMBARI;
+  }
+
+  /**
+   * Transforms a XML version defintion to an entity
+   *
+   * @param definitionUrl the String URL for loading
+   * @return constructed entity
+   * @throws AmbariException if some properties are missing or json has incorrect structure
+   */
+  protected RepositoryVersionEntity toRepositoryVersionEntity(String definitionUrl) throws AmbariException {
+    final VersionDefinitionXml xml;
+    final String xmlString;
+    try {
+      URL url = new URL(definitionUrl);
+
+      xmlString = IOUtils.toString(url.openStream(), "UTF-8");
+
+      xml = VersionDefinitionXml.load(xmlString);
+    } catch (Exception e) {
+      String err = String.format("Could not load url from %s.  %s",
+          definitionUrl, e.getMessage());
+      throw new AmbariException(err, e);
+    }
+
+    // !!! TODO validate parsed object graph
+
+    RepositoryVersionEntity entity = new RepositoryVersionEntity();
+
+    StackId stackId = new StackId(xml.release.stackId);
+
+    StackEntity stackEntity = s_stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
+
+    entity.setStack(stackEntity);
+    entity.setOperatingSystems(s_repoVersionHelper.get().serializeOperatingSystems(
+        xml.repositoryInfo.getRepositories()));
+    entity.setVersion(xml.release.getFullVersion());
+    entity.setDisplayName(stackId, xml.release);
+    entity.setType(xml.release.repositoryType);
+    entity.setVersionUrl(definitionUrl);
+    entity.setVersionXml(xmlString);
+    entity.setVersionXsd(xml.xsdLocation);
+
+    return entity;
+  }
+
+  /**
+   * Convert the given {@link RepositoryVersionEntity} to a {@link Resource}.
+   *
+   * @param entity
+   *          the entity to convert.
+   * @param requestedIds
+   *          the properties that were requested or {@code null} for all.
+   * @return the resource representation of the entity (never {@code null}).
+   */
+  private Resource toResource(RepositoryVersionEntity entity, Set<String> requestedIds)
+      throws SystemException {
+
+    Resource resource = new ResourceImpl(Resource.Type.VersionDefinition);
+
+    resource.setProperty(VERSION_DEF_ID, entity.getId());
+
+    VersionDefinitionXml xml = null;
+    try {
+      xml = entity.getRepositoryXml();
+    } catch (Exception e) {
+      String msg = String.format("Could not load version definition %s", entity.getId());
+      throw new SystemException(msg, e);
+    }
+
+    StackId stackId = new StackId(xml.release.stackId);
+
+    // !!! these are needed for href
+    resource.setProperty(VERSION_DEF_STACK_NAME, stackId.getStackName());
+    resource.setProperty(VERSION_DEF_STACK_VERSION, stackId.getStackVersion());
+
+    setResourceProperty(resource, VERSION_DEF_TYPE_PROPERTY_ID, entity.getType(), requestedIds);
+    setResourceProperty(resource, VERSION_DEF_DEFINITION_URL, entity.getVersionUrl(), requestedIds);
+    setResourceProperty(resource, VERSION_DEF_FULL_VERSION, entity.getVersion(), requestedIds);
+    setResourceProperty(resource, VERSION_DEF_RELEASE_BUILD, xml.release.build, requestedIds);
+    setResourceProperty(resource, VERSION_DEF_RELEASE_COMPATIBLE_WITH, xml.release.compatibleWith, requestedIds);
+    setResourceProperty(resource, VERSION_DEF_RELEASE_NOTES, xml.release.releaseNotes, requestedIds);
+    setResourceProperty(resource, VERSION_DEF_RELEASE_VERSION, xml.release.version, requestedIds);
+
+      // !!! future do something with the manifest
+
+    if (isPropertyRequested(VERSION_DEF_AVAILABLE_SERVICES, requestedIds)) {
+      StackInfo stack = null;
+      try {
+        stack = s_metaInfo.get().getStack(stackId.getStackName(), stackId.getStackVersion());
+      } catch (AmbariException e) {
+        throw new SystemException(String.format("Could not load stack %s", stackId));
+      }
+
+      setResourceProperty(resource, VERSION_DEF_AVAILABLE_SERVICES, xml.getAvailableServices(stack), requestedIds);
+    }
+
+    return resource;
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/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 9d6af76..1ccabd1 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
@@ -150,7 +150,8 @@ public interface Resource {
     Credential,
     KerberosDescriptor,
     RoleAuthorization,
-    UserAuthorization;
+    UserAuthorization,
+    VersionDefinition;
 
     /**
      * Get the {@link Type} that corresponds to this InternalType.
@@ -262,6 +263,7 @@ public interface Resource {
     public static final Type KerberosDescriptor = InternalType.KerberosDescriptor.getType();
     public static final Type RoleAuthorization = InternalType.RoleAuthorization.getType();
     public static final Type UserAuthorization = InternalType.UserAuthorization.getType();
+    public static final Type VersionDefinition = InternalType.VersionDefinition.getType();
 
     /**
      * The type name.

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
index c37abb5..26f96e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
@@ -144,7 +144,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
    * @throws AmbariException
    */
   public RepositoryVersionEntity create(StackEntity stackEntity,
-      String version, String displayName, 
+      String version, String displayName,
       String operatingSystems) throws AmbariException {
       return create(stackEntity, version, displayName, operatingSystems,
           RepositoryType.STANDARD);
@@ -163,7 +163,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
    */
   @Transactional
   public RepositoryVersionEntity create(StackEntity stackEntity,
-      String version, String displayName, 
+      String version, String displayName,
       String operatingSystems, RepositoryType type) throws AmbariException {
 
     if (stackEntity == null || version == null || version.isEmpty()
@@ -196,4 +196,16 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
     this.create(newEntity);
     return newEntity;
   }
+
+  /**
+   * Retrieves repository version when they are loaded by a version definition file
+   *
+   * @return a list of entities, or an empty list when there are none
+   */
+  @RequiresSession
+  public List<RepositoryVersionEntity> findAllDefinitions() {
+    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery(
+        "repositoryVersionsFromDefinition", RepositoryVersionEntity.class);
+    return daoUtils.selectList(query);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
index e2e455b..fa2f905 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
@@ -44,6 +44,7 @@ import javax.persistence.UniqueConstraint;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.repository.Release;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
 import org.apache.commons.lang.StringUtils;
@@ -68,7 +69,8 @@ import com.google.inject.Provider;
 @NamedQueries({
     @NamedQuery(name = "repositoryVersionByDisplayName", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.displayName=:displayname"),
     @NamedQuery(name = "repositoryVersionByStack", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.stack.stackVersion=:stackVersion"),
-        @NamedQuery(name = "repositoryVersionByStackNameAndVersion", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.version=:version")
+    @NamedQuery(name = "repositoryVersionByStackNameAndVersion", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.version=:version"),
+    @NamedQuery(name = "repositoryVersionsFromDefinition", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.versionXsd IS NOT NULL")
 })
 @StaticallyInject
 public class RepositoryVersionEntity {
@@ -195,6 +197,19 @@ public class RepositoryVersionEntity {
     this.displayName = displayName;
   }
 
+  /**
+   * @param stackId the stack id for the version
+   * @param release the XML release instance
+   */
+  public void setDisplayName(StackId stackId, Release release) {
+    if (StringUtils.isNotBlank(release.display)) {
+      displayName = release.display;
+    } else {
+      displayName = stackId.getStackName() + "-" + release.getFullVersion();
+    }
+  }
+
+
   public String getOperatingSystemsJson() {
     return operatingSystems;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/java/org/apache/ambari/server/state/repository/Release.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/Release.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/Release.java
index 450fd95..6bcedf5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/Release.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/Release.java
@@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.ambari.server.state.RepositoryType;
+import org.apache.commons.lang.StringUtils;
 
 /**
  * Release information for a repository.
@@ -67,4 +68,23 @@ public class Release {
   @XmlElement(name="release-notes")
   public String releaseNotes;
 
+  /**
+   * The optional display name
+   */
+  @XmlElement(name="display")
+  public String display;
+
+  /**
+   * @return the full version
+   */
+  public String getFullVersion() {
+    StringBuilder sb = new StringBuilder(version);
+
+    if (StringUtils.isNotBlank(build)) {
+      sb.append('-').append(StringUtils.trim(build));
+    }
+
+    return sb.toString();
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/main/resources/version_definition.xsd
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/version_definition.xsd b/ambari-server/src/main/resources/version_definition.xsd
index 654ea08..2efdd77 100644
--- a/ambari-server/src/main/resources/version_definition.xsd
+++ b/ambari-server/src/main/resources/version_definition.xsd
@@ -33,6 +33,7 @@
      <xs:element name="build" type="xs:string" />
      <xs:element name="compatible-with" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="release-notes" type="xs:string" maxOccurs="1" />
+     <xs:element name="display" type="xs:string" minOccurs="0" />
     </xs:all>
   </xs:complexType>
   

http://git-wip-us.apache.org/repos/asf/ambari/blob/986a5188/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
index 12d2091..f3cf954 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.predicate.AndPredicate;
 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.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
@@ -283,12 +284,12 @@ public class RepositoryVersionResourceProviderTest {
 
     File file = new File("src/test/resources/version_definition_resource_provider.xml");
 
+    final ResourceProvider versionProvider = new VersionDefinitionResourceProvider();
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
     final Map<String, Object> properties = new LinkedHashMap<String, Object>();
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DEFINITION_URL, file.toURI().toURL().toString());
+    properties.put(VersionDefinitionResourceProvider.VERSION_DEF_DEFINITION_URL, file.toURI().toURL().toString());
     propertySet.add(properties);
 
     final Predicate predicateStackName = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).equals("HDP").toPredicate();
@@ -297,9 +298,14 @@ public class RepositoryVersionResourceProviderTest {
     Assert.assertEquals(0, provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).size());
 
     final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null);
-    provider.createResources(createRequest);
+    RequestStatus status = versionProvider.createResources(createRequest);
+    Assert.assertEquals(1, status.getAssociatedResources().size());
 
-    Set<Resource> results = provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion));
+    getRequest = PropertyHelper.getReadRequest("VersionDefinition");
+    Set<Resource> results = versionProvider.getResources(getRequest, null);
+    Assert.assertEquals(1, results.size());
+
+    results = provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion));
     Assert.assertEquals(1, results.size());
 
     getRequest = PropertyHelper.getReadRequest(
@@ -374,36 +380,37 @@ public class RepositoryVersionResourceProviderTest {
     StackEntity stackEntity = stackDAO.find("HDP", "1.1");
     Assert.assertNotNull(stackEntity);
 
-    final RepositoryVersionResourceProvider provider = (RepositoryVersionResourceProvider) injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
-
     final RepositoryVersionEntity entity = new RepositoryVersionEntity();
     entity.setDisplayName("name");
     entity.setStack(stackEntity);
     entity.setVersion("1.1");
     entity.setOperatingSystems("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]");
 
+    final RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+    AmbariMetaInfo info = injector.getInstance(AmbariMetaInfo.class);
+
     // test valid usecases
-    provider.validateRepositoryVersion(entity);
+    RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
     entity.setVersion("1.1-17");
-    provider.validateRepositoryVersion(entity);
+    RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
     entity.setVersion("1.1.1.1");
-    provider.validateRepositoryVersion(entity);
+    RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
     entity.setVersion("1.1.343432.2");
-    provider.validateRepositoryVersion(entity);
+    RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
     entity.setVersion("1.1.343432.2-234234324");
-    provider.validateRepositoryVersion(entity);
+    RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
 
     // test invalid usecases
     entity.setOperatingSystems(jsonStringRedhat7);
     try {
-      provider.validateRepositoryVersion(entity);
+      RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
       Assert.fail("Should throw exception");
     } catch (Exception ex) {
     }
 
     entity.setOperatingSystems("");
     try {
-      provider.validateRepositoryVersion(entity);
+      RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
       Assert.fail("Should throw exception");
     } catch (Exception ex) {
     }
@@ -412,12 +419,12 @@ public class RepositoryVersionResourceProviderTest {
     stackEntity.setStackName("BIGTOP");
     entity.setStack(bigtop);
     try {
-      provider.validateRepositoryVersion(entity);
+      RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity);
       Assert.fail("Should throw exception");
     } catch (Exception ex) {
     }
 
-    final RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+
     entity.setDisplayName("name");
     entity.setStack(stackEntity);
     entity.setVersion("1.1");
@@ -432,7 +439,7 @@ public class RepositoryVersionResourceProviderTest {
     entity2.setOperatingSystems("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]");
 
     try {
-      provider.validateRepositoryVersion(entity2);
+      RepositoryVersionResourceProvider.validateRepositoryVersion(repositoryVersionDAO, info, entity2);
       Assert.fail("Should throw exception: Base url http://example.com/repo1 is already defined for another repository version");
     } catch (Exception ex) {
     }