ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smoha...@apache.org
Subject ambari git commit: AMBARI-13741. API call to delete service fails with error: integrity constraint violated - child record found (Sebastian Toader via smohanty)
Date Sat, 07 Nov 2015 14:53:35 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 473022225 -> 341aeafea


AMBARI-13741. API call to delete service fails with error: integrity constraint violated -
child record found (Sebastian Toader via smohanty)


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

Branch: refs/heads/branch-2.1
Commit: 341aeafea123b78557c88207328f761113001188
Parents: 4730222
Author: Sumit Mohanty <smohanty@hortonworks.com>
Authored: Sat Nov 7 06:51:07 2015 -0800
Committer: Sumit Mohanty <smohanty@hortonworks.com>
Committed: Sat Nov 7 06:53:26 2015 -0800

----------------------------------------------------------------------
 .../orm/entities/ClusterServiceEntity.java      |   2 +-
 .../ServiceComponentDesiredStateEntity.java     |   4 +-
 .../server/state/cluster/ClusterImpl.java       |  35 +++++-
 .../svccomphost/ServiceComponentHostImpl.java   |   6 ++
 .../server/state/cluster/ClusterImplTest.java   | 106 ++++++++++++++++++-
 5 files changed, 144 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/341aeafe/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
index d34e2d5..eade294 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
@@ -52,7 +52,7 @@ public class ClusterServiceEntity {
   @OneToOne(mappedBy = "clusterServiceEntity", cascade = CascadeType.ALL)
   private ServiceDesiredStateEntity serviceDesiredStateEntity;
 
-  @OneToMany(mappedBy = "clusterServiceEntity")
+  @OneToMany(mappedBy = "clusterServiceEntity", cascade = CascadeType.ALL)
   private Collection<ServiceComponentDesiredStateEntity> serviceComponentDesiredStateEntities;
 
   public Long getClusterId() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/341aeafe/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
index 4195710..c39ecc4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
@@ -66,10 +66,10 @@ public class ServiceComponentDesiredStateEntity {
   @JoinColumns({@javax.persistence.JoinColumn(name = "cluster_id", referencedColumnName =
"cluster_id", nullable = false), @JoinColumn(name = "service_name", referencedColumnName =
"service_name", nullable = false)})
   private ClusterServiceEntity clusterServiceEntity;
 
-  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.PERSIST)
+  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.ALL)
   private Collection<HostComponentStateEntity> hostComponentStateEntities;
 
-  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity")
+  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.ALL)
   private Collection<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities;
 
   public Long getClusterId() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/341aeafe/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 63c62a9..e4605d3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -37,6 +37,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javax.persistence.RollbackException;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ConfigGroupNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -1919,9 +1921,8 @@ public class ClusterImpl implements Cluster {
       }
 
       for (Service service : services.values()) {
-        service.delete();
+        deleteService(service);
       }
-
       services.clear();
     } finally {
       clusterGlobalLock.writeLock().unlock();
@@ -1943,13 +1944,41 @@ public class ClusterImpl implements Cluster {
           + ", clusterName=" + getClusterName()
           + ", serviceName=" + service.getName());
       }
-      service.delete();
+      deleteService(service);
       services.remove(serviceName);
+
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }
   }
 
