| /* |
| * 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.storm.utils; |
| |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.Arrays; |
| import java.util.Enumeration; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.jar.JarFile; |
| import java.util.zip.ZipEntry; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public final class VersionInfo { |
| private static final Logger LOG = LoggerFactory.getLogger(VersionInfo.class); |
| private static final String STORM_CORE_PROPERTIES_NAME = "storm-core-version-info.properties"; |
| private static final String STORM_CLIENT_PROPERTIES_NAME = "storm-client-version-info.properties"; |
| public static final IVersionInfo OUR_FULL_VERSION = new VersionInfoImpl("storm-client"); |
| public static final SimpleVersion OUR_VERSION = new SimpleVersion(OUR_FULL_VERSION.getVersion()); |
| |
| private static class VersionInfoImpl implements IVersionInfo { |
| private Properties info; |
| |
| protected VersionInfoImpl(String component) { |
| info = new Properties(); |
| String versionInfoFile = component + "-version-info.properties"; |
| try (InputStream is = Thread.currentThread().getContextClassLoader() |
| .getResourceAsStream(versionInfoFile)) { |
| if (is == null) { |
| throw new IOException("Resource not found"); |
| } |
| info.load(is); |
| } catch (IOException e) { |
| LOG.error("Could not load {}", versionInfoFile, e); |
| } |
| } |
| |
| protected VersionInfoImpl(Properties info) { |
| this.info = info; |
| } |
| |
| @Override |
| public String getVersion() { |
| return info.getProperty("version", "Unknown"); |
| } |
| |
| @Override |
| public String getRevision() { |
| return info.getProperty("revision", "Unknown"); |
| } |
| |
| @Override |
| public String getBranch() { |
| return info.getProperty("branch", "Unknown"); |
| } |
| |
| @Override |
| public String getDate() { |
| return info.getProperty("date", "Unknown"); |
| } |
| |
| @Override |
| public String getUser() { |
| return info.getProperty("user", "Unknown"); |
| } |
| |
| @Override |
| public String getUrl() { |
| return info.getProperty("url", "Unknown"); |
| } |
| |
| @Override |
| public String getSrcChecksum() { |
| return info.getProperty("srcChecksum", "Unknown"); |
| } |
| |
| @Override |
| public String getBuildVersion() { |
| return this.getVersion() |
| + " from " + getRevision() |
| + " by " + getUser() |
| + " source checksum " + getSrcChecksum(); |
| } |
| } |
| |
| /** |
| * Look for the version of storm defined by the given classpath. |
| * @param cp the classpath as a string to be parsed. |
| * @return the IVersionInfo or null. |
| */ |
| public static IVersionInfo getFromClasspath(String cp) { |
| List<String> classpath = Arrays.asList(cp.split(File.pathSeparator)); |
| return getFromClasspath(classpath); |
| } |
| |
| /** |
| * Look for the version of storm defined by the given classpath. |
| * @param classpath the classpath as list of files/directories. |
| * @return the IVersionInfo or null. |
| */ |
| public static IVersionInfo getFromClasspath(List<String> classpath) { |
| IVersionInfo ret = getFromClasspath(classpath, STORM_CLIENT_PROPERTIES_NAME); |
| if (ret == null) { |
| //storm-core is needed here for backwards compatibility. |
| ret = getFromClasspath(classpath, STORM_CORE_PROPERTIES_NAME); |
| } |
| return ret; |
| } |
| |
| private static IVersionInfo getFromClasspath(List<String> classpath, final String propFileName) { |
| IVersionInfo ret = null; |
| for (String part: classpath) { |
| Path p = Paths.get(part); |
| if (Files.isDirectory(p)) { |
| Path child = p.resolve(propFileName); |
| if (Files.exists(child) && !Files.isDirectory(child)) { |
| try (FileReader reader = new FileReader(child.toFile())) { |
| Properties info = new Properties(); |
| info.load(reader); |
| ret = new VersionInfoImpl(info); |
| break; |
| } catch (IOException e) { |
| LOG.error("Skipping {} get an error while trying to parse the file.", part, e); |
| } |
| } |
| } else if (part.toLowerCase().endsWith(".jar") |
| || part.toLowerCase().endsWith(".zip")) { |
| //Treat it like a jar |
| try (JarFile jf = new JarFile(p.toFile())) { |
| Enumeration<? extends ZipEntry> zipEnums = jf.entries(); |
| while (zipEnums.hasMoreElements()) { |
| ZipEntry entry = zipEnums.nextElement(); |
| if (!entry.isDirectory() && entry.getName().equals(propFileName)) { |
| try (InputStreamReader reader = new InputStreamReader(jf.getInputStream(entry))) { |
| Properties info = new Properties(); |
| info.load(reader); |
| ret = new VersionInfoImpl(info); |
| break; |
| } |
| } |
| } |
| } catch (IOException e) { |
| LOG.error("Skipping {} get an error while trying to parse the jar file.", part, e); |
| } |
| } else { |
| LOG.warn("Skipping {} don't know what to do with it.", part); |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * Get the version number of the build. |
| * @return the version number of the build. |
| */ |
| public static String getVersion() { |
| return OUR_FULL_VERSION.getVersion(); |
| } |
| |
| /** |
| * Get the SCM revision number of the build. |
| * @return the SCM revision number of the build. |
| */ |
| public static String getRevision() { |
| return OUR_FULL_VERSION.getRevision(); |
| } |
| |
| /** |
| * Get the SCM branch of the build. |
| * @return the SCM branch of the build. |
| */ |
| public static String getBranch() { |
| return OUR_FULL_VERSION.getBranch(); |
| } |
| |
| /** |
| * Get the date/time the build happened. |
| * @return the date/time of the build. |
| */ |
| public static String getDate() { |
| return OUR_FULL_VERSION.getDate(); |
| } |
| |
| /** |
| * Get the name of the user that did the build. |
| * @return the name of the user that did the build. |
| */ |
| public static String getUser() { |
| return OUR_FULL_VERSION.getUser(); |
| } |
| |
| /** |
| * Get the full SCM URL for the build. |
| * @return the SCM URL of the build. |
| */ |
| public static String getUrl() { |
| return OUR_FULL_VERSION.getUrl(); |
| } |
| |
| /** |
| * Get the checksum of the source. |
| * @return the checksum of the source. |
| */ |
| public static String getSrcChecksum() { |
| return OUR_FULL_VERSION.getSrcChecksum(); |
| } |
| |
| /** |
| * Get a descriptive representation of the build meant for human consumption. |
| * @return a descriptive representation of the build. |
| */ |
| public static String getBuildVersion() { |
| return OUR_FULL_VERSION.getBuildVersion(); |
| } |
| |
| public static void main(String[] args) { |
| System.out.println("Storm " + getVersion()); |
| System.out.println("URL " + getUrl() + " -r " + getRevision()); |
| System.out.println("Branch " + getBranch()); |
| System.out.println("Compiled by " + getUser() + " on " + getDate()); |
| System.out.println("From source with checksum " + getSrcChecksum()); |
| } |
| } |