Repository: ambari Updated Branches: refs/heads/trunk a91890a81 -> 7d06e8bf6
AMBARI-14912: Add upgrade support for Setting feature (Ajit Kumar via smnaha) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7d06e8bf Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7d06e8bf Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7d06e8bf Branch: refs/heads/trunk Commit: 7d06e8bf68abe725620c0eb60cce16959901c747 Parents: a91890a Author: Nahappan Somasundaram <[email protected]> Authored: Wed Feb 17 09:06:39 2016 -0800 Committer: Nahappan Somasundaram <[email protected]> Committed: Wed Feb 17 09:06:39 2016 -0800 ---------------------------------------------------------------------- .../server/upgrade/UpgradeCatalog240.java | 76 +++++++++++++--- .../server/upgrade/UpgradeCatalog240Test.java | 92 ++++++++++++++------ 2 files changed, 132 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/7d06e8bf/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java index 2ea326a..d97962f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.upgrade; +import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -30,6 +31,8 @@ import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; import org.apache.ambari.server.orm.dao.DaoUtils; +import org.apache.ambari.server.orm.dao.PermissionDAO; +import org.apache.ambari.server.orm.dao.ResourceTypeDAO; import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; import org.apache.ambari.server.orm.entities.PermissionEntity; import org.apache.ambari.server.state.Cluster; @@ -37,7 +40,9 @@ import org.apache.ambari.server.state.Clusters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -58,12 +63,19 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { @Inject DaoUtils daoUtils; + @Inject + PermissionDAO permissionDAO; + + @Inject + ResourceTypeDAO resourceTypeDAO; + /** * Logger. */ private static final Logger LOG = LoggerFactory.getLogger(UpgradeCatalog240.class); - + private static final String ID = "id"; + private static final String SETTING_TABLE = "setting"; // ----- Constructors ------------------------------------------------------ @@ -76,7 +88,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { @Inject public UpgradeCatalog240(Injector injector) { super(injector); - this.injector = injector; + injector.injectMembers(this); } // ----- UpgradeCatalog ---------------------------------------------------- @@ -103,6 +115,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { @Override protected void executeDDLUpdates() throws AmbariException, SQLException { updateAdminPermissionTable(); + createSettingTable(); } @Override @@ -115,7 +128,39 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { addNewConfigurationsFromXml(); updateAlerts(); setRoleSortOrder(); + addSettingPermission(); + } + + private void createSettingTable() throws SQLException { + List<DBAccessor.DBColumnInfo> columns = new ArrayList<>(); + // Add setting table + LOG.info("Creating " + SETTING_TABLE + " table"); + + columns.add(new DBAccessor.DBColumnInfo(ID, Long.class, null, null, false)); + columns.add(new DBAccessor.DBColumnInfo("name", String.class, 255, null, false)); + columns.add(new DBAccessor.DBColumnInfo("setting_type", String.class, 255, null, false)); + columns.add(new DBAccessor.DBColumnInfo("content", String.class, 3000, null, false)); + columns.add(new DBAccessor.DBColumnInfo("updated_by", String.class, 255, "_db", false)); + columns.add(new DBAccessor.DBColumnInfo("update_timestamp", Long.class, null, null, false)); + dbAccessor.createTable(SETTING_TABLE, columns, ID); + addSequence("setting_id_seq", 0L, false); + } + + protected void addSettingPermission() throws SQLException { + String administratorPermissionId = + permissionDAO.findPermissionByNameAndType("AMBARI.ADMINISTRATOR", resourceTypeDAO.findByName("AMBARI")).getId().toString(); + String selectRoleSql = "select * from roleauthorization where authorization_id = 'AMBARI.MANAGE_SETTINGS'"; + if (executeAndCheckEmptyResult(selectRoleSql)) { + dbAccessor.insertRow("roleauthorization", new String[]{"authorization_id", "authorization_name"}, + new String[]{"'AMBARI.MANAGE_SETTINGS'", "'Manage settings'"}, false); + } + + String selectPermissionSql = "select * from permission_roleauthorization where authorization_id = 'AMBARI.MANAGE_SETTINGS'"; + if (executeAndCheckEmptyResult(selectPermissionSql)) { + dbAccessor.insertRow("permission_roleauthorization", new String[]{"permission_id", "authorization_id"}, + new String[]{administratorPermissionId, "'AMBARI.MANAGE_SETTINGS'"}, false); + } } protected void updateAlerts() { @@ -147,21 +192,21 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { Map<AlertDefinitionEntity, List<String>> alertDefinitionParams = new HashMap<>(); checkedPutToMap(alertDefinitionParams, namenodeLastCheckpointAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("connection.timeout", "checkpoint.time.warning.threshold", "checkpoint.time.critical.threshold"))); + Lists.newArrayList("connection.timeout", "checkpoint.time.warning.threshold", "checkpoint.time.critical.threshold")); checkedPutToMap(alertDefinitionParams, namenodeHAHealthAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("connection.timeout"))); + Lists.newArrayList("connection.timeout")); checkedPutToMap(alertDefinitionParams, nodemanagerHealthAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("connection.timeout"))); + Lists.newArrayList("connection.timeout")); checkedPutToMap(alertDefinitionParams, nodemanagerHealthSummaryAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("connection.timeout"))); + Lists.newArrayList("connection.timeout")); checkedPutToMap(alertDefinitionParams, hiveMetastoreProcessAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("default.smoke.user", "default.smoke.principal", "default.smoke.keytab"))); + Lists.newArrayList("default.smoke.user", "default.smoke.principal", "default.smoke.keytab")); checkedPutToMap(alertDefinitionParams, hiveServerProcessAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("default.smoke.user", "default.smoke.principal", "default.smoke.keytab"))); + Lists.newArrayList("default.smoke.user", "default.smoke.principal", "default.smoke.keytab")); checkedPutToMap(alertDefinitionParams, hiveWebhcatServerStatusAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("default.smoke.user", "connection.timeout"))); + Lists.newArrayList("default.smoke.user", "connection.timeout")); checkedPutToMap(alertDefinitionParams, flumeAgentStatusAlertDefinitionEntity, - new ArrayList<String>(Arrays.asList("run.directory"))); + Lists.newArrayList("run.directory")); for(Map.Entry<AlertDefinitionEntity, List<String>> entry : alertDefinitionParams.entrySet()){ AlertDefinitionEntity alertDefinition = entry.getKey(); @@ -186,6 +231,17 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { } } + private boolean executeAndCheckEmptyResult(String sql) throws SQLException { + try(Statement statement = dbAccessor.getConnection().createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + if (resultSet != null && resultSet.next()) { + return false; + } else { + return true; + } + } + } + protected String addParam(String source, List<String> params) { JsonObject sourceJson = new JsonParser().parse(source).getAsJsonObject(); JsonArray parametersJson = sourceJson.getAsJsonArray("parameters"); http://git-wip-us.apache.org/repos/asf/ambari/blob/7d06e8bf/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java index 608a348..a145253 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java @@ -19,91 +19,115 @@ package org.apache.ambari.server.upgrade; +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; -import com.google.inject.persist.PersistService; import junit.framework.Assert; +import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.dao.StackDAO; -import org.apache.ambari.server.orm.entities.StackEntity; import org.easymock.Capture; import org.easymock.CaptureType; +import org.apache.ambari.server.state.stack.OsFamily; +import org.easymock.EasyMock; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import javax.persistence.EntityManager; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMockBuilder; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.expectLastCall; 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 static org.junit.Assert.assertEquals; public class UpgradeCatalog240Test { - private Injector injector; + private static Injector injector; private Provider<EntityManager> entityManagerProvider = createStrictMock(Provider.class); private EntityManager entityManager = createNiceMock(EntityManager.class); - private UpgradeCatalogHelper upgradeCatalogHelper; - private StackEntity desiredStackEntity; + @BeforeClass + public static void classSetUp() { + injector = Guice.createInjector(new InMemoryDefaultTestModule()); + injector.getInstance(GuiceJpaInitializer.class); + } @Before public void init() { reset(entityManagerProvider); expect(entityManagerProvider.get()).andReturn(entityManager).anyTimes(); replay(entityManagerProvider); - injector = Guice.createInjector(new InMemoryDefaultTestModule()); - injector.getInstance(GuiceJpaInitializer.class); - upgradeCatalogHelper = injector.getInstance(UpgradeCatalogHelper.class); + injector.getInstance(UpgradeCatalogHelper.class); // inject AmbariMetaInfo to ensure that stacks get populated in the DB injector.getInstance(AmbariMetaInfo.class); // load the stack entity StackDAO stackDAO = injector.getInstance(StackDAO.class); - desiredStackEntity = stackDAO.find("HDP", "2.2.0"); + stackDAO.find("HDP", "2.2.0"); } @After public void tearDown() { - injector.getInstance(PersistService.class).stop(); } @Test - public void testExecuteDDLUpdates() throws Exception { - UpgradeCatalog240 upgradeCatalog240 = injector.getInstance(UpgradeCatalog240.class); - + public void testExecuteDDLUpdates() throws SQLException, AmbariException { Capture<DBAccessor.DBColumnInfo> capturedColumnInfo = newCapture(); + final DBAccessor dbAccessor = createStrictMock(DBAccessor.class); + Configuration configuration = createNiceMock(Configuration.class); + Connection connection = createNiceMock(Connection.class); + Statement statement = createNiceMock(Statement.class); + ResultSet resultSet = createNiceMock(ResultSet.class); + Capture<List<DBAccessor.DBColumnInfo>> capturedSettingColumns = EasyMock.newCapture(); - DBAccessor dbAccessor = createStrictMock(DBAccessor.class); dbAccessor.addColumn(eq("adminpermission"), capture(capturedColumnInfo)); - expectLastCall().once(); - - Field field = AbstractUpgradeCatalog.class.getDeclaredField("dbAccessor"); - field.set(upgradeCatalog240, dbAccessor); + dbAccessor.createTable(eq("setting"), capture(capturedSettingColumns), eq("id")); + expect(configuration.getDatabaseUrl()).andReturn(Configuration.JDBC_IN_MEMORY_URL).anyTimes(); + expect(dbAccessor.getConnection()).andReturn(connection); + expect(connection.createStatement()).andReturn(statement); + expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet); replay(dbAccessor); - + Module module = new Module() { + @Override + public void configure(Binder binder) { + binder.bind(DBAccessor.class).toInstance(dbAccessor); + binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); + binder.bind(EntityManager.class).toInstance(entityManager); + } + }; + + Injector injector = Guice.createInjector(module); + UpgradeCatalog240 upgradeCatalog240 = injector.getInstance(UpgradeCatalog240.class); upgradeCatalog240.executeDDLUpdates(); - verify(dbAccessor); - DBAccessor.DBColumnInfo columnInfo = capturedColumnInfo.getValue(); Assert.assertNotNull(columnInfo); Assert.assertEquals(UpgradeCatalog240.SORT_ORDER_COL, columnInfo.getName()); @@ -111,12 +135,29 @@ public class UpgradeCatalog240Test { Assert.assertEquals(Short.class, columnInfo.getType()); Assert.assertEquals(1, columnInfo.getDefaultValue()); Assert.assertEquals(false, columnInfo.isNullable()); + + Map<String, Class> expectedCaptures = new HashMap<>(); + expectedCaptures.put("id", Long.class); + expectedCaptures.put("name", String.class); + expectedCaptures.put("setting_type", String.class); + expectedCaptures.put("content", String.class); + expectedCaptures.put("updated_by", String.class); + expectedCaptures.put("update_timestamp", Long.class); + + Map<String, Class> actualCaptures = new HashMap<>(); + for(DBAccessor.DBColumnInfo settingColumnInfo : capturedSettingColumns.getValue()) { + actualCaptures.put(settingColumnInfo.getName(), settingColumnInfo.getType()); + } + assertEquals(expectedCaptures, actualCaptures); + + verify(dbAccessor); } @Test public void testExecuteDMLUpdates() throws Exception { Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml"); Method updateAlerts = UpgradeCatalog240.class.getDeclaredMethod("updateAlerts"); + Method addSettingPermission = UpgradeCatalog240.class.getDeclaredMethod("addSettingPermission"); Capture<String> capturedStatements = newCapture(CaptureType.ALL); @@ -126,15 +167,15 @@ public class UpgradeCatalog240Test { UpgradeCatalog240 upgradeCatalog240 = createMockBuilder(UpgradeCatalog240.class) .addMockedMethod(addNewConfigurationsFromXml) .addMockedMethod(updateAlerts) + .addMockedMethod(addSettingPermission) .createMock(); Field field = AbstractUpgradeCatalog.class.getDeclaredField("dbAccessor"); field.set(upgradeCatalog240, dbAccessor); upgradeCatalog240.addNewConfigurationsFromXml(); - expectLastCall().once(); upgradeCatalog240.updateAlerts(); - expectLastCall().once(); + upgradeCatalog240.addSettingPermission(); replay(upgradeCatalog240, dbAccessor); @@ -171,11 +212,10 @@ public class UpgradeCatalog240Test { UpgradeCatalog240 upgradeCatalog240 = new UpgradeCatalog240(injector); String inputSource = "{\"path\":\"test_path\",\"type\":\"SCRIPT\",\"parameters\":[{\"name\":\"connection.timeout\",\"display_name\":\"Connection Timeout\",\"value\":5.0,\"type\":\"NUMERIC\",\"description\":\"The maximum time before this alert is considered to be CRITICAL\",\"units\":\"seconds\",\"threshold\":\"CRITICAL\"}]}"; - List<String> params = new ArrayList<String>(Arrays.asList("connection.timeout", "checkpoint.time.warning.threshold", "checkpoint.time.critical.threshold")); + List<String> params = new ArrayList<>(Arrays.asList("connection.timeout", "checkpoint.time.warning.threshold", "checkpoint.time.critical.threshold")); String expectedSource = "{\"path\":\"test_path\",\"type\":\"SCRIPT\",\"parameters\":[{\"name\":\"connection.timeout\",\"display_name\":\"Connection Timeout\",\"value\":5.0,\"type\":\"NUMERIC\",\"description\":\"The maximum time before this alert is considered to be CRITICAL\",\"units\":\"seconds\",\"threshold\":\"CRITICAL\"},{\"name\":\"checkpoint.time.warning.threshold\",\"display_name\":\"Checkpoint Warning\",\"value\":2.0,\"type\":\"PERCENT\",\"description\":\"The percentage of the last checkpoint time greater than the interval in order to trigger a warning alert.\",\"units\":\"%\",\"threshold\":\"WARNING\"},{\"name\":\"checkpoint.time.critical.threshold\",\"display_name\":\"Checkpoint Critical\",\"value\":2.0,\"type\":\"PERCENT\",\"description\":\"The percentage of the last checkpoint time greater than the interval in order to trigger a critical alert.\",\"units\":\"%\",\"threshold\":\"CRITICAL\"}]}"; String result = upgradeCatalog240.addParam(inputSource, params); Assert.assertEquals(result, expectedSource); } - }
