You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ni...@apache.org on 2017/05/08 21:28:01 UTC

ambari git commit: AMBARI-20936 : now properly uninstalling the zeppelin view instead of just deleting the DB entries (nitirajrathore)

Repository: ambari
Updated Branches:
  refs/heads/trunk 6bae2b607 -> 94ddad50e


AMBARI-20936 : now properly uninstalling the zeppelin view instead of just deleting the DB entries (nitirajrathore)


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

Branch: refs/heads/trunk
Commit: 94ddad50eeeba8dbbc329012cb9f80c79bcb31c9
Parents: 6bae2b6
Author: Nitiraj Singh Rathore <ni...@gmail.com>
Authored: Tue May 9 02:57:30 2017 +0530
Committer: Nitiraj Singh Rathore <ni...@gmail.com>
Committed: Tue May 9 02:57:30 2017 +0530

----------------------------------------------------------------------
 .../server/orm/entities/PrivilegeEntity.java    |  10 ++
 .../ambari/server/orm/entities/ViewEntity.java  |   9 ++
 .../server/orm/entities/ViewInstanceEntity.java |   9 ++
 .../server/upgrade/UpgradeCatalog250.java       |  28 ++++-
 .../view/ViewInstanceOperationHandler.java      |  96 +++++++++++++++++
 .../apache/ambari/server/view/ViewRegistry.java |  55 +++-------
 .../server/upgrade/UpgradeCatalog250Test.java   |   4 +-
 .../view/ViewInstanceOperationHandlerTest.java  | 105 +++++++++++++++++++
 .../ambari/server/view/ViewRegistryTest.java    |  38 ++-----
 9 files changed, 281 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrivilegeEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrivilegeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrivilegeEntity.java
