You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by vb...@apache.org on 2018/01/25 01:04:48 UTC
[ambari] branch branch-feature-AMBARI-14714 updated: [AMBARI-22817]
Update backend code to handle new versioning schema. (#155)
This is an automated email from the ASF dual-hosted git repository.
vbrodetskyi pushed a commit to branch branch-feature-AMBARI-14714
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by this push:
new 80d840e [AMBARI-22817] Update backend code to handle new versioning schema. (#155)
80d840e is described below
commit 80d840e5d50614a0f148a650c9bfc7d21363a218
Author: vbrodetskyi <vb...@cybervisiontech.com>
AuthorDate: Thu Jan 25 03:04:45 2018 +0200
[AMBARI-22817] Update backend code to handle new versioning schema. (#155)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
* AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi)
---
.../libraries/functions/module_version.py | 158 ++++++++++++++++
.../libraries/functions/mpack_version.py | 207 +++++++++++++++++++++
.../apache/ambari/server/utils/ModuleVersion.java | 162 ++++++++++++++++
.../apache/ambari/server/utils/MpackVersion.java | 197 ++++++++++++++++++++
.../ambari/server/utils/TestVersionUtils.java | 142 ++++++++++++++
ambari-server/src/test/python/TestVersion.py | 100 +++++++++-
6 files changed, 964 insertions(+), 2 deletions(-)
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py b/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py
new file mode 100644
index 0000000..6ec4ba3
--- /dev/null
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py
@@ -0,0 +1,158 @@
+"""
+ 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.
+"""
+
+import re
+
+"""
+ This class should be used to compare module(service) versions.
+ Base method which should be used is parse(..), This method will validate and parse
+ version which you will pass as parameter, and return object of current class with
+ parsed version. Same thing you should do with another version, with which you are
+ planning to compare previous one. After that, use "==", "<", ">" to get final result.
+"""
+class ModuleVersion(object):
+ __module_version_pattern = "(?P<aMajor>[0-9]+).(?P<aMinor>[0-9]+).(?P<iMinor>[0-9]+).(?P<iMaint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)"
+ __module_version_regex = re.compile(__module_version_pattern)
+
+ def __init__(self, apache_major, apache_minor, internal_minor, internal_maint, hotfix, build):
+ """
+ :type apache_major int
+ :type apache_minor int
+ :type internal_maint int
+ :type internal_minor int
+ :type hotfix int
+ :type build int
+ """
+ self.__apache_major = int(apache_major)
+ self.__apache_minor = int(apache_minor)
+ self.__internal_maint = int(internal_maint)
+ self.__internal_minor = int(internal_minor)
+ self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group
+ self.__build = int(build)
+
+ def __repr__(self):
+ return "{0}.{1}.{2}.{3}-h{4}-b{5}".format(*self.to_list())
+
+ def to_list(self):
+ """
+ Return version elements as list
+
+ :rtype list
+ """
+ return [
+ self.__apache_major,
+ self.__apache_minor,
+ self.__internal_minor,
+ self.__internal_maint,
+ self.__hotfix,
+ self.__build
+ ]
+
+ def __cmp__(self, other):
+ """
+ :type other ModuleVersion
+
+ :raise TypeError
+ """
+ if other and not isinstance(other, self.__class__):
+ raise TypeError("Operand type is different from {0}".format(self.__class__.__name__))
+
+ r = 0
+ x = self.to_list()
+ y = other.to_list()
+
+ for i in range(0, len(x)):
+ r = x[i] - y[i]
+ if r != 0:
+ break
+
+ return 1 if r > 0 else -1 if r < 0 else 0
+
+ @classmethod
+ def parse(cls, module_version):
+ """
+ Parse string to module version
+
+ :type module_version str
+ :rtype ModuleVersion
+ """
+ matcher = cls.validate(module_version)
+ return ModuleVersion(
+ matcher.group("aMajor"),
+ matcher.group("aMinor"),
+ matcher.group("iMinor"),
+ matcher.group("iMaint"),
+ matcher.group("hotfix"),
+ matcher.group("build")
+ )
+
+ @classmethod
+ def validate(cls, module_version):
+ """
+ Check if provided version is valid. If version is valid will return match object
+ or will raise exception.
+
+ :param module_version version to check
+ :type module_version str
+
+ :rtype __Match[T] | None
+
+ :raise ValueError
+ """
+
+ if not module_version:
+ raise ValueError("Module version can't be empty or null")
+
+ version = module_version.strip()
+
+ if not version:
+ raise ValueError("Module version can't be empty or null")
+
+ matcher = cls.__module_version_regex.match(version)
+
+ if not matcher:
+ raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))
+
+ return matcher
+
+ @property
+ def apache_major(self):
+ return self.__apache_major
+
+ @property
+ def apache_minor(self):
+ return self.__apache_minor
+
+ @property
+ def internal_minor(self):
+ return self.__internal_minor
+
+ @property
+ def internal_maint(self):
+ return self.__internal_maint
+
+ @property
+ def hotfix(self):
+ return self.__hotfix
+
+ @property
+ def build(self):
+ return self.__build
+
+
+
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py
new file mode 100644
index 0000000..664f9fe
--- /dev/null
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py
@@ -0,0 +1,207 @@
+"""
+ 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.
+"""
+
+import re
+
+"""
+ This class should be used to compare mpack and stack versions.
+ Base method which should be used is parse/parse_stack_version, depends
+ on which versions you want to compare. This method will validate and parse
+ version which you will pass as parameter, and return object of current class with
+ parsed version. Same thing you should do with another version, with which you are
+ planning to compare previous one. After that, use "==", ">", "<" to get final result.
+"""
+class MpackVersion(object):
+ __mpack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)"
+ __mpack_legacy_stack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+).(?P<hotfix>[0-9]+)(-(?P<build>[0-9]+))"
+ __mpack_version_regex = re.compile(__mpack_version_pattern)
+ __mpack_legacy_stack_version_regex = re.compile(__mpack_legacy_stack_version_pattern)
+
+ def __init__(self, major, minor, maint, hotfix, build):
+ """
+ :type major int
+ :type minor int
+ :type maint int
+ :type hotfix int
+ :type build int
+ """
+ self.__major = int(major)
+ self.__minor = int(minor)
+ self.__maint = int(maint)
+ self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group
+ self.__build = int(build)
+
+ def __repr__(self):
+ return "{0}.{1}.{2}-h{3}-b{4}".format(*self.to_list())
+
+ def to_list(self):
+ """
+ Return version elements as list
+
+ :rtype list
+ """
+ return [
+ self.__major,
+ self.__minor,
+ self.__maint,
+ self.__hotfix,
+ self.__build
+ ]
+
+ def __cmp__(self, other):
+ """
+ :type other MpackVersion
+
+ :raise TypeError
+ """
+ if other and not isinstance(other, self.__class__):
+ raise TypeError("Operand type is different from {0}".format(self.__class__.__name__))
+
+ r = 0
+ x = self.to_list()
+ y = other.to_list()
+
+ for i in range(0, len(x)):
+ r = x[i] - y[i]
+ if r != 0:
+ break
+
+ return 1 if r > 0 else -1 if r < 0 else 0
+
+ @classmethod
+ def parse(cls, mpack_version):
+ """
+ Parse string to mpack version
+
+ :type mpack_version str
+ :rtype MpackVersion
+ """
+ matcher = cls.validate(mpack_version)
+ return MpackVersion(
+ matcher.group("major"),
+ matcher.group("minor"),
+ matcher.group("maint"),
+ matcher.group("hotfix"),
+ matcher.group("build")
+ )
+
+
+ @classmethod
+ def parse_stack_version(cls, stack_version):
+ """
+ Parse string to mpack version
+
+ :type stack_version str
+ :rtype MpackVersion
+ """
+ matcher = cls.validate_stack_version(stack_version)
+ return MpackVersion(
+ matcher.group("major"),
+ matcher.group("minor"),
+ matcher.group("maint"),
+ matcher.group("hotfix"),
+ matcher.group("build")
+ )
+
+
+ @classmethod
+ def validate_stack_version(cls, stack_version):
+ """
+ Check if provided version is valid. If version is valid will return match object
+ or will raise exception.
+
+ :param stack_version version to check
+ :type stack_version str
+
+ :rtype __Match[T] | None
+
+ :raise ValueError
+ """
+
+ if not stack_version:
+ raise ValueError("Module version can't be empty or null")
+
+ version = stack_version.strip()
+
+ if not version:
+ raise ValueError("Module version can't be empty or null")
+
+ matcher = cls.__mpack_version_regex.match(version)
+
+ if not matcher:
+ matcher = cls.__mpack_legacy_stack_version_regex.match(version)
+ if not matcher:
+ raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))
+ else:
+ if not matcher.group("hotfix"):
+ raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))
+
+ return matcher
+
+
+ @classmethod
+ def validate(cls, mpack_version):
+ """
+ Check if provided version is valid. If version is valid will return match object
+ or will raise exception.
+
+ :param module_version version to check
+ :type module_version str
+
+ :rtype __Match[T] | None
+
+ :raise ValueError
+ """
+
+ if not mpack_version:
+ raise ValueError("Module version can't be empty or null")
+
+ version = mpack_version.strip()
+
+ if not version:
+ raise ValueError("Module version can't be empty or null")
+
+ matcher = cls.__mpack_version_regex.match(version)
+
+ if not matcher:
+ raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))
+
+ return matcher
+
+ @property
+ def major(self):
+ return self.__major
+
+ @property
+ def minor(self):
+ return self.__minor
+
+ @property
+ def maint(self):
+ return self.__maint
+
+ @property
+ def hotfix(self):
+ return self.__hotfix
+
+ @property
+ def build(self):
+ return self.__build
+
+
+
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java
new file mode 100644
index 0000000..520eac7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java
@@ -0,0 +1,162 @@
+/*
+ * 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.utils;
+
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * This class should be used to compare module(service) versions.
+ * Base method which should be used is parse(..), This method will validate and parse
+ * version which you will pass as parameter, and return object of current class with
+ * parsed version. Same thing you should do with another version, with which you are
+ * planning to compare previous one. After that, use method compare to get final result.
+ */
+
+public class ModuleVersion implements Comparable<ModuleVersion> {
+
+ // RE for different version formats like N.N.N.N-bN, N.N.N-hN-bN
+ private static final String VERSION_WITH_HOTFIX_AND_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-h([0-9]+)-b([0-9]+)";
+ private static final String VERSION_WITH_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-b([0-9]+)";
+
+ // Patterns for previous RE
+ private static final Pattern PATTERN_WITH_HOTFIX = Pattern.compile(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN);
+ private static final Pattern PATTERN_WITHOUT_HOTFIX = Pattern.compile(VERSION_WITH_BUILD_PATTERN);
+
+ // Parts of version
+ private int apacheMajor;
+ private int apacheMinor;
+ private int internalMinor;
+ private int internalMaint;
+ private int hotfix;
+ private int build;
+
+
+ public ModuleVersion(int apacheMajor, int apacheMinor, int internalMinor, int internalMaint, int hotfix, int build) {
+ this.apacheMajor = apacheMajor;
+ this.apacheMinor = apacheMinor;
+ this.internalMinor = internalMinor;
+ this.internalMaint = internalMaint;
+ this.hotfix = hotfix;
+ this.build = build;
+ }
+
+ /**
+ * Method which will parse module version
+ * which user passed as parameter. Also
+ * in this method version will be validated.
+ * @param moduleVersion string
+ * @return MpackVersion instance which contains parsed version
+ * */
+ public static ModuleVersion parse(String moduleVersion) {
+ Matcher versionMatcher = validateModuleVersion(moduleVersion);
+ ModuleVersion result = null;
+
+ if (versionMatcher.pattern().pattern().equals(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN)) {
+ result = new ModuleVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+ Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)),
+ Integer.parseInt(versionMatcher.group(5)), Integer.parseInt(versionMatcher.group(6)));
+
+ } else {
+ result = new ModuleVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+ Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), 0,
+ Integer.parseInt(versionMatcher.group(5)));
+
+ }
+
+ return result;
+ }
+
+ /**
+ * Method validate module version not to be
+ * empty or null. Also check if passed version
+ * has valid format.
+ * @param version string
+ * @return Matcher for passed version
+ * @throws IllegalArgumentException() if version empty/null/not valid
+ */
+ private static Matcher validateModuleVersion(String version) {
+ if (StringUtils.isEmpty(version)) {
+ throw new IllegalArgumentException("Module version can't be empty or null");
+ }
+
+ String moduleVersion = StringUtils.trim(version);
+
+ Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(moduleVersion);
+ if (!versionMatcher.find()) {
+ versionMatcher = PATTERN_WITHOUT_HOTFIX.matcher(moduleVersion);
+ if (!versionMatcher.find()) {
+ throw new IllegalArgumentException("Wrong format for module version, should be N.N.N.N-bN or N.N.N-hN-bN");
+ }
+ }
+
+ return versionMatcher;
+ }
+
+ @Override
+ public int compareTo(ModuleVersion other) {
+ int result = this.apacheMajor - other.apacheMajor;
+ if(result == 0) {
+ result = this.apacheMinor - other.apacheMinor;
+ if(result == 0) {
+ result = this.internalMinor - other.internalMinor;
+ if(result == 0) {
+ result = this.internalMaint - other.internalMaint;
+ if(result == 0) {
+ result = this.hotfix - other.hotfix;
+ if(result == 0) {
+ result = this.build - other.build;
+ }
+ }
+ }
+ }
+ }
+ return result > 0 ? 1 : result < 0 ? -1 : 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ModuleVersion that = (ModuleVersion) o;
+
+ if (apacheMajor != that.apacheMajor) return false;
+ if (apacheMinor != that.apacheMinor) return false;
+ if (build != that.build) return false;
+ if (hotfix != that.hotfix) return false;
+ if (internalMaint != that.internalMaint) return false;
+ if (internalMinor != that.internalMinor) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = apacheMajor;
+ result = 31 * result + apacheMinor;
+ result = 31 * result + internalMinor;
+ result = 31 * result + internalMaint;
+ result = 31 * result + hotfix;
+ result = 31 * result + build;
+ return result;
+ }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java
new file mode 100644
index 0000000..ad3fdc8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java
@@ -0,0 +1,197 @@
+/*
+ * 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.utils;
+
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * This class should be used to compare mpack and stack versions.
+ * Base method which should be used is parse/parseStackVersion, depends
+ * on which versions you want to compare. This method will validate and parse
+ * version which you will pass as parameter, and return object of current class with
+ * parsed version. Same thing you should do with another version, with which you are
+ * planning to compare previous one. After that, use method compare to get final result.
+ */
+
+public class MpackVersion implements Comparable<MpackVersion> {
+
+ // RE for different version formats like N.N.N-hN-bN, N.N.N-bN, N.N.N.N-N
+ private final static String VERSION_WITH_HOTFIX_AND_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-h([0-9]+)-b([0-9]+)";
+ private final static String VERSION_WITH_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-b([0-9]+)";
+ private final static String LEGACY_STACK_VERSION_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-([0-9]+)";
+
+ // Patterns for previous RE
+ private final static Pattern PATTERN_WITH_HOTFIX = Pattern.compile(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN);
+ private final static Pattern PATTERN_LEGACY_STACK_VERSION = Pattern.compile(LEGACY_STACK_VERSION_PATTERN);
+ private final static Pattern PATTERN_WITHOUT_HOTFIX = Pattern.compile(VERSION_WITH_BUILD_PATTERN);
+
+ // Parts of version
+ private int major;
+ private int minor;
+ private int maint;
+ private int hotfix;
+ private int build;
+
+
+ public MpackVersion(int major, int minor, int maint, int hotfix, int build) {
+ this.major = major;
+ this.minor = minor;
+ this.maint = maint;
+ this.hotfix = hotfix;
+ this.build = build;
+ }
+
+ /**
+ * Method which will parse mpack version
+ * which user passed as parameter. Also
+ * in this method version will be validated.
+ * @param mpackVersion string
+ * @return MpackVersion instance which contains parsed version
+ * */
+ public static MpackVersion parse(String mpackVersion) {
+ Matcher versionMatcher = validateMpackVersion(mpackVersion);
+ MpackVersion result = null;
+
+ if (versionMatcher.pattern().pattern().equals(VERSION_WITH_BUILD_PATTERN)) {
+ result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+ Integer.parseInt(versionMatcher.group(3)), 0, Integer.parseInt(versionMatcher.group(4)));
+
+ } else {
+ result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+ Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5)));
+
+ }
+
+ return result;
+ }
+
+ /**
+ * Method which will parse stack version
+ * which user passed as parameter. Also
+ * in this method version will be validated.
+ * @param stackVersion string
+ * @return MpackVersion instance which contains parsed version
+ * */
+ public static MpackVersion parseStackVersion(String stackVersion) {
+ Matcher versionMatcher = validateStackVersion(stackVersion);
+ MpackVersion result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+ Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5)));
+
+ return result;
+ }
+
+ /**
+ * Method validate stack version not to be
+ * empty or null. Also check if passed version
+ * has valid format.
+ * @param version string
+ * @return Matcher for passed version
+ * @throws IllegalArgumentException() if version empty/null/not valid
+ */
+ private static Matcher validateStackVersion(String version) {
+ if (StringUtils.isEmpty(version)) {
+ throw new IllegalArgumentException("Stack version can't be empty or null");
+ }
+
+ String stackVersion = StringUtils.trim(version);
+
+ Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(stackVersion);
+ if (!versionMatcher.find()) {
+ versionMatcher = PATTERN_LEGACY_STACK_VERSION.matcher(stackVersion);
+ if (!versionMatcher.find()) {
+ throw new IllegalArgumentException("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN");
+ }
+ }
+
+ return versionMatcher;
+ }
+
+ /**
+ * Method validate mpack version not to be
+ * empty or null. Also check if passed version
+ * has valid format.
+ * @param version string
+ * @return Matcher for passed version
+ * @throws IllegalArgumentException() if version empty/null/not valid
+ */
+ private static Matcher validateMpackVersion(String version) {
+ if (StringUtils.isEmpty(version)) {
+ throw new IllegalArgumentException("Mpack version can't be empty or null");
+ }
+
+ String mpackVersion = StringUtils.trim(version);
+
+ Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(mpackVersion);
+ if (!versionMatcher.find()) {
+ versionMatcher = PATTERN_WITHOUT_HOTFIX.matcher(mpackVersion);
+ if (!versionMatcher.find()) {
+ throw new IllegalArgumentException("Wrong format for mpack version, should be N.N.N-bN or N.N.N-hN-bN");
+ }
+ }
+
+ return versionMatcher;
+ }
+
+ @Override
+ public int compareTo(MpackVersion other) {
+ int result = this.major - other.major;
+ if(result == 0) {
+ result = this.minor - other.minor;
+ if(result == 0) {
+ result = this.maint - other.maint;
+ if(result == 0) {
+ result = this.hotfix - other.hotfix;
+ if(result == 0) {
+ result = this.build - other.build;
+ }
+ }
+ }
+ }
+ return result > 0 ? 1 : result < 0 ? -1 : 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MpackVersion that = (MpackVersion) o;
+
+ if (build != that.build) return false;
+ if (hotfix != that.hotfix) return false;
+ if (maint != that.maint) return false;
+ if (major != that.major) return false;
+ if (minor != that.minor) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = major;
+ result = 31 * result + minor;
+ result = 31 * result + maint;
+ result = 31 * result + hotfix;
+ result = 31 * result + build;
+ return result;
+ }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 42d321a..08c0a06 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -26,6 +26,10 @@ import junit.framework.Assert;
public class TestVersionUtils {
+ private static final String MODULE_ERR_MESSAGE = "Module version can't be empty or null";
+ private static final String STACK_ERR_MESSAGE = "Stack version can't be empty or null";
+ private static final String MPACK_ERR_MESSAGE = "Mpack version can't be empty or null";
+
@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -168,4 +172,142 @@ public class TestVersionUtils {
expectedException.expectMessage("maxLengthToCompare cannot be less than 0");
VersionUtils.compareVersions("2", "1", -1);
}
+
+ @Test
+ public void testMpackVersionWithNotValidVersions() {
+ String errMessage = null;
+ try {
+ MpackVersion.parse(null);
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(MPACK_ERR_MESSAGE, errMessage);
+
+
+ try {
+ errMessage = null;
+ MpackVersion.parse("");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(MPACK_ERR_MESSAGE, errMessage);
+
+ try {
+ errMessage = null;
+ MpackVersion.parse("1.2.3.4-b10");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals("Wrong format for mpack version, should be N.N.N-bN or N.N.N-hN-bN", errMessage);
+ }
+
+
+ @Test
+ public void testStackVersionWithNotValidVersions() {
+ String errMessage = null;
+ try {
+ errMessage = null;
+ MpackVersion.parseStackVersion(null);
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(STACK_ERR_MESSAGE, errMessage);
+
+
+ try {
+ errMessage = null;
+ MpackVersion.parseStackVersion("");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(STACK_ERR_MESSAGE, errMessage);
+
+ try {
+ errMessage = null;
+ MpackVersion.parseStackVersion("1.2.3-10");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN", errMessage);
+ }
+
+
+ @Test
+ public void testModuleVersionWithNotValidVersions() {
+ String errMessage = null;
+ try {
+ errMessage = null;
+ ModuleVersion.parse(null);
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(MODULE_ERR_MESSAGE, errMessage);
+
+
+ try {
+ errMessage = null;
+ ModuleVersion.parse("");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals(MODULE_ERR_MESSAGE, errMessage);
+
+
+ try {
+ errMessage = null;
+ ModuleVersion.parse("1.2.3-10");
+ } catch (IllegalArgumentException e) {
+ errMessage = e.getMessage();
+ }
+ Assert.assertEquals("Wrong format for module version, should be N.N.N.N-bN or N.N.N-hN-bN", errMessage);
+ }
+
+ @Test
+ public void testMpackVersionWithValidVersions() {
+ Assert.assertEquals(1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parse("1.2.3-b888")));
+ Assert.assertEquals(1, MpackVersion.parse("2.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888")));
+ Assert.assertEquals(1, MpackVersion.parse("1.3.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888")));
+ Assert.assertEquals(1, MpackVersion.parse("1.2.4-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888")));
+ Assert.assertEquals(1, MpackVersion.parse("1.2.3-h0-b1000").compareTo(MpackVersion.parse("1.2.3-b888")));
+ Assert.assertEquals(0, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b10")));
+ Assert.assertEquals(0, MpackVersion.parse("1.2.3-b10").compareTo(MpackVersion.parse("1.2.3-b10")));
+ Assert.assertEquals(0, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h0-b10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.4-b10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.3.3-b10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("2.2.3-b10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h1-b10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h0-b11")));
+ }
+
+ @Test
+ public void testStackVersionWithValidVersions() {
+ Assert.assertEquals(1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+ Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.11-888")));
+ Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3.4-999").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+ Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3-h10-b10")));
+ Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.10-10")));
+ Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("2.2.3.4-888")));
+ }
+
+ @Test
+ public void testModuleVersionWithValidVersions() {
+ Assert.assertEquals(1, ModuleVersion.parse("1.2.3.4-h10-b888").compareTo(ModuleVersion.parse("1.2.3.4-b888")));
+ Assert.assertEquals(1, ModuleVersion.parse("1.2.3.5-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(1, ModuleVersion.parse("1.2.4.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(1, ModuleVersion.parse("1.3.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(1, ModuleVersion.parse("2.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(1, ModuleVersion.parse("1.2.3.4-h0-b11").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+
+ Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-h0-b10")));
+ Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10")));
+ Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-b10").compareTo(ModuleVersion.parse("1.2.3.4-h0-b10")));
+
+ Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b888")));
+ Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.5-b10")));
+ Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.4.4-b10")));
+ Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.3.3.4-b10")));
+ Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("2.2.3.4-b10")));
+ }
}
diff --git a/ambari-server/src/test/python/TestVersion.py b/ambari-server/src/test/python/TestVersion.py
index a8f4c65..0b66478 100644
--- a/ambari-server/src/test/python/TestVersion.py
+++ b/ambari-server/src/test/python/TestVersion.py
@@ -16,8 +16,10 @@ See the License for the specific language governing permissions and
limitations under the License.
'''
-from unittest import TestCase
import os
+from unittest import TestCase
+from resource_management.libraries.functions.mpack_version import MpackVersion
+from resource_management.libraries.functions.module_version import ModuleVersion
class TestVersion(TestCase):
@@ -80,4 +82,98 @@ class TestVersion(TestCase):
except ValueError:
pass
else:
- self.fail("Did not raise exception")
\ No newline at end of file
+ self.fail("Did not raise exception")
+
+
+ def test_mpack_version(self):
+ try:
+ MpackVersion.parse("")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ MpackVersion.parse(None)
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ MpackVersion.parse_stack_version("")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ MpackVersion.parse_stack_version(None)
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ ModuleVersion.parse("")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ ModuleVersion.parse(None)
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+
+ try:
+ MpackVersion.parse("1.2.3.4-h1-b1")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ try:
+ MpackVersion.parse_stack_version("1.1.1.1.1-1")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+
+ try:
+ ModuleVersion.parse("1.1.1.1-h1")
+ except ValueError:
+ pass
+ else:
+ self.fail("Did not raise exception")
+
+ m1 = MpackVersion.parse("1.2.3-h1-b2")
+ m2 = MpackVersion.parse("1.2.3-b2")
+ self.assertTrue(m1 > m2)
+
+ m1 = MpackVersion.parse("1.2.3-h1-b2")
+ m2 = MpackVersion.parse_stack_version("1.2.3.4-33")
+ self.assertTrue(m1 < m2)
+
+ m1 = MpackVersion.parse("1.2.3-h0-b10")
+ m2 = MpackVersion.parse("1.2.3-b10")
+ self.assertTrue(m1 == m2)
+
+ m1 = ModuleVersion.parse("1.2.3.4-h10-b10")
+ m2 = ModuleVersion.parse("1.2.3.4-b888")
+ self.assertTrue(m1 > m2)
+
+ m1 = ModuleVersion.parse("1.2.3.5-h10-b10")
+ m2 = ModuleVersion.parse("1.2.3.4-b888")
+ self.assertTrue(m1 > m2)
+
+ m1 = ModuleVersion.parse("1.2.3.4-h0-b10")
+ m2 = ModuleVersion.parse("1.2.3.4-b10")
+ self.assertTrue(m1 == m2)
+
+
+
--
To stop receiving notification emails like this one, please contact
vbrodetskyi@apache.org.