+  /**
+   * Deletes the specified service also removes references to it from {@link this.serviceComponentHosts}
+   * and references to ServiceComponentHost objects that belong to the service from {@link
this.serviceComponentHostsByHost}
+   * <p>
+   *   Note: This method must be called only with write lock acquired.
+   * </p>
+   * @param service the service to be deleted
+   * @throws AmbariException
+   * @see   ServiceComponentHost
+   */
+  private void deleteService(Service service) throws AmbariException {
+    final String serviceName = service.getName();
+
+    service.delete();
+
+    serviceComponentHosts.remove(serviceName);
+
+    for (List<ServiceComponentHost> serviceComponents: serviceComponentHostsByHost.values()){
+      Iterables.removeIf(serviceComponents, new Predicate<ServiceComponentHost>() {
+        @Override
+        public boolean apply(ServiceComponentHost serviceComponentHost) {
+          return serviceComponentHost.getServiceName().equals(serviceName);
+        }
+      });
+    }
+  }
+
   @Override
   public boolean canBeRemoved() {
     loadServices();

http://git-wip-us.apache.org/repos/asf/ambari/blob/341aeafe/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index c0804ff..7b1c6ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1373,6 +1373,12 @@ public class ServiceComponentHostImpl implements ServiceComponentHost
{
       try {
         if (persisted) {
           removeEntities();
+
+          // host must be re-loaded from db to refresh the cached JPA HostEntity
+          // that references HostComponentDesiredStateEntity
+          // and HostComponentStateEntity JPA entities
+          host.refresh();
+
           persisted = false;
           fireRemovalEvent = true;
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/341aeafe/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterImplTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterImplTest.java
index 39431ed..178adc5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterImplTest.java
@@ -18,19 +18,52 @@
 
 package org.apache.ambari.server.state.cluster;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 import org.apache.ambari.server.controller.AmbariSessionManager;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.StackId;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.verify;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class ClusterImplTest {
 
+  private static Injector injector;
+  private static Clusters clusters;
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    Injector injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    injector.getInstance(GuiceJpaInitializer.class);
+    clusters = injector.getInstance(Clusters.class);
+  }
+  
   @Test
   public void testAddSessionAttributes() throws Exception {
     Map<String, Object> attributes = new HashMap<String, Object>();
@@ -156,4 +189,71 @@ public class ClusterImplTest {
 
     verify(sessionManager, cluster);
   }
+
+  @Test
+  public void testDeleteService() throws Exception {
+    // Given
+    String serviceToDelete = "TEZ";
+
+    String clusterName = "TEST_CLUSTER";
+    String hostName1 = "HOST1", hostName2 = "HOST2";
+
+    clusters.addCluster(clusterName, new StackId("HDP-2.1.1"));
+
+    Cluster cluster = clusters.getCluster(clusterName);
+
+    clusters.addHost(hostName1);
+    clusters.addHost(hostName2);
+
+    Host host1 = clusters.getHost(hostName1);
+    host1.setHostAttributes(ImmutableMap.of("os_family", "centos", "os_release_version",
"6.0"));
+    host1.persist();
+
+    Host host2 = clusters.getHost(hostName2);
+    host2.setHostAttributes(ImmutableMap.of("os_family", "centos", "os_release_version",
"6.0"));
+    host2.persist();
+
+    clusters.mapHostsToCluster(Sets.newHashSet(hostName1, hostName2), clusterName);
+
+    Service hdfs = cluster.addService("HDFS");
+    hdfs.persist();
+
+    ServiceComponent nameNode = hdfs.addServiceComponent("NAMENODE");
+    nameNode.persist();
+    nameNode.addServiceComponentHost(hostName1).persist();
+
+    ServiceComponent dataNode = hdfs.addServiceComponent("DATANODE");
+    dataNode.persist();
+    dataNode.addServiceComponentHost(hostName1).persist();
+    dataNode.addServiceComponentHost(hostName2).persist();
+
+    ServiceComponent hdfsClient = hdfs.addServiceComponent("HDFS_CLIENT");
+    hdfsClient.persist();
+    hdfsClient.addServiceComponentHost(hostName1).persist();
+    hdfsClient.addServiceComponentHost(hostName2).persist();
+
+    Service tez = cluster.addService(serviceToDelete);
+    tez.persist();
+
+    ServiceComponent tezClient = tez.addServiceComponent("TEZ_CLIENT");
+    tezClient.persist();
+    ServiceComponentHost tezClientHost1 =  tezClient.addServiceComponentHost(hostName1);
+    tezClientHost1.persist();
+    ServiceComponentHost tezClientHost2 = tezClient.addServiceComponentHost(hostName2);
+    tezClientHost2.persist();
+
+    // When
+    cluster.deleteService(serviceToDelete);
+
+    // Then
+    assertFalse("Deleted service should be removed from the service collection !", cluster.getServices().containsKey(serviceToDelete));
+
+    assertEquals("All components of the deleted service should be removed from all hosts",
0, cluster.getServiceComponentHosts(serviceToDelete, null).size());
+
+    boolean checkHost1 = !cluster.getServiceComponentHosts(hostName1).contains(tezClientHost1);
+    boolean checkHost2 = !cluster.getServiceComponentHosts(hostName2).contains(tezClientHost2);
+
+    assertTrue("All components of the deleted service should be removed from all hosts",
checkHost1 && checkHost2);
+
+  }
 }
\ No newline at end of file


Mime
View raw message