AMBARI-18858. Disallow Ambari upgrade for versions less than exiting upgrade catalogs (dgrinenko via dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9dfb7e92 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9dfb7e92 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9dfb7e92 Branch: refs/heads/branch-feature-AMBARI-18634 Commit: 9dfb7e9231107d78503f7699ad8e49e549fbf81e Parents: 24f1eb6 Author: Lisnichenko Dmitro <[email protected]> Authored: Mon Nov 14 12:09:19 2016 +0200 Committer: Lisnichenko Dmitro <[email protected]> Committed: Mon Nov 14 12:09:56 2016 +0200 ---------------------------------------------------------------------- .../server/upgrade/SchemaUpgradeHelper.java | 43 ++++- .../server/upgrade/SchemaUpgradeHelperTest.java | 163 +++++++++++++++++++ 2 files changed, 204 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/9dfb7e92/ambari-server/src/main/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelper.java index 10f9ed3..28e374b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelper.java @@ -137,8 +137,8 @@ public class SchemaUpgradeHelper { */ protected List<UpgradeCatalog> getUpgradePath(String sourceVersion, String targetVersion) throws AmbariException { - List<UpgradeCatalog> upgradeCatalogs = new ArrayList<UpgradeCatalog>(); - List<UpgradeCatalog> candidateCatalogs = new ArrayList<UpgradeCatalog>(allUpgradeCatalogs); + List<UpgradeCatalog> upgradeCatalogs = new ArrayList<>(); + List<UpgradeCatalog> candidateCatalogs = new ArrayList<>(allUpgradeCatalogs); Collections.sort(candidateCatalogs, new AbstractUpgradeCatalog.VersionComparator()); @@ -317,6 +317,38 @@ public class SchemaUpgradeHelper { } } + /** + * Returns minimal version of available {@link UpgradeCatalog} + * + * @return string representation of minimal version of {@link UpgradeCatalog} + */ + private String getMinimalUpgradeCatalogVersion(){ + List<UpgradeCatalog> candidateCatalogs = new ArrayList<>(allUpgradeCatalogs); + Collections.sort(candidateCatalogs, new AbstractUpgradeCatalog.VersionComparator()); + + if (candidateCatalogs.isEmpty()) { + return null; + } + + return candidateCatalogs.iterator().next().getTargetVersion(); + } + + /** + * Checks if source version meets minimal requirements for upgrade + * + * @param minUpgradeVersion min allowed version for the upgrade, could be obtained via {@link SchemaUpgradeHelper.getMinimalUpgradeCatalogVersion} + * @param sourceVersion current version of the Database, which need to be upgraded + * + * @return true if upgrade is allowed or false if not + */ + private boolean verifyUpgradePath(String minUpgradeVersion, String sourceVersion){ + if (null == minUpgradeVersion){ + return false; + } + + return VersionUtils.compareVersions(sourceVersion, minUpgradeVersion) >= 0; + } + /** * Upgrade Ambari DB schema to the target version passed in as the only @@ -349,6 +381,13 @@ public class SchemaUpgradeHelper { String sourceVersion = schemaUpgradeHelper.readSourceVersion(); LOG.info("Upgrading schema from source version = " + sourceVersion); + String minimalRequiredUpgradeVersion = schemaUpgradeHelper.getMinimalUpgradeCatalogVersion(); + + if (!schemaUpgradeHelper.verifyUpgradePath(minimalRequiredUpgradeVersion, sourceVersion)){ + throw new AmbariException(String.format("Database version does not meet minimal upgrade requirements. Expected version should be not less than %s, current version is %s", + minimalRequiredUpgradeVersion, sourceVersion)); + } + List<UpgradeCatalog> upgradeCatalogs = schemaUpgradeHelper.getUpgradePath(sourceVersion, targetVersion); http://git-wip-us.apache.org/repos/asf/ambari/blob/9dfb7e92/ambari-server/src/test/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelperTest.java new file mode 100644 index 0000000..937fea0 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/SchemaUpgradeHelperTest.java @@ -0,0 +1,163 @@ +/* + * 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.upgrade; + +import java.lang.reflect.Method; +import java.sql.SQLException; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.utils.EventBusSynchronizer; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.multibindings.Multibinder; + +/** + * Base Test Upgrade Catalog class + */ +abstract class TestUpgradeCatalog extends AbstractUpgradeCatalog{ + + @Inject + public TestUpgradeCatalog(Injector injector) { + super(injector); + } + + @Override + protected void executeDDLUpdates() throws AmbariException, SQLException { + // no op + } + + @Override + protected void executePreDMLUpdates() throws AmbariException, SQLException { + // no op + } + + @Override + protected void executeDMLUpdates() throws AmbariException, SQLException { + // no op + } +} + +/** + * Sample Upgrade Catalog version 1.0 + */ +class TestUpgradeCatalog10 extends TestUpgradeCatalog { + + @Inject + public TestUpgradeCatalog10(Injector injector) { + super(injector); + } + + @Override + public String getTargetVersion() { + return "0.1.0"; + } +} + +/** + * Sample Upgrade Catalog version 2.0 + */ +class TestUpgradeCatalog20 extends TestUpgradeCatalog { + + @Inject + public TestUpgradeCatalog20(Injector injector) { + super(injector); + } + + @Override + public String getTargetVersion() { + return "0.2.0"; + } +} + +/** + * Sample Upgrade Catalog version 3.0 + */ +class TestUpgradeCatalog30 extends TestUpgradeCatalog { + + @Inject + public TestUpgradeCatalog30(Injector injector) { + super(injector); + } + + @Override + public String getTargetVersion() { + return "0.3.0"; + } +} + + +class UpgradeHelperTestModule extends InMemoryDefaultTestModule { + + UpgradeHelperTestModule() { + } + + @Override + protected void configure() { + super.configure(); + + Multibinder<UpgradeCatalog> catalogBinder = + Multibinder.newSetBinder(binder(), UpgradeCatalog.class); + catalogBinder.addBinding().to(TestUpgradeCatalog10.class); + catalogBinder.addBinding().to(TestUpgradeCatalog20.class); + catalogBinder.addBinding().to(TestUpgradeCatalog30.class); + + EventBusSynchronizer.synchronizeAmbariEventPublisher(binder()); + } +} + +/** + * Test class for {@link SchemaUpgradeHelper} + */ +public class SchemaUpgradeHelperTest { + + private SchemaUpgradeHelper schemaUpgradeHelper; + + @Before + public void init(){ + Injector injector = Guice.createInjector(new UpgradeHelperTestModule()); + schemaUpgradeHelper = injector.getInstance(SchemaUpgradeHelper.class); + } + + @Test + public void testGetMinimalUpgradeCatalogVersion() throws Exception{ + Method getMinimalUpgradeCatalogVersion = schemaUpgradeHelper.getClass().getDeclaredMethod("getMinimalUpgradeCatalogVersion"); + getMinimalUpgradeCatalogVersion.setAccessible(true); + String s = (String)getMinimalUpgradeCatalogVersion.invoke(schemaUpgradeHelper); + + Assert.assertEquals("0.1.0", s); + } + + @Test + public void testVerifyUpgradePath() throws Exception{ + Method verifyUpgradePath = schemaUpgradeHelper.getClass().getDeclaredMethod("verifyUpgradePath", String.class, String.class); + verifyUpgradePath.setAccessible(true); + + boolean failToVerify = (boolean)verifyUpgradePath.invoke(schemaUpgradeHelper, "0.3.0", "0.2.0"); + boolean verifyPassed = (boolean)verifyUpgradePath.invoke(schemaUpgradeHelper, "0.1.0", "0.2.0"); + + Assert.assertTrue(verifyPassed); + Assert.assertFalse(failToVerify); + } + +}
