You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2014/11/13 13:00:53 UTC

ambari git commit: AMBARI-8211. Repository Version Management - Create API and BE support for update/delete repository version (yshylov via dlysnichenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk f327b0a23 -> f630f1293


AMBARI-8211. Repository Version Management - Create API and BE support for update/delete repository version (yshylov via dlysnichenko)


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

Branch: refs/heads/trunk
Commit: f630f12936e99f53cd7425c76b18f443c9d39f13
Parents: f327b0a
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Thu Nov 13 13:59:24 2014 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Thu Nov 13 14:00:11 2014 +0200

----------------------------------------------------------------------
 .../api/services/RepositoryVersionService.java  |  34 +++++
 .../RepositoryVersionResourceProvider.java      |  84 ++++++++++++-
 .../server/orm/dao/ClusterVersionDAO.java       |  66 ++--------
 .../apache/ambari/server/orm/dao/CrudDAO.java   | 126 +++++++++++++++++++
 .../server/orm/dao/RepositoryVersionDAO.java    |  65 +---------
 .../orm/entities/ClusterVersionEntity.java      |   2 +-
 .../server/upgrade/UpgradeCatalog200.java       |   8 +-
 .../services/RepositoryVersionServiceTest.java  |  36 ++++--
 .../RepositoryVersionResourceProviderTest.java  |  66 ++++++++++
 .../server/orm/dao/ClusterVersionDAOTest.java   |  11 +-
 .../ambari/server/orm/dao/CrudDAOTest.java      | 112 +++++++++++++++++
 .../orm/dao/RepositoryVersionDAOTest.java       |  56 +--------
 12 files changed, 474 insertions(+), 192 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/main/java/org/apache/ambari/server/api/services/RepositoryVersionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RepositoryVersionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RepositoryVersionService.java
index f9e8885..2c40788 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RepositoryVersionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RepositoryVersionService.java
@@ -17,8 +17,10 @@
  */
 package org.apache.ambari.server.api.services;
 
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -82,6 +84,38 @@ public class RepositoryVersionService extends BaseService {
   }
 
   /**
+   * Deletes a repository version. Handles: DELETE /repository_version/{repositoryVersionId} requests.
+   *
+   * @param headers               http headers
+   * @param ui                    uri info
+   * @param repositoryVersionId   the repository version id
+   * @return information regarding the deleted repository
+   */
+  @DELETE
+  @Path("{repositoryVersionId}")
+  @Produces("text/plain")
+  public Response deleteRepositoryVersion(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("repositoryVersionId") String repositoryVersionId) {
+    return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(repositoryVersionId));
+  }
+
+  /**
+   * Updates a specific repository version. Handles: PUT /repository_version/{repositoryVersionId} requests.
+   *
+   * @param headers               http headers
+   * @param ui                    uri info
+   * @param repositoryVersionId   the repository version id
+   * @return information regarding the updated repository
+   */
+  @PUT
+  @Path("{repositoryVersionId}")
+  @Produces("text/plain")
+  public Response updateRepositoryVersion(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("repositoryVersionId") String repositoryVersionId) {
+    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(repositoryVersionId));
+  }
+
+  /**
    * Create a repository version resource instance.
    *
    * @param repositoryVersionId repository version id

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/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 6fb1448..502a94e 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
@@ -36,7 +36,9 @@ 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.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 
 import com.google.gson.Gson;
@@ -85,6 +87,9 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   @Inject
   private RepositoryVersionDAO repositoryVersionDAO;
 
+  @Inject
+  private ClusterVersionDAO clusterVersionDAO;
+
   /**
    * Create a new resource provider.
    *
@@ -188,13 +193,88 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   @Override
   public RequestStatus updateResources(Request request, Predicate predicate)
     throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
-    throw new UnsupportedOperationException();
+    final Set<Map<String, Object>> propertyMaps = request.getProperties();
+
+    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 RepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id);
+      if (entity == null) {
+        throw new NoSuchResourceException("There is no repository version with id " + id);
+      }
+
+      if (propertyMap.get(REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID) != null
+          || propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID) != null) {
+
+        final List<ClusterVersionEntity> clusterVersionEntities =
+            clusterVersionDAO.findByStackAndVersion(entity.getStack(), entity.getVersion());
+
+        if (!clusterVersionEntities.isEmpty()) {
+          final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
+          throw new SystemException("Repository version can't be updated as it is " +
+            firstClusterVersion.getState().name() + " on cluster " + firstClusterVersion.getClusterEntity().getClusterName());
+        }
+
+        if (propertyMap.get(REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID) != null) {
+          entity.setRepositories(propertyMap.get(REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID).toString());
+        }
+
+        if (propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID) != null) {
+          entity.setUpgradePackage(propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID).toString());
+        }
+      }
+
+      if (propertyMap.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID) != null) {
+        entity.setDisplayName(propertyMap.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID).toString());
+      }
+
+      repositoryVersionDAO.merge(entity);
+    }
+
+    return getRequestStatus(null);
   }
 
   @Override
   public RequestStatus deleteResources(Predicate predicate)
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
-    throw new UnsupportedOperationException();
+    final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+
+    final List<RepositoryVersionEntity> entitiesToBeRemoved = new ArrayList<RepositoryVersionEntity>();
+    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 RepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id);
+      if (entity == null) {
+        throw new NoSuchResourceException("There is no repository version with id " + id);
+      }
+
+      final List<ClusterVersionEntity> clusterVersionEntities =
+          clusterVersionDAO.findByStackAndVersion(entity.getStack(), entity.getVersion());
+
+      if (!clusterVersionEntities.isEmpty()) {
+        final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
+        throw new SystemException("Repository version can't be deleted as it is " +
+          firstClusterVersion.getState().name() + " on cluster " + firstClusterVersion.getClusterEntity().getClusterName());
+      }
+
+      entitiesToBeRemoved.add(entity);
+    }
+
+    for (RepositoryVersionEntity entity: entitiesToBeRemoved) {
+      repositoryVersionDAO.remove(entity);
+    }
+
+    return getRequestStatus(null);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
index b39497c..e2a2e2d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -15,22 +15,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
-import org.apache.ambari.server.orm.RequiresSession;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
-import org.apache.ambari.server.state.ClusterVersionState;
+import java.util.List;
 
-import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.TypedQuery;
-import java.util.List;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.state.ClusterVersionState;
+
+import com.google.inject.Singleton;
 
 /**
  * The {@link ClusterVersionDAO} class manages the {@link ClusterVersionEntity} instances associated with a cluster.
@@ -39,21 +36,12 @@ import java.util.List;
  * stack version that is {@link ClusterVersionState#UPGRADING}.
  */
 @Singleton
