| /* |
| * 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.tephra.util; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.lang.reflect.Method; |
| import java.text.ParseException; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| /** |
| * Detects the currently loaded HBase version. It is assumed that only one HBase version is loaded at a time, |
| * since using more than one HBase version within the same process will require classloader isolation anyway. |
| */ |
| public class HBaseVersion { |
| private static final String HBASE_94_VERSION = "0.94"; |
| private static final String HBASE_96_VERSION = "0.96"; |
| private static final String HBASE_98_VERSION = "0.98"; |
| private static final String HBASE_10_VERSION = "1.0"; |
| private static final String HBASE_11_VERSION = "1.1"; |
| private static final String HBASE_12_VERSION = "1.2"; |
| private static final String HBASE_13_VERSION = "1.3"; |
| private static final String HBASE_14_VERSION = "1.4"; |
| private static final String HBASE_15_VERSION = "1.5"; |
| private static final String HBASE_16_VERSION = "1.6"; |
| private static final String HBASE_20_VERSION = "2.0"; |
| private static final String HBASE_21_VERSION = "2.1"; |
| private static final String HBASE_22_VERSION = "2.2"; |
| private static final String HBASE_23_VERSION = "2.3"; |
| private static final String CDH_CLASSIFIER = "cdh"; |
| |
| private static final Logger LOG = LoggerFactory.getLogger(HBaseVersion.class); |
| |
| /** |
| * Represents the major version of the HBase library that is currently loaded. |
| */ |
| public enum Version { |
| HBASE_94("0.94"), |
| HBASE_96("0.96"), |
| HBASE_98("0.98"), |
| HBASE_10("1.0"), |
| HBASE_10_CDH("1.0-cdh"), |
| HBASE_11("1.1"), |
| HBASE_12("1.2"), |
| HBASE_13("1.3"), |
| HBASE_14("1.4"), |
| HBASE_15("1.5"), |
| HBASE_16("1.6"), |
| HBASE_20("2.0"), |
| HBASE_21("2.1"), |
| HBASE_22("2.2"), |
| HBASE_23("2.3"), |
| UNKNOWN("unknown"); |
| |
| final String majorVersion; |
| |
| Version(String majorVersion) { |
| this.majorVersion = majorVersion; |
| } |
| |
| public String getMajorVersion() { |
| return majorVersion; |
| } |
| } |
| |
| private static Version currentVersion; |
| private static String versionString; |
| static { |
| try { |
| Class versionInfoClass = Class.forName("org.apache.hadoop.hbase.util.VersionInfo"); |
| Method versionMethod = versionInfoClass.getMethod("getVersion"); |
| versionString = (String) versionMethod.invoke(null); |
| if (versionString.startsWith(HBASE_94_VERSION)) { |
| currentVersion = Version.HBASE_94; |
| } else if (versionString.startsWith(HBASE_96_VERSION)) { |
| currentVersion = Version.HBASE_96; |
| } else if (versionString.startsWith(HBASE_98_VERSION)) { |
| currentVersion = Version.HBASE_98; |
| } else if (versionString.startsWith(HBASE_10_VERSION)) { |
| VersionNumber ver = VersionNumber.create(versionString); |
| if (ver.getClassifier() != null && ver.getClassifier().startsWith(CDH_CLASSIFIER)) { |
| currentVersion = Version.HBASE_10_CDH; |
| } else { |
| currentVersion = Version.HBASE_10; |
| } |
| } else if (versionString.startsWith(HBASE_11_VERSION)) { |
| currentVersion = Version.HBASE_11; |
| } else if (versionString.startsWith(HBASE_12_VERSION)) { |
| currentVersion = Version.HBASE_12; |
| } else if (versionString.startsWith(HBASE_13_VERSION)) { |
| currentVersion = Version.HBASE_13; |
| } else if (versionString.startsWith(HBASE_14_VERSION)) { |
| currentVersion = Version.HBASE_14; |
| } else if (versionString.startsWith(HBASE_15_VERSION)) { |
| currentVersion = Version.HBASE_15; |
| } else if (versionString.startsWith(HBASE_16_VERSION)) { |
| currentVersion = Version.HBASE_16; |
| } else if (versionString.startsWith(HBASE_20_VERSION)) { |
| currentVersion = Version.HBASE_20; |
| } else if (versionString.startsWith(HBASE_21_VERSION)) { |
| currentVersion = Version.HBASE_21; |
| } else if (versionString.startsWith(HBASE_22_VERSION)) { |
| currentVersion = Version.HBASE_22; |
| } else if (versionString.startsWith(HBASE_23_VERSION)) { |
| currentVersion = Version.HBASE_23; |
| } else { |
| currentVersion = Version.UNKNOWN; |
| } |
| } catch (Throwable e) { |
| // must be a class loading exception, HBase is not there |
| LOG.error("Unable to determine HBase version from string '{}', are HBase classes available?", versionString); |
| LOG.error("Exception was: ", e); |
| currentVersion = Version.UNKNOWN; |
| } |
| } |
| |
| /** |
| * Returns the major version of the currently loaded HBase library. |
| */ |
| public static Version get() { |
| return currentVersion; |
| } |
| |
| /** |
| * Returns the full version string for the currently loaded HBase library. |
| */ |
| public static String getVersionString() { |
| return versionString; |
| } |
| |
| /** |
| * Prints out the HBase {@link Version} enum value for the current version of HBase on the classpath. |
| */ |
| public static void main(String[] args) { |
| boolean verbose = args.length == 1 && "-v".equals(args[0]); |
| Version version = HBaseVersion.get(); |
| System.out.println(version.getMajorVersion()); |
| if (verbose) { |
| System.out.println("versionString=" + getVersionString()); |
| } |
| } |
| |
| /** |
| * Utility class to parse apart version number components. The version string provided is expected to be in |
| * the format: major[.minor[.patch[.last]][-classifier][-SNAPSHOT] |
| * |
| * <p>Only the major version number is actually required.</p> |
| */ |
| public static class VersionNumber { |
| private static final Pattern PATTERN = |
| Pattern.compile("(\\d+)(\\.(\\d+))?(\\.(\\d+))?(\\.(\\d+))?(\\-(?!SNAPSHOT)([^\\-]+))?(\\-SNAPSHOT)?"); |
| |
| private Integer major; |
| private Integer minor; |
| private Integer patch; |
| private Integer last; |
| private String classifier; |
| private boolean snapshot; |
| |
| private VersionNumber(Integer major, Integer minor, Integer patch, Integer last, |
| String classifier, boolean snapshot) { |
| this.major = major; |
| this.minor = minor; |
| this.patch = patch; |
| this.last = last; |
| this.classifier = classifier; |
| this.snapshot = snapshot; |
| } |
| |
| public Integer getMajor() { |
| return major; |
| } |
| |
| public Integer getMinor() { |
| return minor; |
| } |
| |
| public Integer getPatch() { |
| return patch; |
| } |
| |
| public Integer getLast() { |
| return last; |
| } |
| |
| public String getClassifier() { |
| return classifier; |
| } |
| |
| public boolean isSnapshot() { |
| return snapshot; |
| } |
| |
| public static VersionNumber create(String versionString) throws ParseException { |
| Matcher matcher = PATTERN.matcher(versionString); |
| if (matcher.matches()) { |
| String majorString = matcher.group(1); |
| String minorString = matcher.group(3); |
| String patchString = matcher.group(5); |
| String last = matcher.group(7); |
| String classifier = matcher.group(9); |
| String snapshotString = matcher.group(10); |
| return new VersionNumber(new Integer(majorString), |
| minorString != null ? new Integer(minorString) : null, |
| patchString != null ? new Integer(patchString) : null, |
| last != null ? new Integer(last) : null, |
| classifier, |
| "-SNAPSHOT".equals(snapshotString)); |
| } |
| throw new ParseException( |
| "Input string did not match expected pattern: major[.minor[.patch]][-classifier][-SNAPSHOT]", 0); |
| } |
| } |
| } |