This is an automated email from the ASF dual-hosted git repository.

krisztiankasa pushed a commit to branch branch-2.6
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-2.6 by this push:
     new a072610  AMBARI-24283 - DB consistency warning due to config group 
without service name (#1876)
a072610 is described below

commit a07261021bd3001cd33748c2203c2479b9df8c32
Author: kasakrisz <33458261+kasakr...@users.noreply.github.com>
AuthorDate: Fri Jul 27 14:26:51 2018 +0200

    AMBARI-24283 - DB consistency warning due to config group without service 
name (#1876)
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - output message
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - doc
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - out message fix
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - check service name is valid
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - check service name is valid by service map
    
    * AMBARI-24283 - DB consistency warning due to config group without service 
name - do not delete config groups without service name
---
 .../checks/DatabaseConsistencyCheckHelper.java     | 109 ++++++++++++++---
 .../checks/DatabaseConsistencyCheckHelperTest.java | 130 +++++++++++++++++++--
 2 files changed, 218 insertions(+), 21 deletions(-)

diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
index 1f94bae..fac79ac 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
@@ -51,7 +51,6 @@ import 
org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.MetainfoEntity;
@@ -60,8 +59,6 @@ import 
org.apache.ambari.server.state.ClientConfigFileDefinition;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.Service;
@@ -185,6 +182,7 @@ public class DatabaseConsistencyCheckHelper {
       if (fixIssues) {
         fixHostComponentStatesCountEqualsHostComponentsDesiredStates();
         fixClusterConfigsNotMappedToAnyService();
+        fixConfigGroupServiceNames();
         fixConfigGroupHostMappings();
         fixConfigGroupsForDeletedServices();
         fixConfigsSelectedMoreThanOnce();
@@ -198,6 +196,7 @@ public class DatabaseConsistencyCheckHelper {
       checkServiceConfigs();
       checkTopologyTables();
       checkForLargeTables();
+      checkConfigGroupsHasServiceName();
       checkConfigGroupHostMapping(true);
       checkConfigGroupsForDeletedServices(true);
       LOG.info("******************************* Check database completed 
*******************************");
@@ -1191,6 +1190,82 @@ public class DatabaseConsistencyCheckHelper {
   }
 
   /**
+   * This method collects the ConfigGroups with empty or null service name 
field
+   */
+  static Map<Long, ConfigGroup> collectConfigGroupsWithoutServiceName() {
+    Map<Long, ConfigGroup> configGroupMap = new HashMap<>();
+    Clusters clusters = injector.getInstance(Clusters.class);
+    Map<String, Cluster> clusterMap = clusters.getClusters();
+
+    if (MapUtils.isEmpty(clusterMap))
+      return configGroupMap;
+
+    for (Cluster cluster : clusterMap.values()) {
+      Map<Long, ConfigGroup> configGroups = cluster.getConfigGroups();
+
+      if (MapUtils.isEmpty(configGroups))
+        continue;
+
+      for (ConfigGroup configGroup : configGroups.values()) {
+        if (StringUtils.isEmpty(configGroup.getServiceName())) {
+          configGroupMap.put(configGroup.getId(), configGroup);
+        }
+      }
+    }
+
+    return configGroupMap;
+  }
+
+  /**
+   * This method checks if there are any ConfigGroup with empty or null 
service name field
+   */
+  static void checkConfigGroupsHasServiceName() {
+    Map<Long, ConfigGroup> configGroupMap = 
collectConfigGroupsWithoutServiceName();
+    if (MapUtils.isEmpty(configGroupMap))
+      return;
+
+    StringBuilder output = new StringBuilder("[(ConfigGroup) => ");
+
+    for (ConfigGroup configGroup : configGroupMap.values()) {
+      output.append("( ");
+      output.append(configGroup.getName());
+      output.append(" ), ");
+    }
+
+    output.replace(output.lastIndexOf(","), output.length(), "]");
+    warning("You have config groups present in the database with no " +
+            "service name, {}. Run --auto-fix-database to fix " +
+            "this automatically. Please backup Ambari Server database before 
running --auto-fix-database.", output.toString());
+  }
+
+  /**
+   * Fix inconsistencies found by @collectConfigGroupsWithoutServiceName
+   */
+  @Transactional
+  static void fixConfigGroupServiceNames() {
+    Map<Long, ConfigGroup> configGroupMap = 
collectConfigGroupsWithoutServiceName();
+    if (MapUtils.isEmpty(configGroupMap))
+      return;
+
+    Clusters clusters = injector.getInstance(Clusters.class);
+
+    for (Map.Entry<Long, ConfigGroup> configGroupEntry : 
configGroupMap.entrySet()) {
+      ConfigGroup configGroup = configGroupEntry.getValue();
+      try {
+        Cluster cluster = clusters.getCluster(configGroup.getClusterName());
+        Map<String, Service> serviceMap = cluster.getServices();
+        if (serviceMap.containsKey(configGroup.getTag())) {
+          LOG.info("Setting service name of config group {} with id {} to {}",
+                  configGroup.getName(), configGroupEntry.getKey(), 
configGroup.getTag());
+          configGroup.setServiceName(configGroup.getTag());
+        }
+      } catch (AmbariException e) {
+        // Ignore if cluster not found
+      }
+    }
+  }
+
+  /**
    * This method checks if there are any ConfigGroup host mappings with hosts
    * that are not longer a part of the cluster.
    */
@@ -1253,7 +1328,7 @@ public class DatabaseConsistencyCheckHelper {
       warning("You have config group host mappings with hosts that are no " +
         "longer associated with the cluster, {}. Run --auto-fix-database to " +
         "fix this automatically. Alternatively, you can remove this mapping " +
-        "from the UI.", output.toString());
+        "from the UI. Please backup Ambari Server database before running 
--auto-fix-database.", output.toString());
     }
 
     return nonMappedHostIds;
@@ -1289,7 +1364,7 @@ public class DatabaseConsistencyCheckHelper {
       output.replace(output.lastIndexOf(","), output.length(), "]");
       warning("You have config groups present in the database with no " +
         "corresponding service found, {}. Run --auto-fix-database to fix " +
-          "this automatically.", output.toString());
+          "this automatically. Please backup Ambari Server database before 
running --auto-fix-database.", output.toString());
     }
 
     return configGroupMap;
@@ -1304,15 +1379,21 @@ public class DatabaseConsistencyCheckHelper {
       for (Map.Entry<Long, ConfigGroup> configGroupEntry : 
configGroupMap.entrySet()) {
         Long id = configGroupEntry.getKey();
         ConfigGroup configGroup = configGroupEntry.getValue();
-        LOG.info("Deleting config group {} with id {} for deleted service {}",
-          configGroup.getName(), id, configGroup.getServiceName());
-        try {
-          Cluster cluster = clusters.getCluster(configGroup.getClusterName());
-          cluster.deleteConfigGroup(id);
-        } catch (AuthorizationException e) {
-          // This call does not thrown Authorization Exception
-        } catch (AmbariException e) {
-          // Ignore if cluster not found
+        if (!StringUtils.isEmpty(configGroup.getServiceName())) {
+          LOG.info("Deleting config group {} with id {} for deleted service 
{}",
+                  configGroup.getName(), id, configGroup.getServiceName());
+          try {
+            Cluster cluster = 
clusters.getCluster(configGroup.getClusterName());
+            cluster.deleteConfigGroup(id);
+          } catch (AuthorizationException e) {
+            // This call does not thrown Authorization Exception
+          } catch (AmbariException e) {
+            // Ignore if cluster not found
+          }
+        }
+        else {
+          warning("The config group {} with id {} can not be fixed 
automatically because service name is missing.",
+                  configGroup.getName(), id);
         }
       }
     }
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
index 23dd1e6..73c4aac 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
@@ -713,23 +713,26 @@ public class DatabaseConsistencyCheckHelperTest {
     });
 
     Map<String, Cluster> clusters = new HashMap<>();
-    Cluster cluster = easyMockSupport.createNiceMock(Cluster.class);
+    Cluster cluster = easyMockSupport.createStrictMock(Cluster.class);
     clusters.put("c1", cluster);
     expect(mockClusters.getClusters()).andReturn(clusters).anyTimes();
 
     Map<Long, ConfigGroup> configGroupMap = new HashMap<>();
     ConfigGroup cg1 = easyMockSupport.createNiceMock(ConfigGroup.class);
     ConfigGroup cg2 = easyMockSupport.createNiceMock(ConfigGroup.class);
+    ConfigGroup cgWithoutServiceName = 
easyMockSupport.createNiceMock(ConfigGroup.class);
     configGroupMap.put(1L, cg1);
     configGroupMap.put(2L, cg2);
+    configGroupMap.put(3L, cgWithoutServiceName);
 
-    expect(cluster.getConfigGroups()).andReturn(configGroupMap).anyTimes();
+    expect(cluster.getConfigGroups()).andStubReturn(configGroupMap);
     expect(cg1.getName()).andReturn("cg1").anyTimes();
     expect(cg1.getId()).andReturn(1L).anyTimes();
     expect(cg1.getServiceName()).andReturn("YARN").anyTimes();
     expect(cg2.getServiceName()).andReturn("HDFS").anyTimes();
-
-    expect(cluster.getClusterName()).andReturn("c1").anyTimes();
+    expect(cgWithoutServiceName.getName()).andReturn("cg3").anyTimes();
+    expect(cgWithoutServiceName.getId()).andReturn(3L).anyTimes();
+    expect(cgWithoutServiceName.getServiceName()).andReturn(null).anyTimes();
 
     Service service = easyMockSupport.createNiceMock(Service.class);
     Map<String, Service> services = new HashMap<>();
@@ -737,7 +740,7 @@ public class DatabaseConsistencyCheckHelperTest {
     expect(cluster.getServices()).andReturn(services).anyTimes();
 
     expect(cg1.getClusterName()).andReturn("c1");
-    expect(mockClusters.getCluster("c1")).andReturn(cluster);
+    expect(mockClusters.getCluster("c1")).andReturn(cluster).anyTimes();
     cluster.deleteConfigGroup(1L);
     expectLastCall();
 
@@ -751,8 +754,121 @@ public class DatabaseConsistencyCheckHelperTest {
     easyMockSupport.verifyAll();
 
     Assert.assertFalse(MapUtils.isEmpty(configGroups));
-    Assert.assertEquals(1, configGroups.size());
-    Assert.assertEquals(1L, 
configGroups.values().iterator().next().getId().longValue());
+    Assert.assertEquals(2, configGroups.size());
+    Assert.assertTrue(configGroups.containsKey(1L));
+    Assert.assertFalse(configGroups.containsKey(2L));
+    Assert.assertTrue(configGroups.containsKey(3L));
+  }
+
+  @Test
+  public void testCollectConfigGroupsWithoutServiceName() throws Exception {
+    EasyMockSupport easyMockSupport = new EasyMockSupport();
+
+    final DBAccessor mockDBDbAccessor = 
easyMockSupport.createNiceMock(DBAccessor.class);
+
+    final StackManagerFactory mockStackManagerFactory = 
easyMockSupport.createNiceMock(StackManagerFactory.class);
+    final EntityManager mockEntityManager = 
easyMockSupport.createNiceMock(EntityManager.class);
+    final Clusters mockClusters = 
easyMockSupport.createNiceMock(Clusters.class);
+    final OsFamily mockOSFamily = 
easyMockSupport.createNiceMock(OsFamily.class);
+    final Injector mockInjector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(StackManagerFactory.class).toInstance(mockStackManagerFactory);
+        bind(EntityManager.class).toInstance(mockEntityManager);
+        bind(DBAccessor.class).toInstance(mockDBDbAccessor);
+        bind(Clusters.class).toInstance(mockClusters);
+        bind(OsFamily.class).toInstance(mockOSFamily);
+      }
+    });
+
+    Map<String, Cluster> clusters = new HashMap<>();
+    Cluster cluster1 = easyMockSupport.createNiceMock(Cluster.class);
+    clusters.put("c1", cluster1);
+    Cluster cluster2 = easyMockSupport.createNiceMock(Cluster.class);
+    clusters.put("c2", cluster2);
+    expect(cluster2.getConfigGroups()).andReturn(new HashMap<Long, 
ConfigGroup>(0)).anyTimes();
+    expect(mockClusters.getClusters()).andReturn(clusters).anyTimes();
+    expect(mockClusters.getCluster("c1")).andReturn(cluster1).anyTimes();
+    expect(mockClusters.getCluster("c2")).andReturn(cluster2).anyTimes();
+
+    Map<Long, ConfigGroup> configGroupMap = new HashMap<>();
+    ConfigGroup cgWithoutServiceName = 
easyMockSupport.createNiceMock(ConfigGroup.class);
+    ConfigGroup cgWithServiceName = 
easyMockSupport.createNiceMock(ConfigGroup.class);
+    ConfigGroup cgForNonExistentService = 
easyMockSupport.createNiceMock(ConfigGroup.class);
+    configGroupMap.put(1L, cgWithoutServiceName);
+    configGroupMap.put(2L, cgWithServiceName);
+    configGroupMap.put(3L, cgForNonExistentService);
+
+    expect(cluster1.getConfigGroups()).andReturn(configGroupMap).anyTimes();
+    expect(cgWithoutServiceName.getId()).andReturn(1L).anyTimes();
+    expect(cgWithoutServiceName.getClusterName()).andReturn("c1").anyTimes();
+    expect(cgWithoutServiceName.getServiceName()).andReturn(null).anyTimes();
+    expect(cgWithoutServiceName.getTag()).andReturn("YARN").anyTimes();
+    cgWithoutServiceName.setServiceName("YARN"); expectLastCall();
+    expect(cgWithServiceName.getId()).andReturn(2L).anyTimes();
+    expect(cgWithServiceName.getClusterName()).andReturn("c1").anyTimes();
+    expect(cgWithServiceName.getServiceName()).andReturn("HDFS").anyTimes();
+    expect(cgForNonExistentService.getId()).andReturn(3L).anyTimes();
+    
expect(cgForNonExistentService.getClusterName()).andReturn("c1").anyTimes();
+    
expect(cgForNonExistentService.getServiceName()).andReturn(null).anyTimes();
+    
expect(cgForNonExistentService.getTag()).andReturn("NOT_EXISTS").anyTimes();
+
+    Service hdfsService = easyMockSupport.createNiceMock(Service.class);
+    Service yarnService = easyMockSupport.createNiceMock(Service.class);
+    Map<String, Service> services = new HashMap<>();
+    services.put("HDFS", hdfsService);
+    services.put("YARN", yarnService);
+    expect(cluster1.getServices()).andReturn(services).anyTimes();
+
+    DatabaseConsistencyCheckHelper.setInjector(mockInjector);
+
+    easyMockSupport.replayAll();
+
+    Map<Long, ConfigGroup> configGroups = 
DatabaseConsistencyCheckHelper.collectConfigGroupsWithoutServiceName();
+    DatabaseConsistencyCheckHelper.fixConfigGroupServiceNames();
+
+    easyMockSupport.verifyAll();
+
+    Assert.assertFalse(MapUtils.isEmpty(configGroups));
+    Assert.assertEquals(2, configGroups.size());
+    Assert.assertTrue(configGroups.containsKey(1L));
+    Assert.assertFalse(configGroups.containsKey(2L));
+    Assert.assertTrue(configGroups.containsKey(3L));
+  }
+
+  @Test
+  public void 
testCollectConfigGroupsWithoutServiceNameReturnsEmptyMapWhenNoClusters() throws 
Exception {
+    EasyMockSupport easyMockSupport = new EasyMockSupport();
+
+    final DBAccessor mockDBDbAccessor = 
easyMockSupport.createNiceMock(DBAccessor.class);
+
+    final StackManagerFactory mockStackManagerFactory = 
easyMockSupport.createNiceMock(StackManagerFactory.class);
+    final EntityManager mockEntityManager = 
easyMockSupport.createNiceMock(EntityManager.class);
+    final Clusters mockClusters = 
easyMockSupport.createNiceMock(Clusters.class);
+    final OsFamily mockOSFamily = 
easyMockSupport.createNiceMock(OsFamily.class);
+    final Injector mockInjector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(StackManagerFactory.class).toInstance(mockStackManagerFactory);
+        bind(EntityManager.class).toInstance(mockEntityManager);
+        bind(DBAccessor.class).toInstance(mockDBDbAccessor);
+        bind(Clusters.class).toInstance(mockClusters);
+        bind(OsFamily.class).toInstance(mockOSFamily);
+      }
+    });
+
+    Map<String, Cluster> clusters = new HashMap<>();
+    expect(mockClusters.getClusters()).andReturn(clusters).anyTimes();
+
+    DatabaseConsistencyCheckHelper.setInjector(mockInjector);
+
+    easyMockSupport.replayAll();
+
+    Map<Long, ConfigGroup> configGroups = 
DatabaseConsistencyCheckHelper.collectConfigGroupsWithoutServiceName();
+
+    easyMockSupport.verifyAll();
+
+    Assert.assertTrue(MapUtils.isEmpty(configGroups));
   }
 
   @Test

Reply via email to