-public class ClusterVersionDAO {
-  @Inject
-  Provider<EntityManager> entityManagerProvider;
-  @Inject
-  DaoUtils daoUtils;
-
+public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
   /**
-   * Get the object with the given id.
-   *
-   * @param id Primary key id
-   * @return Return the object with the given primary key
+   * Constructor.
    */
-  @RequiresSession
-  public ClusterVersionEntity findByPK(long id) {
-    return entityManagerProvider.get().find(ClusterVersionEntity.class, id);
+  public ClusterVersionDAO() {
+    super(ClusterVersionEntity.class);
   }
 
   /**
@@ -68,7 +56,7 @@ public class ClusterVersionDAO {
     final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get().createNamedQuery("clusterVersionByStackVersion", ClusterVersionEntity.class);
     query.setParameter("stack", stack);
     query.setParameter("version", version);
-    
+
     return daoUtils.selectList(query);
   }
 
@@ -136,34 +124,4 @@ public class ClusterVersionDAO {
 
     return daoUtils.selectList(query);
   }
-
-  @RequiresSession
-  public List<ClusterVersionEntity> findAll() {
-    return daoUtils.selectAll(entityManagerProvider.get(), ClusterVersionEntity.class);
-  }
-
-  @Transactional
-  public void refresh(ClusterVersionEntity clusterVersionEntity) {
-    entityManagerProvider.get().refresh(clusterVersionEntity);
-  }
-
-  @Transactional
-  public void create(ClusterVersionEntity clusterVersionEntity) {
-    entityManagerProvider.get().persist(clusterVersionEntity);
-  }
-
-  @Transactional
-  public ClusterVersionEntity merge(ClusterVersionEntity clusterVersionEntity) {
-    return entityManagerProvider.get().merge(clusterVersionEntity);
-  }
-
-  @Transactional
-  public void remove(ClusterVersionEntity clusterVersionEntity) {
-    entityManagerProvider.get().remove(merge(clusterVersionEntity));
-  }
-
-  @Transactional
-  public void removeByPK(long id) {
-    remove(findByPK(id));
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
new file mode 100644
index 0000000..4382f59
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
@@ -0,0 +1,126 @@
+/**
+ * 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.orm.dao;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.persist.Transactional;
+
+/**
+ * CRUD DAO.
+ *
+ * @param <E> entity class
+ * @param <K> primary key class
+ */
+public class CrudDAO<E, K> {
+  @Inject
+  Provider<EntityManager> entityManagerProvider;
+  @Inject
+  DaoUtils daoUtils;
+
+  private Class<E> entityClass;
+
+  /**
+   * Constructor.
+   *
+   * @param entityClass entity class
+   */
+  public CrudDAO(Class<E> entityClass) {
+    this.entityClass = entityClass;
+  }
+
+  /**
+   * Retrieves entity by primary key.
+   *
+   * @param pk primary key
+   * @return null if there is no suitable entity
+   */
+  @RequiresSession
+  public E findByPK(K pk) {
+    return entityManagerProvider.get().find(entityClass, pk);
+  }
+
+  /**
+   * Retrieves all entities.
+   *
+   * @return list of all entities
+   */
+  @RequiresSession
+  public List<E> findAll() {
+    final TypedQuery<E> query = entityManagerProvider.get().createQuery("SELECT entity FROM " + entityClass.getSimpleName() + " entity", entityClass);
+    return daoUtils.selectList(query);
+  }
+
+  /**
+   * Creates entity.
+   *
+   * @param entity entity to create
+   */
+  @Transactional
+  public void create(E entity) {
+    entityManagerProvider.get().persist(entity);
+  }
+
+  /**
+   * Updates entity.
+   *
+   * @param entity entity to update
+   * @return updated entity
+   */
+  @Transactional
+  public E merge(E entity) {
+    return entityManagerProvider.get().merge(entity);
+  }
+
+  /**
+   * Refreshes entity.
+   *
+   * @param entity entity to refresh
+   */
+  @Transactional
+  public void refresh(E entity) {
+    entityManagerProvider.get().refresh(entity);
+  }
+
+  /**
+   * Deletes entity.
+   *
+   * @param entity entity to delete
+   */
+  @Transactional
+  public void remove(E entity) {
+    entityManagerProvider.get().remove(merge(entity));
+    entityManagerProvider.get().getEntityManagerFactory().getCache().evictAll();
+  }
+
+  /**
+   * Deletes entity by PK.
+   *
+   * @param pk primary key
+   */
+  @Transactional
+  public void removeByPK(K pk) {
+    remove(findByPK(pk));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/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 f0dcb44..c9511fc 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
@@ -17,50 +17,24 @@
  */
 package org.apache.ambari.server.orm.dao;
 
-import java.util.List;
-
-import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
 import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
 
 /**
  * DAO for repository versions.
  *
  */
 @Singleton
-public class RepositoryVersionDAO {
-  @Inject
-  Provider<EntityManager> entityManagerProvider;
-  @Inject
-  DaoUtils daoUtils;
-
+public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long> {
   /**
-   * Retrieves repository version by primary key.
-   *
-   * @param repositoryVersionPK primary key
-   * @return null if there is no suitable repository version
+   * Constructor.
    */
-  @RequiresSession
-  public RepositoryVersionEntity findByPK(Long repositoryVersionPK) {
-    return entityManagerProvider.get().find(RepositoryVersionEntity.class, repositoryVersionPK);
-  }
-
-  /**
-   * Retrieves all repository versions.
-   *
-   * @return list of all repository versions
-   */
-  @RequiresSession
-  public List<RepositoryVersionEntity> findAll() {
-    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createQuery("SELECT repoversion FROM RepositoryVersionEntity repoversion", RepositoryVersionEntity.class);
-    return daoUtils.selectList(query);
+  public RepositoryVersionDAO() {
+    super(RepositoryVersionEntity.class);
   }
 
   /**
@@ -90,35 +64,4 @@ public class RepositoryVersionDAO {
     query.setParameter("version", version);
     return daoUtils.selectSingle(query);
   }
-
-  /**
-   * Create repository version.
-   *
-   * @param repositoryVersion entity to create
-   */
-  @Transactional
-  public void create(RepositoryVersionEntity repositoryVersion) {
-    entityManagerProvider.get().persist(repositoryVersion);
-  }
-
-  /**
-   * Update repository version.
-   *
-   * @param repositoryVersion entity to update
-   * @return updated repository version
-   */
-  @Transactional
-  public RepositoryVersionEntity merge(RepositoryVersionEntity repositoryVersion) {
-    return entityManagerProvider.get().merge(repositoryVersion);
-  }
-
-  /**
-   * Deletes repository version.
-   *
-   * @param repositoryVersion entity to delete
-   */
-  @Transactional
-  public void remove(RepositoryVersionEntity repositoryVersion) {
-    entityManagerProvider.get().remove(merge(repositoryVersion));
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
index a7d9ab1..aaf8eed 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
@@ -30,8 +30,8 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
-import javax.persistence.NamedQuery;
 import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
 import javax.persistence.TableGenerator;
 import javax.persistence.Table;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
index 8e14bc1..8250e83 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
@@ -106,10 +106,10 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog {
     columns.add(new DBColumnInfo("display_name",    String.class,  128,   null, false));
     columns.add(new DBColumnInfo("upgrade_package", String.class,  255,   null, false));
     columns.add(new DBColumnInfo("repositories",    char[].class,  32672, null, false));
-    dbAccessor.createTable("repoversion", columns, "repoversion_id");
-    dbAccessor.executeQuery("INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES('repoversion_id_seq', 0)", false);
-    dbAccessor.executeQuery("ALTER TABLE repoversion ADD CONSTRAINT UQ_repoversion_display_name UNIQUE (display_name)");
-    dbAccessor.executeQuery("ALTER TABLE repoversion ADD CONSTRAINT UQ_repoversion_stack_version UNIQUE (stack, version)");
+    dbAccessor.createTable("repo_version", columns, "repo_version_id");
+    dbAccessor.executeQuery("INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES('repo_version_id_seq', 0)", false);
+    dbAccessor.executeQuery("ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_display_name UNIQUE (display_name)");
+    dbAccessor.executeQuery("ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_stack_version UNIQUE (stack, version)");
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/test/java/org/apache/ambari/server/api/services/RepositoryVersionServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/RepositoryVersionServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RepositoryVersionServiceTest.java
index 94b4963..031ce85 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/RepositoryVersionServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RepositoryVersionServiceTest.java
@@ -39,27 +39,39 @@ public class RepositoryVersionServiceTest extends BaseServiceTest {
   public List<ServiceTestInvocation> getTestInvocations() throws Exception {
     List<ServiceTestInvocation> listInvocations = new ArrayList<ServiceTestInvocation>();
 
-    RepositoryVersionService RepositoryVersionService;
+    RepositoryVersionService repositoryVersionService;
     Method m;
     Object[] args;
 
     //getRepositoryVersions
-    RepositoryVersionService = new TestRepositoryVersionService();
-    m = RepositoryVersionService.getClass().getMethod("getRepositoryVersions", HttpHeaders.class, UriInfo.class);
+    repositoryVersionService = new TestRepositoryVersionService();
+    m = repositoryVersionService.getClass().getMethod("getRepositoryVersions", HttpHeaders.class, UriInfo.class);
     args = new Object[] {getHttpHeaders(), getUriInfo()};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, RepositoryVersionService, m, args, null));
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, repositoryVersionService, m, args, null));
 
     //getRepositoryVersion
-    RepositoryVersionService = new TestRepositoryVersionService();
-    m = RepositoryVersionService.getClass().getMethod("getRepositoryVersion", HttpHeaders.class, UriInfo.class, String.class);
-    args = new Object[] {getHttpHeaders(), getUriInfo(), "RepositoryVersionname"};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, RepositoryVersionService, m, args, null));
+    repositoryVersionService = new TestRepositoryVersionService();
+    m = repositoryVersionService.getClass().getMethod("getRepositoryVersion", HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "RepositoryVersionName"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, repositoryVersionService, m, args, null));
 
     //createRepositoryVersion
-    RepositoryVersionService = new TestRepositoryVersionService();
-    m = RepositoryVersionService.getClass().getMethod("createRepositoryVersion", String.class, HttpHeaders.class, UriInfo.class);
+    repositoryVersionService = new TestRepositoryVersionService();
+    m = repositoryVersionService.getClass().getMethod("createRepositoryVersion", String.class, HttpHeaders.class, UriInfo.class);
     args = new Object[] {"body", getHttpHeaders(), getUriInfo()};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.POST, RepositoryVersionService, m, args, "body"));
+    listInvocations.add(new ServiceTestInvocation(Request.Type.POST, repositoryVersionService, m, args, "body"));
+
+    //deleteRepositoryVersion
+    repositoryVersionService = new TestRepositoryVersionService();
+    m = repositoryVersionService.getClass().getMethod("deleteRepositoryVersion", HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "repositoryVersionName"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.DELETE, repositoryVersionService, m, args, null));
+
+    //updateRepositoryVersion
+    repositoryVersionService = new TestRepositoryVersionService();
+    m = repositoryVersionService.getClass().getMethod("updateRepositoryVersion", String.class, HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {"body", getHttpHeaders(), getUriInfo(), "repositoryVersionName"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.PUT, repositoryVersionService, m, args, "body"));
 
     return listInvocations;
   }