index ba39efb..92a9387 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrivilegeEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrivilegeEntity.java
@@ -173,4 +173,14 @@ public class PrivilegeEntity {
   public int hashCode() {
     return Objects.hash(id, permission, resource, principal);
   }
+
+  @Override
+  public String toString() {
+    return "PrivilegeEntity{" +
+        "id=" + id +
+        ", permission=" + permission +
+        ", resource=" + resource +
+        ", principal=" + principal +
+        '}';
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
index 6ccec36..7d9e5f0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
@@ -894,4 +894,13 @@ public class ViewEntity implements ViewDefinition {
   public static String getViewName(String name, String version) {
     return name + "{" + version + "}";
   }
+
+  @Override
+  public String toString() {
+    return "ViewEntity{" +
+        "name='" + name + '\'' +
+        ", label='" + label + '\'' +
+        ", description='" + description + '\'' +
+        '}';
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
index 95ec52d..e1cdd8a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
@@ -1071,4 +1071,13 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
     }
   }
 
+  @Override
+  public String toString() {
+    return "ViewInstanceEntity{" +
+        "viewInstanceId=" + viewInstanceId +
+        ", viewName='" + viewName + '\'' +
+        ", name='" + name + '\'' +
+        ", label='" + label + '\'' +
+        '}';
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
index 36c4b24..058acb2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
@@ -46,10 +46,12 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.AlertsDAO;
 import org.apache.ambari.server.orm.dao.ArtifactDAO;
 import org.apache.ambari.server.orm.dao.DaoUtils;
+import org.apache.ambari.server.orm.dao.ViewInstanceDAO;
 import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
 import org.apache.ambari.server.orm.entities.ArtifactEntity;
+import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -62,6 +64,7 @@ import org.apache.ambari.server.state.kerberos.KerberosKeytabDescriptor;
 import org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor;
 import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
 import org.apache.ambari.server.view.ViewArchiveUtility;
+import org.apache.ambari.server.view.ViewInstanceOperationHandler;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -111,6 +114,12 @@ public class UpgradeCatalog250 extends AbstractUpgradeCatalog {
   protected static final String HOST_COMPONENT_DESIREDSTATE_INDEX = "UQ_hcdesiredstate_name";
 
   @Inject
+  ViewInstanceDAO viewInstanceDAO;
+
+  @Inject
+  ViewInstanceOperationHandler viewInstanceOperationHandler;
+
+  @Inject
   protected ViewArchiveUtility archiveUtility;
 
   /**
@@ -192,7 +201,7 @@ public class UpgradeCatalog250 extends AbstractUpgradeCatalog {
     updateKafkaConfigs();
     updateHIVEInteractiveConfigs();
     updateHiveLlapConfigs();
-    updateTablesForZeppelinViewRemoval();
+    unInstallAllZeppelinViews();
     updateZeppelinConfigs();
     updateAtlasConfigs();
     updateLogSearchConfigs();
@@ -732,10 +741,19 @@ public class UpgradeCatalog250 extends AbstractUpgradeCatalog {
     }
   }
 
-  protected void updateTablesForZeppelinViewRemoval() throws SQLException {
-    dbAccessor.executeQuery("DELETE from viewinstance WHERE view_name='ZEPPELIN{1.0.0}'", true);
-    dbAccessor.executeQuery("DELETE from viewmain WHERE view_name='ZEPPELIN{1.0.0}'", true);
-    dbAccessor.executeQuery("DELETE from viewparameter WHERE view_name='ZEPPELIN{1.0.0}'", true);
+  protected void unInstallAllZeppelinViews(){
+    LOG.info("Removing all Zeppelin views.");
+    List<ViewInstanceEntity> viewInstanceList =  viewInstanceDAO.findAll();
+    for( ViewInstanceEntity viewInstanceEntity : viewInstanceList ){
+      if(viewInstanceEntity.getViewName().equalsIgnoreCase("ZEPPELIN{1.0.0}")){
+        LOG.info("Uninstalling zeppelin view : {}", viewInstanceEntity);
+        try {
+          viewInstanceOperationHandler.uninstallViewInstance(viewInstanceEntity);
+        }catch(Exception e){
+          LOG.error("Exception occurred while uninstalling view {}. Ignored for now.", viewInstanceEntity);
+        }
+      }
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceOperationHandler.java
new file mode 100644
index 0000000..56850f7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceOperationHandler.java
@@ -0,0 +1,96 @@
+/*
+ * 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.view;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
+import org.apache.ambari.server.orm.dao.ViewDAO;
+import org.apache.ambari.server.orm.dao.ViewInstanceDAO;
+import org.apache.ambari.server.orm.entities.PrincipalEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class ViewInstanceOperationHandler {
+  private final static Logger LOG = LoggerFactory.getLogger(ViewInstanceOperationHandler.class);
+
+  @Inject
+  ViewDAO viewDAO;
+
+  /**
+   * View instance data access object.
+   */
+  @Inject
+  ViewInstanceDAO instanceDAO;
+
+  /**
+   * Privilege data access object.
+   */
+  @Inject
+  PrivilegeDAO privilegeDAO;
+
+  // remove a privilege entity.
+  private void removePrivilegeEntity(PrivilegeEntity privilegeEntity) {
+
+    PrincipalEntity principalEntity = privilegeEntity.getPrincipal();
+    if (principalEntity != null) {
+      principalEntity.removePrivilege(privilegeEntity);
+    }
+
+    privilegeDAO.remove(privilegeEntity);
+  }
+
+  public void uninstallViewInstance(ViewInstanceEntity instanceEntity) {
+    LOG.info("uninstalling ViewInstance : {} ", instanceEntity);
+    ViewEntity viewEntity = viewDAO.findByName(instanceEntity.getViewName());
+    LOG.info("viewEntity received corresponding to the view entity : {} ", viewEntity);
+
+    if (viewEntity != null) {
+      String instanceName = instanceEntity.getName();
+      String viewName = viewEntity.getCommonName();
+      String version = viewEntity.getVersion();
+
+      ViewInstanceEntity instanceDefinition = instanceDAO.findByName(instanceEntity.getViewName(), instanceEntity.getName()); //getInstanceDefinition(viewName, version, instanceName);
+      LOG.debug("view instance entity received from database : {}", instanceDefinition);
+      if (instanceDefinition != null) {
+        if (instanceDefinition.isXmlDriven()) {
+          throw new IllegalStateException("View instances defined via xml can't be deleted through api requests");
+        }
+        List<PrivilegeEntity> instancePrivileges = privilegeDAO.findByResourceId(instanceEntity.getResource().getId());
+        LOG.info("Removing privilege entities : {}", instancePrivileges);
+        for (PrivilegeEntity privilegeEntity : instancePrivileges) {
+          removePrivilegeEntity(privilegeEntity);
+        }
+        LOG.info("Deleting view instance : view name : {}, version : {}, instanceName : {}", viewName, version, instanceName);
+        instanceDAO.remove(instanceDefinition);
+      }else{
+        throw new IllegalStateException("View instance '" + instanceEntity.getName() + "' not found.");
+      }
+    }else{
+      throw new IllegalStateException("View '" + instanceEntity.getViewName() + "' not found corresponding to view instance '" + instanceEntity.getName() + "'");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
index 6d16327..0125d54 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -329,6 +329,8 @@ public class ViewRegistry {
   @Inject
   ViewURLDAO viewURLDAO;
 
+  @Inject
+  ViewInstanceOperationHandler viewInstanceOperationHandler;
   // ----- Constructors -----------------------------------------------------
 
   /**
@@ -556,6 +558,7 @@ public class ViewRegistry {
   }
 
   /**
+   * TODO : This should move to {@link ViewInstanceOperationHandler}
    * Install the given view instance with its associated view.
    *
    * @param instanceEntity the view instance entity
@@ -661,35 +664,23 @@ public class ViewRegistry {
    */
   @Transactional
   public void uninstallViewInstance(ViewInstanceEntity instanceEntity) throws IllegalStateException {
-    ViewEntity viewEntity = getDefinition(instanceEntity.getViewName());
-
-    if (viewEntity != null) {
-      String instanceName = instanceEntity.getName();
-      String viewName = viewEntity.getCommonName();
-      String version = viewEntity.getVersion();
-
-      if (getInstanceDefinition(viewName, version, instanceName) != null) {
-        if (instanceEntity.isXmlDriven()) {
-          throw new IllegalStateException("View instances defined via xml can't be deleted through api requests");
-        }
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("Deleting view instance " + viewName + "/" +
-              version + "/" + instanceName);
-        }
-        List<PrivilegeEntity> instancePrivileges = privilegeDAO.findByResourceId(instanceEntity.getResource().getId());
-        for (PrivilegeEntity privilegeEntity : instancePrivileges) {
-          removePrivilegeEntity(privilegeEntity);
-        }
-        instanceDAO.remove(instanceEntity);
-        viewEntity.removeInstanceDefinition(instanceName);
-        removeInstanceDefinition(viewEntity, instanceName);
-
-        // remove the web app context
-        handlerList.removeViewInstance(instanceEntity);
-      }
+    try {
+      viewInstanceOperationHandler.uninstallViewInstance(instanceEntity);
+      updateCaches(instanceEntity);
+    } catch (IllegalStateException illegalStateExcpetion) {
+      LOG.error("Exception occurred while uninstalling view : {}", instanceEntity, illegalStateExcpetion);
+      throw illegalStateExcpetion;
     }
   }
 
+  private void updateCaches(ViewInstanceEntity instanceEntity) {
+    ViewEntity viewEntity = getDefinition(instanceEntity.getViewName());
+    viewEntity.removeInstanceDefinition(instanceEntity.getInstanceName());
+    removeInstanceDefinition(viewEntity, instanceEntity.getInstanceName());
+    // remove the web app context
+    handlerList.removeViewInstance(instanceEntity);
+  }
+
   /**
    * Remove the data entry keyed by the given key from the given instance entity.
    *
@@ -1621,18 +1612,6 @@ public class ViewRegistry {
     }
   }
 
-  // remove a privilege entity.
-  private void removePrivilegeEntity(PrivilegeEntity privilegeEntity) {
-
-    PrincipalEntity principalEntity = privilegeEntity.getPrincipal();
-    if (principalEntity != null) {
-      principalEntity.removePrivilege(privilegeEntity);
-    }
-
-    privilegeDAO.remove(privilegeEntity);
-  }
-
-
   /**
    * Extract a view archive at the specified path
    *

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
index 5251c56..b5dc32b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
@@ -387,11 +387,11 @@ public class UpgradeCatalog250Test {
     Method updateHadoopEnvConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateHadoopEnvConfigs");
     Method updateKafkaConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateKafkaConfigs");
     Method updateHiveLlapConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateHiveLlapConfigs");
+    Method updateTablesForZeppelinViewRemoval = UpgradeCatalog250.class.getDeclaredMethod("unInstallAllZeppelinViews");
     Method updateHIVEInteractiveConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateHIVEInteractiveConfigs");
     Method addManageServiceAutoStartPermissions = UpgradeCatalog250.class.getDeclaredMethod("addManageServiceAutoStartPermissions");
     Method addManageAlertNotificationsPermissions = UpgradeCatalog250.class.getDeclaredMethod("addManageAlertNotificationsPermissions");
     Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml");
-    Method updateTablesForZeppelinViewRemoval = UpgradeCatalog250.class.getDeclaredMethod("updateTablesForZeppelinViewRemoval");
     Method updateZeppelinConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateZeppelinConfigs");
     Method updateAtlasConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateAtlasConfigs");
     Method updateLogSearchConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateLogSearchConfigs");
@@ -447,7 +447,7 @@ public class UpgradeCatalog250Test {
     upgradeCatalog250.updateHiveLlapConfigs();
     expectLastCall().once();
 
-    upgradeCatalog250.updateTablesForZeppelinViewRemoval();
+    upgradeCatalog250.unInstallAllZeppelinViews();
     expectLastCall().once();
 
     upgradeCatalog250.updateZeppelinConfigs();

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/test/java/org/apache/ambari/server/view/ViewInstanceOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewInstanceOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewInstanceOperationHandlerTest.java
new file mode 100644
index 0000000..147d7f7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewInstanceOperationHandlerTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.view;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
+import org.apache.ambari.server.orm.dao.ViewDAO;
+import org.apache.ambari.server.orm.dao.ViewInstanceDAO;
+import org.apache.ambari.server.orm.entities.PrincipalEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
+import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class ViewInstanceOperationHandlerTest {
+  @Test
+  public void uninstallViewInstance() throws Exception {
+    ViewInstanceOperationHandler viewInstanceOperationHandler = getViewInstanceOperationHandler();
+
+    ResourceEntity resourceEntity = new ResourceEntity();
+    resourceEntity.setId(3L);
+    ViewInstanceEntity instanceEntity = new ViewInstanceEntity();
+    instanceEntity.setName("VIEW_INSTANCE_NAME");
+    instanceEntity.setViewName("VIEW_NAME");
+    instanceEntity.setResource(resourceEntity);
+
+    ViewDAO viewDAO = viewInstanceOperationHandler.viewDAO;
+    ViewEntity viewEntity = EasyMock.createNiceMock(ViewEntity.class);
+    expect(viewDAO.findByName(instanceEntity.getViewName())).andReturn(viewEntity);
+    expect(viewEntity.getCommonName()).andReturn("view-common-name");
+    expect(viewEntity.getVersion()).andReturn("0.0.1");
+
+    ViewInstanceDAO viewInstanceDAO = viewInstanceOperationHandler.instanceDAO;
+    ViewInstanceEntity viewInstanceEntity = createNiceMock(ViewInstanceEntity.class);
+    expect(viewInstanceDAO.findByName(instanceEntity.getViewName(), instanceEntity.getName())).andReturn(viewInstanceEntity);
+    expect(viewInstanceEntity.isXmlDriven()).andReturn(false);
+    expect(viewInstanceEntity.isXmlDriven()).andReturn(false);
+
+    PrivilegeEntity privilege1 = createNiceMock(PrivilegeEntity.class);
+    PrivilegeEntity privilege2 = createNiceMock(PrivilegeEntity.class);
+    List<PrivilegeEntity> privileges = Arrays.asList(privilege1, privilege2);
+
+    PrivilegeDAO privilegeDAO = viewInstanceOperationHandler.privilegeDAO;
+
+    PrincipalEntity principalEntity = createNiceMock(PrincipalEntity.class);
+
+    expect(privilege1.getPrincipal()).andReturn(principalEntity);
+    expect(privilege2.getPrincipal()).andReturn(principalEntity);
+
+    principalEntity.removePrivilege(privilege1);
+    principalEntity.removePrivilege(privilege2);
+
+    expect(privilegeDAO.findByResourceId(3L)).andReturn(privileges);
+
+    privilegeDAO.remove(privilege1);
+    privilegeDAO.remove(privilege2);
+
+    viewInstanceDAO.remove(viewInstanceEntity);
+
+    replay(privilegeDAO, viewDAO, viewInstanceDAO, principalEntity, privilege1, privilege2,viewInstanceEntity, viewEntity);
+
+    viewInstanceOperationHandler.uninstallViewInstance(instanceEntity);
+
+    verify(privilegeDAO, viewDAO, viewInstanceDAO);
+  }
+
+  private ViewInstanceOperationHandler getViewInstanceOperationHandler() {
+    ViewDAO viewDAO = EasyMock.createNiceMock(ViewDAO.class);
+    ViewInstanceDAO instanceDAO = EasyMock.createNiceMock(ViewInstanceDAO.class);
+    PrivilegeDAO privilegeDAO = EasyMock.createNiceMock(PrivilegeDAO.class);
+
+    ViewInstanceOperationHandler instance = new ViewInstanceOperationHandler();
+    instance.viewDAO = viewDAO;
+    instance.instanceDAO = instanceDAO;
+    instance.privilegeDAO = privilegeDAO;
+
+    return instance;
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/94ddad50/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
index daabcb3..eda232b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
@@ -37,7 +37,6 @@ import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -212,6 +211,7 @@ public class ViewRegistryTest {
   // registry mocks
   private static final ViewDAO viewDAO = createMock(ViewDAO.class);
   private static final ViewInstanceDAO viewInstanceDAO = createNiceMock(ViewInstanceDAO.class);
+  private static final ViewInstanceOperationHandler viewInstanceOperationHandler = createNiceMock(ViewInstanceOperationHandler.class);
   private static final UserDAO userDAO = createNiceMock(UserDAO.class);
   private static final MemberDAO memberDAO = createNiceMock(MemberDAO.class);
   private static final PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class);
@@ -227,10 +227,10 @@ public class ViewRegistryTest {
 
   @Before
   public void resetGlobalMocks() {
-    ViewRegistry.initInstance(getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO,
+    ViewRegistry.initInstance(getRegistry(viewInstanceOperationHandler, viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO,
         permissionDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, ambariMetaInfo, clusters));
 
-    reset(viewDAO, resourceDAO, viewInstanceDAO, userDAO, memberDAO,
+    reset(viewInstanceOperationHandler, viewDAO, resourceDAO, viewInstanceDAO, userDAO, memberDAO,
         privilegeDAO, resourceTypeDAO, securityHelper, configuration, handlerList, ambariMetaInfo,
         clusters);
   }
@@ -448,7 +448,7 @@ public class ViewRegistryTest {
     TestViewArchiveUtility archiveUtility =
         new TestViewArchiveUtility(viewConfigs, files, outputStreams, jarFiles, badArchive);
 
-    ViewRegistry registry = getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, permissionDAO,
+    ViewRegistry registry = getRegistry(viewInstanceOperationHandler, viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, permissionDAO,
         resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, archiveUtility, ambariMetaInfo, clusters);
 
     registry.readViewArchives();
@@ -1122,29 +1122,10 @@ public class ViewRegistryTest {
     ViewConfig config = ViewConfigTest.getConfig(XML_VALID_INSTANCE);
     ViewEntity viewEntity = getViewEntity(config, ambariConfig, getClass().getClassLoader(), "");
     ViewInstanceEntity viewInstanceEntity = getViewInstanceEntity(viewEntity, config.getInstances().get(0));
-    ResourceEntity resource = new ResourceEntity();
-    resource.setId(3L);
-    viewInstanceEntity.setResource(resource);
-    PrivilegeEntity privilege1 = createNiceMock(PrivilegeEntity.class);
-    PrivilegeEntity privilege2 = createNiceMock(PrivilegeEntity.class);
-    List<PrivilegeEntity> privileges = Arrays.asList(privilege1, privilege2);
-
-    PrincipalEntity principalEntity = createNiceMock(PrincipalEntity.class);
-
-    expect(privilege1.getPrincipal()).andReturn(principalEntity);
-    expect(privilege2.getPrincipal()).andReturn(principalEntity);
-
-    principalEntity.removePrivilege(privilege1);
-    principalEntity.removePrivilege(privilege2);
-
-    expect(privilegeDAO.findByResourceId(3L)).andReturn(privileges);
-    privilegeDAO.remove(privilege1);
-    privilegeDAO.remove(privilege2);
-    viewInstanceDAO.remove(viewInstanceEntity);
 
+    viewInstanceOperationHandler.uninstallViewInstance(viewInstanceEntity);
     handlerList.removeViewInstance(viewInstanceEntity);
-
-    replay(viewInstanceDAO, privilegeDAO, handlerList, privilege1, privilege2, principalEntity);
+    replay(viewInstanceOperationHandler,/* viewInstanceDAO, privilegeDAO,*/ handlerList/*, privilege1, privilege2, principalEntity*/);
 
     registry.addDefinition(viewEntity);
     registry.addInstanceDefinition(viewEntity, viewInstanceEntity);
@@ -1154,7 +1135,7 @@ public class ViewRegistryTest {
 
     Assert.assertEquals(0, viewInstanceDefinitions.size());
 
-    verify(viewInstanceDAO, privilegeDAO, handlerList, privilege1, privilege2, principalEntity);
+    verify(viewInstanceOperationHandler, /*viewInstanceDAO, privilegeDAO,*/ handlerList/*, privilege1, privilege2, principalEntity*/);
   }
 
   @Test
@@ -1809,12 +1790,12 @@ public class ViewRegistryTest {
                                          ViewExtractor viewExtractor,
                                          ViewArchiveUtility archiveUtility,
                                          AmbariMetaInfo ambariMetaInfo) {
-    return getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, permissionDAO,
+    return getRegistry(null, viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, permissionDAO,
         resourceDAO, resourceTypeDAO, securityHelper, handlerList, viewExtractor, archiveUtility,
         ambariMetaInfo, null);
   }
 
-  public static ViewRegistry getRegistry(ViewDAO viewDAO, ViewInstanceDAO viewInstanceDAO,
+  public static ViewRegistry getRegistry(ViewInstanceOperationHandler viewInstanceOperationHandler, ViewDAO viewDAO, ViewInstanceDAO viewInstanceDAO,
                                          UserDAO userDAO, MemberDAO memberDAO,
                                          PrivilegeDAO privilegeDAO, PermissionDAO permissionDAO,
                                          ResourceDAO resourceDAO, ResourceTypeDAO resourceTypeDAO,
@@ -1833,6 +1814,7 @@ public class ViewRegistryTest {
 
     ViewRegistry instance = new ViewRegistry(publisher);
 
+    instance.viewInstanceOperationHandler = viewInstanceOperationHandler;
     instance.viewDAO = viewDAO;
     instance.resourceDAO = resourceDAO;
     instance.instanceDAO = viewInstanceDAO;