You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/02/21 17:06:50 UTC
ambari git commit: AMBARI-20055 - Add Upgrade Logic For Removal of
clusterconfigmapping (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/branch-feature-AMBARI-20053 e8e2df21f -> 9386eed40
AMBARI-20055 - Add Upgrade Logic For Removal of clusterconfigmapping (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9386eed4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9386eed4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9386eed4
Branch: refs/heads/branch-feature-AMBARI-20053
Commit: 9386eed4073cb8b75800f516ddfe01c3f6528bb4
Parents: e8e2df2
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Feb 20 13:59:55 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Feb 20 16:49:10 2017 -0500
----------------------------------------------------------------------
.../orm/helpers/dbms/GenericDbmsHelper.java | 2 +-
.../server/upgrade/UpgradeCatalog300.java | 92 ++++++++++-
.../server/upgrade/UpgradeCatalog300Test.java | 155 +++++++++++++++++--
3 files changed, 233 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9386eed4/ambari-server/src/main/java/org/apache/ambari/server/orm/helpers/dbms/GenericDbmsHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/helpers/dbms/GenericDbmsHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/helpers/dbms/GenericDbmsHelper.java
index 36fab83..f60c138 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/helpers/dbms/GenericDbmsHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/helpers/dbms/GenericDbmsHelper.java
@@ -426,7 +426,7 @@ public class GenericDbmsHelper implements DbmsHelper {
// org.eclipse.persistence.internal.databaseaccess.appendParameterInternal
Object dbValue = databasePlatform.convertToDatabaseType(value);
String valueString = value.toString();
- if (dbValue instanceof String) {
+ if (dbValue instanceof String || dbValue instanceof Enum) {
valueString = "'" + value.toString() + "'";
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9386eed4/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index 0267a5e..d9b9b57 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -18,7 +18,9 @@
package org.apache.ambari.server.upgrade;
+import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -44,6 +46,7 @@ import org.apache.ambari.server.state.Config;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.support.JdbcUtils;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -55,11 +58,15 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
*/
private static final Logger LOG = LoggerFactory.getLogger(UpgradeCatalog300.class);
- private static final String STAGE_TABLE = "stage";
- private static final String STAGE_STATUS_COLUMN = "status";
- private static final String STAGE_DISPLAY_STATUS_COLUMN = "display_status";
- private static final String REQUEST_TABLE = "request";
- private static final String REQUEST_DISPLAY_STATUS_COLUMN = "display_status";
+ protected static final String STAGE_TABLE = "stage";
+ protected static final String STAGE_STATUS_COLUMN = "status";
+ protected static final String STAGE_DISPLAY_STATUS_COLUMN = "display_status";
+ protected static final String REQUEST_TABLE = "request";
+ protected static final String REQUEST_DISPLAY_STATUS_COLUMN = "display_status";
+ protected static final String CLUSTER_CONFIG_TABLE = "clusterconfig";
+ protected static final String CLUSTER_CONFIG_SELECTED_COLUMN = "selected";
+ protected static final String CLUSTER_CONFIG_SELECTED_TIMESTAMP_COLUMN = "selected_timestamp";
+ protected static final String CLUSTER_CONFIG_MAPPING_TABLE = "clusterconfigmapping";
@Inject
DaoUtils daoUtils;
@@ -104,6 +111,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
@Override
protected void executeDDLUpdates() throws AmbariException, SQLException {
updateStageTable();
+ updateClusterConfigurationTable();
}
protected void updateStageTable() throws SQLException {
@@ -120,6 +128,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
*/
@Override
protected void executePreDMLUpdates() throws AmbariException, SQLException {
+ setSelectedConfigurationsAndRemoveMappingTable();
}
/**
@@ -189,7 +198,80 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
}
}
});
+ }
+
+ /**
+ * Performs the following operations on {@code clusterconfig}:
+ * <ul>
+ * <li>Adds the {@link #CLUSTER_CONFIG_SELECTED_COLUMN} to
+ * {@link #CLUSTER_CONFIG_TABLE}.
+ * <li>Adds the {@link #CLUSTER_CONFIG_SELECTED_TIMESTAMP} to
+ * {@link #CLUSTER_CONFIG_TABLE}.
+ * </ul>
+ */
+ protected void updateClusterConfigurationTable() throws SQLException {
+ dbAccessor.addColumn(CLUSTER_CONFIG_TABLE,
+ new DBAccessor.DBColumnInfo(CLUSTER_CONFIG_SELECTED_COLUMN, Short.class, null, 0, false));
+ dbAccessor.addColumn(CLUSTER_CONFIG_TABLE,
+ new DBAccessor.DBColumnInfo(CLUSTER_CONFIG_SELECTED_TIMESTAMP_COLUMN, Long.class, null, 0,
+ false));
}
+ /**
+ * Performs the following operations on {@code clusterconfig} and
+ * {@code clusterconfigmapping}:
+ * <ul>
+ * <li>Sets both selected columns to the current config by querying
+ * {@link #CLUSTER_CONFIG_MAPPING_TABLE}.
+ * <li>Removes {@link #CLUSTER_CONFIG_MAPPING_TABLE}.
+ * </ul>
+ */
+ protected void setSelectedConfigurationsAndRemoveMappingTable() throws SQLException {
+ // update the new selected columns
+ executeInTransaction(new Runnable() {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ String selectSQL = String.format(
+ "SELECT cluster_id, type_name, version_tag FROM %s WHERE selected = 1 ORDER BY cluster_id ASC, type_name ASC, version_tag ASC",
+ CLUSTER_CONFIG_MAPPING_TABLE);
+
+ Statement statement = null;
+ ResultSet resultSet = null;
+
+ long now = System.currentTimeMillis();
+
+ try {
+ statement = dbAccessor.getConnection().createStatement();
+ resultSet = statement.executeQuery(selectSQL);
+
+ while (resultSet.next()) {
+ final Long clusterId = resultSet.getLong("cluster_id");
+ final String typeName = resultSet.getString("type_name");
+ final String versionTag = resultSet.getString("version_tag");
+
+ // inefficient since this can be done with a single nested SELECT,
+ // but this way we can log what's happening which is more useful
+ String updateSQL = String.format(
+ "UPDATE %s SET selected = 1, selected_timestamp = %d WHERE cluster_id = %d AND type_name = '%s' AND version_tag = '%s'",
+ CLUSTER_CONFIG_TABLE, now, clusterId, typeName, versionTag);
+
+ dbAccessor.executeQuery(updateSQL);
+ }
+ } catch (SQLException sqlException) {
+ throw new RuntimeException(sqlException);
+ } finally {
+ JdbcUtils.closeResultSet(resultSet);
+ JdbcUtils.closeStatement(statement);
+ }
+ }
+ });
+
+ // if the above execution and committed the transaction, then we can remove
+ // the cluster configuration mapping table
+ dbAccessor.dropTable(CLUSTER_CONFIG_MAPPING_TABLE);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9386eed4/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
index ec001ec..a44c2b3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
@@ -17,16 +17,84 @@
*/
package org.apache.ambari.server.upgrade;
+import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.newCapture;
import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import java.lang.reflect.Method;
-
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import javax.persistence.Cache;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockRunner;
+import org.easymock.Mock;
+import org.easymock.MockType;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.google.gson.Gson;
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+@RunWith(EasyMockRunner.class)
public class UpgradeCatalog300Test {
+ @Mock(type = MockType.STRICT)
+ private Provider<EntityManager> entityManagerProvider;
+
+ @Mock(type = MockType.NICE)
+ private Injector injector;
+
+ @Mock(type = MockType.NICE)
+ private EntityManager entityManager;
+
+ @Mock(type = MockType.NICE)
+ private DBAccessor dbAccessor;
+
+ @Mock(type = MockType.NICE)
+ private OsFamily osFamily;
+
+ @Mock(type = MockType.NICE)
+ private Configuration configuration;
+
+ @Before
+ public void init() {
+ reset(entityManagerProvider, injector);
+
+ expect(entityManagerProvider.get()).andReturn(entityManager).anyTimes();
+
+ expect(injector.getInstance(Gson.class)).andReturn(null).anyTimes();
+ expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).anyTimes();
+
+ replay(entityManagerProvider, injector);
+ }
+
+ @After
+ public void tearDown() {
+ }
+
@Test
public void testExecuteDMLUpdates() throws Exception {
Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml");
@@ -54,19 +122,86 @@ public class UpgradeCatalog300Test {
@Test
public void testExecuteDDLUpdates() throws Exception {
- Method updateStageTable = UpgradeCatalog300.class.getDeclaredMethod("updateStageTable");
- UpgradeCatalog300 upgradeCatalog300 = createMockBuilder(UpgradeCatalog300.class)
- .addMockedMethod(updateStageTable)
- .createMock();
-
- upgradeCatalog300.updateStageTable();
+ Module module = new Module() {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(DBAccessor.class).toInstance(dbAccessor);
+ binder.bind(OsFamily.class).toInstance(osFamily);
+ binder.bind(EntityManager.class).toInstance(entityManager);
+ binder.bind(Configuration.class).toInstance(configuration);
+ }
+ };
+
+ Capture<DBAccessor.DBColumnInfo> clusterConfigSelectedColumn = newCapture();
+ Capture<DBAccessor.DBColumnInfo> clusterConfigSelectedTimestampColumn = newCapture();
+ dbAccessor.addColumn(eq(UpgradeCatalog300.CLUSTER_CONFIG_TABLE), capture(clusterConfigSelectedColumn));
+ dbAccessor.addColumn(eq(UpgradeCatalog300.CLUSTER_CONFIG_TABLE), capture(clusterConfigSelectedTimestampColumn));
+
+ replay(dbAccessor, configuration);
+
+ Injector injector = Guice.createInjector(module);
+ UpgradeCatalog300 upgradeCatalog300 = injector.getInstance(UpgradeCatalog300.class);
+ upgradeCatalog300.executeDDLUpdates();
- replay(upgradeCatalog300);
+ DBAccessor.DBColumnInfo capturedSelectedColumn = clusterConfigSelectedColumn.getValue();
+ Assert.assertNotNull(capturedSelectedColumn);
+ Assert.assertEquals(UpgradeCatalog300.CLUSTER_CONFIG_SELECTED_COLUMN, capturedSelectedColumn.getName());
+ Assert.assertEquals(Short.class, capturedSelectedColumn.getType());
- upgradeCatalog300.executeDDLUpdates();
+ DBAccessor.DBColumnInfo capturedSelectedTimestampColumn = clusterConfigSelectedTimestampColumn.getValue();
+ Assert.assertNotNull(capturedSelectedTimestampColumn);
+ Assert.assertEquals(UpgradeCatalog300.CLUSTER_CONFIG_SELECTED_TIMESTAMP_COLUMN, capturedSelectedTimestampColumn.getName());
+ Assert.assertEquals(Long.class, capturedSelectedTimestampColumn.getType());
- verify(upgradeCatalog300);
+ verify(dbAccessor);
}
+ /**
+ * Tests pre-DML executions.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testExecutePreDMLUpdates() throws Exception {
+ Module module = new Module() {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(DBAccessor.class).toInstance(dbAccessor);
+ binder.bind(OsFamily.class).toInstance(osFamily);
+ binder.bind(EntityManager.class).toInstance(entityManager);
+ binder.bind(Configuration.class).toInstance(configuration);
+ }
+ };
+
+ EntityManagerFactory emFactory = EasyMock.createNiceMock(EntityManagerFactory.class);
+ Cache emCache = EasyMock.createNiceMock(Cache.class);
+
+ expect(entityManager.getEntityManagerFactory()).andReturn(emFactory).atLeastOnce();
+ expect(emFactory.getCache()).andReturn(emCache).atLeastOnce();
+
+ EntityTransaction mockTransaction = EasyMock.createNiceMock(EntityTransaction.class);
+ Connection mockConnection = EasyMock.createNiceMock(Connection.class);
+ Statement mockStatement = EasyMock.createNiceMock(Statement.class);
+ expect(dbAccessor.getConnection()).andReturn(mockConnection).once();
+ expect(mockConnection.createStatement()).andReturn(mockStatement).once();
+
+ expect(mockStatement.executeQuery(EasyMock.anyString())).andReturn(
+ EasyMock.createNiceMock(ResultSet.class));
+
+ expect(entityManager.getTransaction()).andReturn(
+ mockTransaction).atLeastOnce();
+
+ dbAccessor.dropTable(UpgradeCatalog300.CLUSTER_CONFIG_MAPPING_TABLE);
+ EasyMock.expectLastCall().once();
+
+ replay(dbAccessor, entityManager, emFactory, emCache, mockConnection, mockTransaction,
+ mockStatement, configuration);
+
+ Injector injector = Guice.createInjector(module);
+ UpgradeCatalog300 upgradeCatalog300 = injector.getInstance(UpgradeCatalog300.class);
+ upgradeCatalog300.executePreDMLUpdates();
+
+ verify(dbAccessor, entityManager, emFactory, emCache);
+ }
}