AMBARI-22419 Ambari upgrade failed (dgrinenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d6f26fb1 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d6f26fb1 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d6f26fb1 Branch: refs/heads/branch-feature-AMBARI-20859 Commit: d6f26fb1c7d79fa6ba9a289daf51f6151c6bb3de Parents: 72812bd Author: Dmytro Grinenko <[email protected]> Authored: Fri Jan 5 10:01:16 2018 +0200 Committer: Dmytro Grinenko <[email protected]> Committed: Fri Jan 5 10:01:16 2018 +0200 ---------------------------------------------------------------------- .../server/api/services/AmbariMetaInfo.java | 80 +++++++++----------- .../server/api/services/AmbariMetaInfoTest.java | 53 +++++++++++++ 2 files changed, 89 insertions(+), 44 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d6f26fb1/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java index 5f63c76..af0b700 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java @@ -1035,6 +1035,30 @@ public class AmbariMetaInfo { } /** + * Returns new definitions for the merge + * + * @param definitions List of the definitions + * @param clusterId Cluster ID + * @param mappedEntities Mapped entities + * @return Entities to merge + */ + private List<AlertDefinitionEntity> getDefinitionsForMerge(List<AlertDefinition> definitions, long clusterId, + Map<String, AlertDefinitionEntity> mappedEntities ) { + List<AlertDefinitionEntity> definitionsForMerge = new ArrayList<>(); + + for (AlertDefinition definition: definitions) { + AlertDefinitionEntity entity = mappedEntities.get(definition.getName()); + + // no entity means this is new; create a new entity + if (null == entity) { + entity = alertDefinitionFactory.coerce(clusterId, definition); + definitionsForMerge.add(entity); + } + } + return definitionsForMerge; + } + + /** * Compares the alert definitions defined on the stack with those in the * database and merges any new or updated definitions. This method will first * determine the services that are installed on each cluster to prevent alert @@ -1058,18 +1082,12 @@ public class AmbariMetaInfo { // for every cluster for (Cluster cluster : clusterMap.values()) { - long clusterId = cluster.getClusterId(); - // creating a mapping between names and service/component for fast lookups -// Collection<ServiceInfo> stackServices = new ArrayList<>(); + long clusterId = cluster.getClusterId(); Map<String, ServiceInfo> stackServiceMap = new HashMap<>(); Map<String, ComponentInfo> stackComponentMap = new HashMap<>(); - - Map<String, Service> clusterServiceMap = cluster.getServices(); - Set<String> clusterServiceNames = clusterServiceMap.keySet(); - - // for every service installed in that cluster, get the service metainfo + // for every service installed in that cluster, get the service MetaInfo // and off of that the alert definitions List<AlertDefinition> stackDefinitions = new ArrayList<>(50); @@ -1116,11 +1134,6 @@ public class AmbariMetaInfo { // use the REST APIs to modify them instead AlertDefinition databaseDefinition = alertDefinitionFactory.coerce(entity); if (!stackDefinition.deeplyEquals(databaseDefinition)) { - // this is the code that would normally merge the stack definition - // into the database; this is not the behavior we want today - - // entity = alertDefinitionFactory.merge(stackDefinition, entity); - // persist.add(entity); LOG.debug( "The alert named {} has been modified from the stack definition and will not be merged", @@ -1149,28 +1162,10 @@ public class AmbariMetaInfo { } // ambari agent host-only alert definitions - List<AlertDefinition> agentDefinitions = ambariServiceAlertDefinitions.getAgentDefinitions(); - for (AlertDefinition agentDefinition : agentDefinitions) { - AlertDefinitionEntity entity = mappedEntities.get(agentDefinition.getName()); - - // no entity means this is new; create a new entity - if (null == entity) { - entity = alertDefinitionFactory.coerce(clusterId, agentDefinition); - persist.add(entity); - } - } + persist.addAll(getDefinitionsForMerge(ambariServiceAlertDefinitions.getAgentDefinitions(), clusterId, mappedEntities)); // ambari server host-only alert definitions - List<AlertDefinition> serverDefinitions = ambariServiceAlertDefinitions.getServerDefinitions(); - for (AlertDefinition serverDefinition : serverDefinitions) { - AlertDefinitionEntity entity = mappedEntities.get(serverDefinition.getName()); - - // no entity means this is new; create a new entity - if (null == entity) { - entity = alertDefinitionFactory.coerce(clusterId, serverDefinition); - persist.add(entity); - } - } + persist.addAll(getDefinitionsForMerge(ambariServiceAlertDefinitions.getServerDefinitions(), clusterId, mappedEntities)); // persist any new or updated definition for (AlertDefinitionEntity entity : persist) { @@ -1205,20 +1200,17 @@ public class AmbariMetaInfo { continue; } - StackId stackId = cluster.getService(serviceName).getDesiredStackId(); - if (!stackServiceMap.containsKey(serviceName)) { - LOG.info( - "The {} service has been marked as deleted for stack {}, disabling alert {}", - serviceName, stackId, definition.getDefinitionName()); + + LOG.info( "The {} service has been marked as deleted for cluster {}, disabling alert {}", + serviceName, cluster.getClusterName(), definition.getDefinitionName()); definitionsToDisable.add(definition); - } else if (null != componentName - && !stackComponentMap.containsKey(componentName)) { - LOG.info( - "The {} component {} has been marked as deleted for stack {}, disabling alert {}", - serviceName, componentName, stackId, - definition.getDefinitionName()); + } else if (null != componentName && !stackComponentMap.containsKey(componentName)) { + + StackId stackId = cluster.getService(serviceName).getDesiredStackId(); + LOG.info( "The {} component {} has been marked as deleted for stack {}, disabling alert {}", + serviceName, componentName, stackId, definition.getDefinitionName()); definitionsToDisable.add(definition); } http://git-wip-us.apache.org/repos/asf/ambari/blob/d6f26fb1/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java index 83b8f87..b7d977e 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java @@ -1791,6 +1791,59 @@ public class AmbariMetaInfoTest { assertFalse(entity.getEnabled()); } + /** + * Test scenario when service were removed and not mapped alerts need to be disabled + * + * @throws Exception + */ + @Test + public void testAlertDefinitionMergingRemoveScenario() throws Exception { + final String repoVersion = "2.0.6-1234"; + final String stackVersion = "2.0.6"; + + Injector injector = Guice.createInjector(Modules.override( + new InMemoryDefaultTestModule()).with(new MockModule())); + + EventBusSynchronizer.synchronizeAmbariEventPublisher(injector); + + injector.getInstance(GuiceJpaInitializer.class); + injector.getInstance(EntityManager.class); + + OrmTestHelper ormHelper = injector.getInstance(OrmTestHelper.class); + long clusterId = ormHelper.createCluster("cluster" + System.currentTimeMillis()); + + Class<?> c = metaInfo.getClass().getSuperclass(); + + Field f = c.getDeclaredField("alertDefinitionDao"); + f.setAccessible(true); + f.set(metaInfo, injector.getInstance(AlertDefinitionDAO.class)); + + f = c.getDeclaredField("ambariServiceAlertDefinitions"); + f.setAccessible(true); + f.set(metaInfo, injector.getInstance(AmbariServiceAlertDefinitions.class)); + + Clusters clusters = injector.getInstance(Clusters.class); + Cluster cluster = clusters.getClusterById(clusterId); + cluster.setDesiredStackVersion( + new StackId(STACK_NAME_HDP, stackVersion)); + + RepositoryVersionEntity repositoryVersion = ormHelper.getOrCreateRepositoryVersion( + cluster.getCurrentStackVersion(), repoVersion); + + cluster.addService("HDFS", repositoryVersion); + + metaInfo.reconcileAlertDefinitions(clusters, false); + + AlertDefinitionDAO dao = injector.getInstance(AlertDefinitionDAO.class); + List<AlertDefinitionEntity> definitions = dao.findAll(clusterId); + assertEquals(13, definitions.size()); + + cluster.deleteService("HDFS"); + metaInfo.reconcileAlertDefinitions(clusters, false); + List<AlertDefinitionEntity> updatedDefinitions = dao.findAll(clusterId); + assertEquals(7, updatedDefinitions.size()); + } + @Test public void testKerberosDescriptor() throws Exception { ServiceInfo service;
