blob: c71a58c8dc6f593c754ba6465917774e96e3664d [file] [log] [blame]
/*
* 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());
}
}