@@ -85,4 +97,4 @@ public class RepositoryVersionServiceTest extends BaseServiceTest {
       return getTestResultSerializer();
     }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/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 9dc4996..2debfd3 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
@@ -26,8 +26,10 @@ import java.util.Set;
 import junit.framework.Assert;
 
 import org.apache.ambari.server.controller.ResourceProviderFactory;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
@@ -95,6 +97,70 @@ public class RepositoryVersionResourceProviderTest {
     Assert.assertEquals(1, provider.getResources(getRequest, null).size());
   }
 
+  @Test
+  public void testDeleteResources() throws Exception {
+    final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionProvider();
+
+    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_REPOSITORIES_PROPERTY_ID, "repositories");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "stack");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "version");
+    propertySet.add(properties);
+
+    final Request getRequest = PropertyHelper.getReadRequest(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
+    Assert.assertEquals(0, provider.getResources(getRequest, null).size());
+
+    final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null);
+    provider.createResources(createRequest);
+
+    Assert.assertEquals(1, provider.getResources(getRequest, null).size());
+
+    final Predicate predicate = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID).equals("1").toPredicate();
+    provider.deleteResources(predicate);
+
+    Assert.assertEquals(0, provider.getResources(getRequest, null).size());
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionProvider();
+
+    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_REPOSITORIES_PROPERTY_ID, "repositories");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "stack");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "version");
+    propertySet.add(properties);
+
+    final Request getRequest = PropertyHelper.getReadRequest(
+        RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
+        RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID,
+        RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID);
+    Assert.assertEquals(0, provider.getResources(getRequest, null).size());
+
+    final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null);
+    provider.createResources(createRequest);
+
+    Assert.assertEquals(1, provider.getResources(getRequest, null).size());
+    Assert.assertEquals("name", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID));
+
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID, "1");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name2");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "repositories2");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade2");
+    final Request updateRequest = PropertyHelper.getUpdateRequest(properties, null);
+    provider.updateResources(updateRequest, null);
+
+    Assert.assertEquals("name2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID));
+    Assert.assertEquals("repositories2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID));
+    Assert.assertEquals("upgrade2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID));
+  }
+
   @After
   public void after() {
     injector.getInstance(PersistService.class).stop();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
index 15fcb41..42bf009 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
@@ -34,7 +34,6 @@ import org.junit.Test;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.junit.Assert;
 
-
 /**
  * ClusterVersionDAO unit tests.
  */
@@ -98,8 +97,8 @@ public class ClusterVersionDAOTest {
 
     // Switch from A to B
     if (currStep >= 3 && lastStep <= 2) {
-      cvA.setState(ClusterVersionState.CURRENT.INSTALLED);
-      cvB.setState(ClusterVersionState.CURRENT.CURRENT);
+      cvA.setState(ClusterVersionState.INSTALLED);
+      cvB.setState(ClusterVersionState.CURRENT);
       clusterVersionDAO.merge(cvA);
       clusterVersionDAO.merge(cvB);
     }
@@ -117,14 +116,14 @@ public class ClusterVersionDAOTest {
 
     // Fail upgrade for C
     if (currStep >= 5 && lastStep <= 4) {
-        cvC.setState(ClusterVersionState.CURRENT.UPGRADE_FAILED);
+        cvC.setState(ClusterVersionState.UPGRADE_FAILED);
         cvC.setEndTime(System.currentTimeMillis());
         clusterVersionDAO.merge(cvC);
     }
 
     // Retry upgrade on C
     if (currStep >= 6 && lastStep <= 5) {
-        cvC.setState(ClusterVersionState.CURRENT.UPGRADING);
+        cvC.setState(ClusterVersionState.UPGRADING);
         cvC.setEndTime(0L);
         clusterVersionDAO.merge(cvC);
     }
@@ -238,4 +237,4 @@ public class ClusterVersionDAOTest {
     injector.getInstance(PersistService.class).stop();
     injector = null;
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
new file mode 100644
index 0000000..9416b68
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.orm.dao;
+
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+/**
+ * CrudDAO unit tests.
+ * Uses repo_version table for in-memory DB tests.
+ */
+public class CrudDAOTest {
+
+  private static Injector injector;
+  private CrudDAO<RepositoryVersionEntity, Long> repositoryVersionDAO;
+  private int uniqueCounter = 0;
+  private static final long FIRST_ID = 1L;
+
+  @Before
+  public void before() {
+    injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+    injector.getInstance(GuiceJpaInitializer.class);
+  }
+
+  private void createSingleRecord() {
+    final RepositoryVersionEntity entity = new RepositoryVersionEntity();
+    entity.setDisplayName("display name" + uniqueCounter);
+    entity.setRepositories("repositories");
+    entity.setStack("stack" + uniqueCounter);
+    entity.setUpgradePackage("upgrade package");
+    entity.setVersion("version");
+    repositoryVersionDAO.create(entity);
+    uniqueCounter++;
+  }
+
+  @Test
+  public void testFindByPK() {
+    Assert.assertNull(repositoryVersionDAO.findByPK(FIRST_ID));
+    createSingleRecord();
+    Assert.assertNotNull(repositoryVersionDAO.findByPK(FIRST_ID));
+  }
+
+  @Test
+  public void testFindAll() {
+    Assert.assertEquals(0, repositoryVersionDAO.findAll().size());
+    createSingleRecord();
+    createSingleRecord();
+    Assert.assertEquals(2, repositoryVersionDAO.findAll().size());
+    repositoryVersionDAO.remove(repositoryVersionDAO.findByPK(FIRST_ID));
+    Assert.assertEquals(1, repositoryVersionDAO.findAll().size());
+  }
+
+  @Test
+  public void testCreate() {
+    createSingleRecord();
+    Assert.assertTrue(repositoryVersionDAO.findAll().size() == 1);
+    createSingleRecord();
+    Assert.assertTrue(repositoryVersionDAO.findAll().size() == 2);
+  }
+
+  @Test
+  public void testMerge() {
+    createSingleRecord();
+    RepositoryVersionEntity entity = repositoryVersionDAO.findByPK(FIRST_ID);
+    entity.setDisplayName("newname");
+    repositoryVersionDAO.merge(entity);
+    entity = repositoryVersionDAO.findByPK(FIRST_ID);
+    Assert.assertEquals("newname", entity.getDisplayName());
+  }
+
+  @Test
+  public void testRemove() {
+    createSingleRecord();
+    createSingleRecord();
+    Assert.assertEquals(2, repositoryVersionDAO.findAll().size());
+    repositoryVersionDAO.remove(repositoryVersionDAO.findByPK(FIRST_ID));
+    Assert.assertEquals(1, repositoryVersionDAO.findAll().size());
+    Assert.assertNull(repositoryVersionDAO.findByPK(1L));
+  }
+
+  @After
+  public void after() {
+    injector.getInstance(PersistService.class).stop();
+    injector = null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f630f129/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
index 7dd3fab..8fcae58 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
@@ -37,8 +37,6 @@ public class RepositoryVersionDAOTest {
 
   private static Injector injector;
   private RepositoryVersionDAO repositoryVersionDAO;
-  private int uniqueCounter = 0;
-  private static final long FIRST_ID = 1L;
 
   @Before
   public void before() {
@@ -49,72 +47,26 @@ public class RepositoryVersionDAOTest {
 
   private void createSingleRecord() {
     final RepositoryVersionEntity entity = new RepositoryVersionEntity();
-    entity.setDisplayName("display name" + uniqueCounter);
+    entity.setDisplayName("display name");
     entity.setRepositories("repositories");
-    entity.setStack("stack" + uniqueCounter);
+    entity.setStack("stack");
     entity.setUpgradePackage("upgrade package");
     entity.setVersion("version");
     repositoryVersionDAO.create(entity);
-    uniqueCounter++;
-  }
-
-  @Test
-  public void testFindByPK() {
-    Assert.assertNull(repositoryVersionDAO.findByPK(FIRST_ID));
-    createSingleRecord();
-    Assert.assertNotNull(repositoryVersionDAO.findByPK(FIRST_ID));
-  }
-
-  @Test
-  public void testFindAll() {
-    Assert.assertEquals(0, repositoryVersionDAO.findAll().size());
-    createSingleRecord();
-    createSingleRecord();
-    Assert.assertEquals(2, repositoryVersionDAO.findAll().size());
-    repositoryVersionDAO.remove(repositoryVersionDAO.findByPK(FIRST_ID));
-    Assert.assertEquals(1, repositoryVersionDAO.findAll().size());
   }
 
   @Test
   public void testFindByDisplayName() {
     createSingleRecord();
     Assert.assertNull(repositoryVersionDAO.findByDisplayName("non existing"));
-    Assert.assertNotNull(repositoryVersionDAO.findByDisplayName("display name0"));
+    Assert.assertNotNull(repositoryVersionDAO.findByDisplayName("display name"));
   }
 
   @Test
   public void testFindByStackAndVersion() {
     createSingleRecord();
     Assert.assertNull(repositoryVersionDAO.findByStackAndVersion("non existing", "non existing"));
-    Assert.assertNotNull(repositoryVersionDAO.findByStackAndVersion("stack0", "version"));
-  }
-
-  @Test
-  public void testCreate() {
-    createSingleRecord();
-    Assert.assertTrue(repositoryVersionDAO.findAll().size() == 1);
-    createSingleRecord();
-    Assert.assertTrue(repositoryVersionDAO.findAll().size() == 2);
-  }
-
-  @Test
-  public void testMerge() {
-    createSingleRecord();
-    RepositoryVersionEntity entity = repositoryVersionDAO.findByPK(FIRST_ID);
-    entity.setDisplayName("newname");
-    repositoryVersionDAO.merge(entity);
-    entity = repositoryVersionDAO.findByPK(FIRST_ID);
-    Assert.assertEquals("newname", entity.getDisplayName());
-  }
-
-  @Test
-  public void testRemove() {
-    createSingleRecord();
-    createSingleRecord();
-    Assert.assertEquals(2, repositoryVersionDAO.findAll().size());
-    repositoryVersionDAO.remove(repositoryVersionDAO.findByPK(FIRST_ID));
-    Assert.assertEquals(1, repositoryVersionDAO.findAll().size());
-    Assert.assertNull(repositoryVersionDAO.findByPK(1L));
+    Assert.assertNotNull(repositoryVersionDAO.findByStackAndVersion("stack", "version"));
   }
 
   @After