You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by kr...@apache.org on 2018/07/27 12:26:54 UTC
[ambari] branch branch-2.6 updated: AMBARI-24283 - DB consistency
warning due to config group without service name (#1876)
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 <33...@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