ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dmitriu...@apache.org
Subject [3/4] ambari git commit: AMBARI-19464. Stack Downgrading Potentially Corrupts Kerberos Descriptor (echekanskiy via dlysnichenko)
Date Thu, 12 Jan 2017 14:26:11 GMT
AMBARI-19464. Stack Downgrading Potentially Corrupts Kerberos Descriptor (echekanskiy via dlysnichenko)


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

Branch: refs/heads/trunk
Commit: 59a770f2edd5e2e40cff3221d9b972e97ba4afa5
Parents: 384a7f0
Author: Lisnichenko Dmitro <dlysnichenko@hortonworks.com>
Authored: Thu Jan 12 16:24:30 2017 +0200
Committer: Lisnichenko Dmitro <dlysnichenko@hortonworks.com>
Committed: Thu Jan 12 16:24:30 2017 +0200

----------------------------------------------------------------------
 .../server/orm/entities/ArtifactEntity.java     |   4 +-
 .../upgrades/UpgradeUserKerberosDescriptor.java | 130 +++++++++---
 .../UpgradeUserKerberosDescriptorTest.java      | 201 +++++++++++++++++++
 3 files changed, 302 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/59a770f2/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ArtifactEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ArtifactEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ArtifactEntity.java
index 367c093..d06d985 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ArtifactEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ArtifactEntity.java
@@ -113,7 +113,7 @@ public class ArtifactEntity {
    *
    * @param foreignKeys  ordered map of foreign key property names to values
    */
-  public void setForeignKeys(TreeMap<String, String> foreignKeys) {
+  public void setForeignKeys(Map<String, String> foreignKeys) {
     this.foreignKeys = serializeForeignKeys(foreignKeys);
   }
 
@@ -135,7 +135,7 @@ public class ArtifactEntity {
    *
    * @return string representation of the foreign keys map
    */
-  public static String serializeForeignKeys(TreeMap<String, String> foreignKeys) {
+  public static String serializeForeignKeys(Map<String, String> foreignKeys) {
     return jsonSerializer.toJson(foreignKeys);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/59a770f2/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
index 6f79670..ac1e86d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
@@ -76,6 +76,9 @@ public class UpgradeUserKerberosDescriptor extends AbstractServerAction
{
    */
   private static final String TARGET_STACK_KEY = "target_stack";
 
+  private final static String KERBEROS_DESCRIPTOR_NAME = "kerberos_descriptor";
+  private final static String KERBEROS_DESCRIPTOR_BACKUP_NAME = "kerberos_descriptor_backup";
+
   @Inject
   private ArtifactDAO artifactDAO;
 
@@ -117,49 +120,52 @@ public class UpgradeUserKerberosDescriptor extends AbstractServerAction
{
       if (userDescriptor != null) {
         StackId originalStackId = getStackIdFromCommandParams(ORIGINAL_STACK_KEY);
         StackId targetStackId = getStackIdFromCommandParams(TARGET_STACK_KEY);
-        boolean isDowngrade = isDowngrade();
-
-        StackId newVersion = (isDowngrade) ? originalStackId : targetStackId;
-        StackId previousVersion = (isDowngrade) ? targetStackId : originalStackId;
-        KerberosDescriptor newDescriptor = null;
-        KerberosDescriptor previousDescriptor = null;
 
-        if (newVersion == null) {
-          logErrorMessage(messages, errorMessages, "The new stack version information was
not found.");
+        if (isDowngrade()) {
+          restoreDescriptor(foreignKeys, messages, errorMessages);
         } else {
-          logMessage(messages, String.format("Obtaining new stack Kerberos descriptor for
%s.", newVersion.toString()));
-          newDescriptor = ambariMetaInfo.getKerberosDescriptor(newVersion.getStackName(),
newVersion.getStackVersion());
+          backupDescriptor(foreignKeys, messages, errorMessages);
+
+          KerberosDescriptor newDescriptor = null;
+          KerberosDescriptor previousDescriptor = null;
+
+          if (targetStackId == null) {
+            logErrorMessage(messages, errorMessages, "The new stack version information was
not found.");
+          } else {
+            logMessage(messages, String.format("Obtaining new stack Kerberos descriptor for
%s.", targetStackId.toString()));
+            newDescriptor = ambariMetaInfo.getKerberosDescriptor(targetStackId.getStackName(),
targetStackId.getStackVersion());
 
-          if (newDescriptor == null) {
-            logErrorMessage(messages, errorMessages, String.format("The Kerberos descriptor
for the new stack version, %s, was not found.", newVersion.toString()));
+            if (newDescriptor == null) {
+              logErrorMessage(messages, errorMessages, String.format("The Kerberos descriptor
for the new stack version, %s, was not found.", targetStackId.toString()));
+            }
           }
-        }
 
-        if (previousVersion == null) {
-          logErrorMessage(messages, errorMessages, "The previous stack version information
was not found.");
-        } else {
-          logMessage(messages, String.format("Obtaining previous stack Kerberos descriptor
for %s.", previousVersion.toString()));
-          previousDescriptor = ambariMetaInfo.getKerberosDescriptor(previousVersion.getStackName(),
previousVersion.getStackVersion());
+          if (originalStackId == null) {
+            logErrorMessage(messages, errorMessages, "The previous stack version information
was not found.");
+          } else {
+            logMessage(messages, String.format("Obtaining previous stack Kerberos descriptor
for %s.", originalStackId.toString()));
+            previousDescriptor = ambariMetaInfo.getKerberosDescriptor(originalStackId.getStackName(),
originalStackId.getStackVersion());
 
-          if (newDescriptor == null) {
-            logErrorMessage(messages, errorMessages, String.format("The Kerberos descriptor
for the previous stack version, %s, was not found.", previousVersion.toString()));
+            if (newDescriptor == null) {
+              logErrorMessage(messages, errorMessages, String.format("The Kerberos descriptor
for the previous stack version, %s, was not found.", originalStackId.toString()));
+            }
           }
-        }
 
-        if (errorMessages.isEmpty()) {
-          logMessage(messages, "Updating the user-specified Kerberos descriptor.");
+          if (errorMessages.isEmpty()) {
+            logMessage(messages, "Updating the user-specified Kerberos descriptor.");
 
-          KerberosDescriptor updatedDescriptor = KerberosDescriptorUpdateHelper.updateUserKerberosDescriptor(
-              previousDescriptor,
-              newDescriptor,
-              userDescriptor);
+            KerberosDescriptor updatedDescriptor = KerberosDescriptorUpdateHelper.updateUserKerberosDescriptor(
+                previousDescriptor,
+                newDescriptor,
+                userDescriptor);
 
-          logMessage(messages, "Storing updated user-specified Kerberos descriptor.");
+            logMessage(messages, "Storing updated user-specified Kerberos descriptor.");
 
-          entity.setArtifactData(updatedDescriptor.toMap());
-          artifactDAO.merge(entity);
+            entity.setArtifactData(updatedDescriptor.toMap());
+            artifactDAO.merge(entity);
 
-          logMessage(messages, "Successfully updated the user-specified Kerberos descriptor.");
+            logMessage(messages, "Successfully updated the user-specified Kerberos descriptor.");
+          }
         }
       } else {
         logMessage(messages, "A user-specified Kerberos descriptor was not found. No updates
are necessary.");
@@ -203,4 +209,66 @@ public class UpgradeUserKerberosDescriptor extends AbstractServerAction
{
     messages.add(message);
     errorMessages.add(message);
   }
+
+  /**
+   * Create copy of user defined kerberos descriptor and stores it with name {@code kerberos_descriptor_backup}.
+   *
+   * @param foreignKeys   keys specific for cluster
+   * @param messages      list of log messages
+   * @param errorMessages list of error log messages
+   */
+  private void backupDescriptor(TreeMap<String, String> foreignKeys, List<String>
messages, List<String> errorMessages) {
+    ArtifactEntity backupEntity = artifactDAO.findByNameAndForeignKeys(KERBEROS_DESCRIPTOR_BACKUP_NAME,
foreignKeys);
+    if (backupEntity != null) {
+      artifactDAO.remove(backupEntity);
+    }
+
+    ArtifactEntity entity = artifactDAO.findByNameAndForeignKeys(KERBEROS_DESCRIPTOR_NAME,
foreignKeys);
+    if (entity != null) {
+      backupEntity = new ArtifactEntity();
+      backupEntity.setArtifactName(KERBEROS_DESCRIPTOR_BACKUP_NAME);
+      backupEntity.setForeignKeys(entity.getForeignKeys());
+      backupEntity.setArtifactData(entity.getArtifactData());
+
+      artifactDAO.create(backupEntity);
+      logMessage(messages, "Created backup of kerberos descriptor");
+    } else {
+      logErrorMessage(
+          messages,
+          errorMessages,
+          "No backup of kerberos descriptor created due to missing original kerberos descriptor"
+      );
+    }
+
+
+  }
+
+  /**
+   * Restores user defined kerberos descriptor from artifact with name {@code kerberos_descriptor_backup}.
+   *
+   * @param foreignKeys   keys specific for cluster
+   * @param messages      list of log messages
+   * @param errorMessages list of error log messages
+   */
+  private void restoreDescriptor(TreeMap<String, String> foreignKeys, List<String>
messages, List<String> errorMessages) {
+    ArtifactEntity backupEntity = artifactDAO.findByNameAndForeignKeys(KERBEROS_DESCRIPTOR_BACKUP_NAME,
foreignKeys);
+
+    if (backupEntity != null) {
+      ArtifactEntity entity = artifactDAO.findByNameAndForeignKeys(KERBEROS_DESCRIPTOR_NAME,
foreignKeys);
+      if (entity != null) {
+        artifactDAO.remove(entity);
+      }
+
+      entity = new ArtifactEntity();
+      entity.setArtifactName(KERBEROS_DESCRIPTOR_NAME);
+      entity.setForeignKeys(backupEntity.getForeignKeys());
+      entity.setArtifactData(backupEntity.getArtifactData());
+
+      artifactDAO.create(entity);
+      logMessage(messages, "Restored kerberos descriptor from backup");
+    } else {
+      logErrorMessage(messages, errorMessages, "No backup of kerberos descriptor found");
+    }
+  }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/59a770f2/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptorTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptorTest.java
new file mode 100644
index 0000000..9e2080b
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptorTest.java
@@ -0,0 +1,201 @@
+/**
+ * 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.serveraction.upgrades;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.orm.dao.ArtifactDAO;
+import org.apache.ambari.server.orm.entities.ArtifactEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
+import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
+import org.apache.ambari.server.state.kerberos.KerberosDescriptorUpdateHelper;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Tests OozieConfigCalculation logic
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(KerberosDescriptorUpdateHelper.class)
+public class UpgradeUserKerberosDescriptorTest {
+  private Clusters clusters;
+  private Cluster cluster;
+  private AmbariMetaInfo ambariMetaInfo;
+  private KerberosDescriptorFactory kerberosDescriptorFactory;
+  private ArtifactDAO artifactDAO;
+
+  private TreeMap<String, Field> fields = new TreeMap<>();
+
+  @Before
+  public void setup() throws Exception {
+    clusters = EasyMock.createMock(Clusters.class);
+    cluster = EasyMock.createMock(Cluster.class);
+    kerberosDescriptorFactory = EasyMock.createNiceMock(KerberosDescriptorFactory.class);
+    ambariMetaInfo = EasyMock.createMock(AmbariMetaInfo.class);
+    artifactDAO = EasyMock.createNiceMock(ArtifactDAO.class);
+
+    expect(clusters.getCluster((String) anyObject())).andReturn(cluster).anyTimes();
+    expect(cluster.getClusterId()).andReturn(1l).atLeastOnce();
+    replay(clusters, cluster);
+
+    prepareFields();
+
+  }
+
+  @Test
+  public void testUpgrade() throws Exception {
+
+    Map<String, String> commandParams = new HashMap<String, String>();
+    commandParams.put("clusterName", "c1");
+    commandParams.put("upgrade_direction", "UPGRADE");
+    commandParams.put("original_stack", "HDP-2.4");
+    commandParams.put("target_stack", "HDP-2.5");
+
+    ExecutionCommand executionCommand = new ExecutionCommand();
+    executionCommand.setCommandParams(commandParams);
+    executionCommand.setClusterName("c1");
+
+    HostRoleCommand hrc = EasyMock.createMock(HostRoleCommand.class);
+    expect(hrc.getRequestId()).andReturn(1L).anyTimes();
+    expect(hrc.getStageId()).andReturn(2L).anyTimes();
+    expect(hrc.getExecutionCommandWrapper()).andReturn(new ExecutionCommandWrapper(executionCommand)).anyTimes();
+    replay(hrc);
+
+    UpgradeUserKerberosDescriptor action = new UpgradeUserKerberosDescriptor();
+    injectFields(action);
+
+    action.setExecutionCommand(executionCommand);
+    action.setHostRoleCommand(hrc);
+
+    ArtifactEntity entity = EasyMock.createNiceMock(ArtifactEntity.class);
+    expect(entity.getArtifactData()).andReturn(null).anyTimes();
+    expect(entity.getForeignKeys()).andReturn(null).anyTimes();
+    expect(artifactDAO.findByNameAndForeignKeys(anyString(), (TreeMap<String, String>)
anyObject())).andReturn(entity).atLeastOnce();
+
+    KerberosDescriptor userDescriptor = EasyMock.createMock(KerberosDescriptor.class);
+    KerberosDescriptor newDescriptor = EasyMock.createMock(KerberosDescriptor.class);
+    KerberosDescriptor previousDescriptor = EasyMock.createMock(KerberosDescriptor.class);
+    KerberosDescriptor updatedKerberosDescriptor = EasyMock.createMock(KerberosDescriptor.class);
+
+    PowerMockito.mockStatic(KerberosDescriptorUpdateHelper.class);
+    PowerMockito.when(KerberosDescriptorUpdateHelper.updateUserKerberosDescriptor(previousDescriptor,
newDescriptor, userDescriptor)).thenReturn(updatedKerberosDescriptor);
+    expect(kerberosDescriptorFactory.createInstance((Map)null)).andReturn(userDescriptor).atLeastOnce();
+    expect(ambariMetaInfo.getKerberosDescriptor("HDP","2.5")).andReturn(newDescriptor).atLeastOnce();
+    expect(ambariMetaInfo.getKerberosDescriptor("HDP","2.4")).andReturn(previousDescriptor).atLeastOnce();
+
+
+    expect(updatedKerberosDescriptor.toMap()).andReturn(null).once();
+
+
+    expect(artifactDAO.merge(entity)).andReturn(entity).once();
+    Capture<ArtifactEntity> createCapture = Capture.newInstance();
+    artifactDAO.create(capture(createCapture));
+    EasyMock.expectLastCall().once();
+
+    replay(artifactDAO, entity, ambariMetaInfo, kerberosDescriptorFactory, updatedKerberosDescriptor);
+
+    action.execute(null);
+
+    verify(artifactDAO, updatedKerberosDescriptor);
+    assertEquals(createCapture.getValue().getArtifactName(), "kerberos_descriptor_backup");
+  }
+
+  @Test
+  public void testDowngrade() throws Exception {
+
+    Map<String, String> commandParams = new HashMap<String, String>();
+    commandParams.put("clusterName", "c1");
+    commandParams.put("upgrade_direction", "DOWNGRADE");
+    commandParams.put("original_stack", "HDP-2.4");
+    commandParams.put("target_stack", "HDP-2.5");
+
+    ExecutionCommand executionCommand = new ExecutionCommand();
+    executionCommand.setCommandParams(commandParams);
+    executionCommand.setClusterName("c1");
+
+    HostRoleCommand hrc = EasyMock.createMock(HostRoleCommand.class);
+    expect(hrc.getRequestId()).andReturn(1L).anyTimes();
+    expect(hrc.getStageId()).andReturn(2L).anyTimes();
+    expect(hrc.getExecutionCommandWrapper()).andReturn(new ExecutionCommandWrapper(executionCommand)).anyTimes();
+    replay(hrc);
+
+    UpgradeUserKerberosDescriptor action = new UpgradeUserKerberosDescriptor();
+    injectFields(action);
+
+    action.setExecutionCommand(executionCommand);
+    action.setHostRoleCommand(hrc);
+
+    ArtifactEntity entity = EasyMock.createNiceMock(ArtifactEntity.class);
+    expect(entity.getArtifactData()).andReturn(null).anyTimes();
+    expect(entity.getForeignKeys()).andReturn(null).anyTimes();
+    expect(artifactDAO.findByNameAndForeignKeys(anyString(), (TreeMap<String, String>)
anyObject())).andReturn(entity).atLeastOnce();
+
+    KerberosDescriptor userDescriptor = EasyMock.createMock(KerberosDescriptor.class);
+
+    expect(kerberosDescriptorFactory.createInstance((Map)null)).andReturn(userDescriptor).atLeastOnce();
+
+    Capture<ArtifactEntity> createCapture = Capture.newInstance();
+    artifactDAO.create(capture(createCapture));
+    EasyMock.expectLastCall().once();
+
+    artifactDAO.remove(entity);
+    EasyMock.expectLastCall().atLeastOnce();
+
+    replay(artifactDAO, entity, ambariMetaInfo, kerberosDescriptorFactory);
+
+    action.execute(null);
+
+    verify(artifactDAO);
+    assertEquals(createCapture.getValue().getArtifactName(), "kerberos_descriptor");
+  }
+
+  private void prepareFields() throws NoSuchFieldException {
+    String[] fieldsNames = {"artifactDAO","clusters","ambariMetaInfo","kerberosDescriptorFactory"};
+    for(String fieldName : fieldsNames)
+    {
+      Field clustersField = UpgradeUserKerberosDescriptor.class.getDeclaredField(fieldName);
+      clustersField.setAccessible(true);
+      fields.put(fieldName, clustersField);
+    }
+  }
+  private void injectFields(UpgradeUserKerberosDescriptor action) throws IllegalAccessException
{
+    fields.get("artifactDAO").set(action, artifactDAO);
+    fields.get("clusters").set(action, clusters);
+    fields.get("ambariMetaInfo").set(action, ambariMetaInfo);
+    fields.get("kerberosDescriptorFactory").set(action, kerberosDescriptorFactory);
+  }
+}


Mime
View raw message