NIFI-2115 Detailed Version Info in About Box

* Java version and vendor
* OS name and version
* Release Tag
* Build revision (commit SHA), branch, and timestamp
* Handles formal releases, ad-hoc builds, and non-release source builds
* Standalone UI presence in About dialog, Summary -> System Diagnostics
* Cluster UI as Versions tab in Cluster dialog
* Reduce About Dialog Content
* Fix Missing Property Display Bugs
* Marking the build time as type string.
* This closes #583
This commit is contained in:
James Wing 2016-09-29 11:00:00 -07:00 committed by Matt Gilman
parent edb0ebe52b
commit a486fefb1e
18 changed files with 489 additions and 6 deletions

View File

@ -48,6 +48,28 @@ language governing permissions and limitations under the License. -->
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<shortRevisionLength>7</shortRevisionLength>
<getRevisionOnlyOnce>true</getRevisionOnlyOnce>
<revisionOnScmFailure></revisionOnScmFailure>
<buildNumberPropertyName>buildRevision</buildNumberPropertyName>
<scmBranchPropertyName>buildBranch</scmBranchPropertyName>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
@ -630,5 +652,18 @@ language governing permissions and limitations under the License. -->
</dependency>
</dependencies>
</profile>
<profile>
<id>build-info-no-git</id>
<activation>
<activeByDefault>false</activeByDefault>
<file>
<missing>../.git/HEAD</missing>
</file>
</activation>
<properties>
<buildRevision></buildRevision>
<buildBranch></buildBranch>
</properties>
</profile>
</profiles>
</project>

View File

@ -24,9 +24,12 @@ import java.net.InetSocketAddress;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -198,6 +201,12 @@ public abstract class NiFiProperties {
// expression language properties
public static final String VARIABLE_REGISTRY_PROPERTIES = "nifi.variable.registry.properties";
// build info
public static final String BUILD_TAG = "nifi.build.tag";
public static final String BUILD_BRANCH = "nifi.build.branch";
public static final String BUILD_REVISION = "nifi.build.revision";
public static final String BUILD_TIMESTAMP = "nifi.build.timestamp";
// defaults
public static final String DEFAULT_TITLE = "NiFi";
public static final Boolean DEFAULT_AUTO_RESUME_STATE = true;
@ -992,6 +1001,21 @@ public abstract class NiFiProperties {
}
}
public Date getBuildTimestamp() {
String buildTimestampString = getProperty(NiFiProperties.BUILD_TIMESTAMP);
if (!StringUtils.isEmpty(buildTimestampString)) {
try {
SimpleDateFormat buildTimestampFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date buildTimestampDate = buildTimestampFormat.parse(buildTimestampString);
return buildTimestampDate;
} catch (ParseException parseEx) {
return null;
}
} else {
return null;
}
}
public int size() {
return getPropertyKeys().size();
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.util.DateTimeAdapter;
import org.apache.nifi.web.api.dto.util.TimezoneAdapter;
import javax.xml.bind.annotation.XmlType;
@ -36,6 +37,11 @@ public class AboutDTO {
private String contentViewerUrl;
private Date timezone;
private String buildTag;
private String buildRevision;
private String buildBranch;
private Date buildTimestamp;
/* getters / setters */
/**
* The title to be used on the page and in the About dialog.
@ -113,4 +119,50 @@ public class AboutDTO {
public void setTimezone(Date timezone) {
this.timezone = timezone;
}
@ApiModelProperty(
value = "Build tag"
)
public String getBuildTag() {
return buildTag;
}
public void setBuildTag(String buildTag) {
this.buildTag = buildTag;
}
@ApiModelProperty(
value = "Build revision or commit hash"
)
public String getBuildRevision() {
return buildRevision;
}
public void setBuildRevision(String buildRevision) {
this.buildRevision = buildRevision;
}
@ApiModelProperty(
value = "Build branch"
)
public String getBuildBranch() {
return buildBranch;
}
public void setBuildBranch(String buildBranch) {
this.buildBranch = buildBranch;
}
@XmlJavaTypeAdapter(DateTimeAdapter.class)
@ApiModelProperty(
value = "Build timestamp",
dataType = "string"
)
public Date getBuildTimestamp() {
return buildTimestamp;
}
public void setBuildTimestamp(Date buildTimestamp) {
this.buildTimestamp = buildTimestamp;
}
}

View File

@ -23,6 +23,7 @@ import java.util.Set;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.nifi.web.api.dto.util.DateTimeAdapter;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import com.wordnik.swagger.annotations.ApiModelProperty;
@ -65,6 +66,8 @@ public class SystemDiagnosticsSnapshotDTO implements Cloneable {
private Date statsLastRefreshed;
private VersionInfoDTO versionInfo;
@ApiModelProperty("Number of available processors if supported by the underlying system.")
public Integer getAvailableProcessors() {
@ -305,6 +308,14 @@ public class SystemDiagnosticsSnapshotDTO implements Cloneable {
this.maxHeapBytes = maxHeapBytes;
}
@ApiModelProperty("The nifi, os, java, and build version information")
public VersionInfoDTO getVersionInfo() {
return versionInfo;
}
public void setVersionInfo(VersionInfoDTO versionInfo) {
this.versionInfo = versionInfo;
}
@Override
public SystemDiagnosticsSnapshotDTO clone() {
@ -347,6 +358,8 @@ public class SystemDiagnosticsSnapshotDTO implements Cloneable {
gcUsage.add(gcDto.clone());
}
other.setVersionInfo(getVersionInfo().clone());
return other;
}
@ -549,4 +562,129 @@ public class SystemDiagnosticsSnapshotDTO implements Cloneable {
return other;
}
}
/**
* Details for version information.
*/
@XmlType(name = "versionInfo")
public static class VersionInfoDTO implements Cloneable {
private String nifiVersion;
private String javaVendor;
private String javaVersion;
private String osName;
private String osVersion;
private String osArchitecture;
private String buildTag;
private String buildRevision;
private String buildBranch;
private Date buildTimestamp;
@ApiModelProperty("The version of this NiFi.")
public String getNiFiVersion() {
return nifiVersion;
}
public void setNiFiVersion(String nifiVersion) {
this.nifiVersion = nifiVersion;
}
@ApiModelProperty("Java JVM vendor")
public String getJavaVendor() {
return javaVendor;
}
public void setJavaVendor(String javaVendor) {
this.javaVendor = javaVendor;
}
@ApiModelProperty("Java version")
public String getJavaVersion() {
return javaVersion;
}
public void setJavaVersion(String javaVersion) {
this.javaVersion = javaVersion;
}
@ApiModelProperty("Host operating system name")
public String getOsName() {
return osName;
}
public void setOsName(String osName) {
this.osName = osName;
}
@ApiModelProperty("Host operating system version")
public String getOsVersion() {
return osVersion;
}
public void setOsVersion(String osVersion) {
this.osVersion = osVersion;
}
@ApiModelProperty("Host operating system architecture")
public String getOsArchitecture() {
return osArchitecture;
}
public void setOsArchitecture(String osArchitecture) {
this.osArchitecture = osArchitecture;
}
@ApiModelProperty("Build tag")
public String getBuildTag() {
return buildTag;
}
public void setBuildTag(String buildTag) {
this.buildTag = buildTag;
}
@ApiModelProperty("Build revision or commit hash")
public String getBuildRevision() {
return buildRevision;
}
public void setBuildRevision(String buildRevision) {
this.buildRevision = buildRevision;
}
@ApiModelProperty("Build branch")
public String getBuildBranch() {
return buildBranch;
}
public void setBuildBranch(String buildBranch) {
this.buildBranch = buildBranch;
}
@XmlJavaTypeAdapter(DateTimeAdapter.class)
@ApiModelProperty("Build timestamp")
public Date getBuildTimestamp() {
return buildTimestamp;
}
public void setBuildTimestamp(Date buildTimestamp) {
this.buildTimestamp = buildTimestamp;
}
@Override
public VersionInfoDTO clone() {
final VersionInfoDTO other = new VersionInfoDTO();
other.setNiFiVersion(getNiFiVersion());
other.setJavaVendor(getJavaVendor());
other.setJavaVersion(getJavaVersion());
other.setOsName(getOsName());
other.setOsVersion(getOsVersion());
other.setOsArchitecture(getOsArchitecture());
other.setBuildTag(getBuildTag());
other.setBuildTimestamp(getBuildTimestamp());
other.setBuildBranch(getBuildBranch());
other.setBuildRevision(getBuildRevision());
return other;
}
}
}

View File

@ -170,6 +170,13 @@
<nifi.kerberos.spnego.principal />
<nifi.kerberos.spnego.keytab.location />
<nifi.kerberos.spnego.authentication.expiration>12 hours</nifi.kerberos.spnego.authentication.expiration>
<!-- nifi.properties: build info -->
<nifi.build.tag>${project.scm.tag}</nifi.build.tag>
<nifi.build.timestamp>${maven.build.timestamp}</nifi.build.timestamp>
<!-- buildRevision and buildBranch provided by buildnumber-maven-plugin or build-info-read-properties profile -->
<nifi.build.branch>${buildBranch}</nifi.build.branch>
<nifi.build.revision>${buildRevision}</nifi.build.revision>
</properties>
<build>
<plugins>

View File

@ -195,4 +195,10 @@ nifi.kerberos.spnego.authentication.expiration=${nifi.kerberos.spnego.authentica
# external properties files for variable registry
# supports a comma delimited list of file locations
nifi.variable.registry.properties=
nifi.variable.registry.properties=
# Build info
nifi.build.tag=${nifi.build.tag}
nifi.build.branch=${nifi.build.branch}
nifi.build.revision=${nifi.build.revision}
nifi.build.timestamp=${nifi.build.timestamp}

View File

@ -1089,7 +1089,14 @@ public class FlowResource extends ApplicationResource {
aboutDTO.setTimezone(new Date());
// get the content viewer url
aboutDTO.setContentViewerUrl(getProperties().getProperty(NiFiProperties.CONTENT_VIEWER_URL));
final NiFiProperties properties = getProperties();
aboutDTO.setContentViewerUrl(properties.getProperty(NiFiProperties.CONTENT_VIEWER_URL));
// Get build info
aboutDTO.setBuildTag(properties.getProperty(NiFiProperties.BUILD_TAG));
aboutDTO.setBuildRevision(properties.getProperty(NiFiProperties.BUILD_REVISION));
aboutDTO.setBuildBranch(properties.getProperty(NiFiProperties.BUILD_BRANCH));
aboutDTO.setBuildTimestamp(properties.getBuildTimestamp());
// create the response entity
final AboutEntity entity = new AboutEntity();

View File

@ -107,6 +107,7 @@ import org.apache.nifi.reporting.BulletinRepository;
import org.apache.nifi.reporting.ReportingTask;
import org.apache.nifi.scheduling.SchedulingStrategy;
import org.apache.nifi.util.FormatUtils;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.StringUtils;
import org.apache.nifi.web.FlowModification;
import org.apache.nifi.web.Revision;
@ -193,6 +194,7 @@ public final class DtoFactory {
private ControllerServiceProvider controllerServiceProvider;
private EntityFactory entityFactory;
private Authorizer authorizer;
private NiFiProperties properties;
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade) {
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
@ -2356,6 +2358,10 @@ public final class DtoFactory {
garbageCollectionDtos.add(createGarbageCollectionDTO(entry.getKey(), entry.getValue()));
}
// version info
final SystemDiagnosticsSnapshotDTO.VersionInfoDTO versionInfoDto = createVersionInfoDTO();
snapshot.setVersionInfo(versionInfoDto);
return dto;
}
@ -2395,6 +2401,21 @@ public final class DtoFactory {
return dto;
}
public SystemDiagnosticsSnapshotDTO.VersionInfoDTO createVersionInfoDTO() {
final SystemDiagnosticsSnapshotDTO.VersionInfoDTO dto = new SystemDiagnosticsSnapshotDTO.VersionInfoDTO();
dto.setNiFiVersion(properties.getUiTitle());
dto.setJavaVendor(System.getProperty("java.vendor"));
dto.setJavaVersion(System.getProperty("java.version"));
dto.setOsName(System.getProperty("os.name"));
dto.setOsVersion(System.getProperty("os.version"));
dto.setOsArchitecture(System.getProperty("os.arch"));
dto.setBuildTag(properties.getProperty(NiFiProperties.BUILD_TAG));
dto.setBuildRevision(properties.getProperty(NiFiProperties.BUILD_REVISION));
dto.setBuildBranch(properties.getProperty(NiFiProperties.BUILD_BRANCH));
dto.setBuildTimestamp(properties.getBuildTimestamp());
return dto;
}
/**
* Creates a ResourceDTO from the specified Resource.
*
@ -3063,4 +3084,8 @@ public final class DtoFactory {
public void setBulletinRepository(BulletinRepository bulletinRepository) {
this.bulletinRepository = bulletinRepository;
}
public void setProperties(final NiFiProperties properties) {
this.properties = properties;
}
}

View File

@ -52,6 +52,7 @@
<property name="entityFactory" ref="entityFactory"/>
<property name="authorizer" ref="authorizer"/>
<property name="bulletinRepository" ref="bulletinRepository"/>
<property name="properties" ref="nifiProperties"/>
</bean>
<!-- snippet utils -->

View File

@ -22,6 +22,17 @@
<div class="dialog-content">
<div id="nf-about-content">
<span id="nf-version"></span>
<div id="nf-version-detail">
<p id="nf-version-detail-timestamp">
<span id="nf-about-build-timestamp"></span>
</p>
<p id="nf-version-detail-tag">
Tagged <span id="nf-about-build-tag"></span>
</p>
<p id="nf-version-detail-commit">
From <span id="nf-about-build-revision"></span> on branch <span id="nf-about-build-branch"></span>
</p>
</div>
<p>
Apache NiFi is a framework to support highly scalable and flexible dataflows.
It can be run on on laptops up through clusters of enterprise class servers.

View File

@ -45,6 +45,9 @@
<div id="cluster-content-tab-content" class="configuration-tab">
<div id="cluster-content-table" class="cluster-tabbed-table"></div>
</div>
<div id="cluster-version-tab-content" class="configuration-tab">
<div id="cluster-version-table" class="cluster-tabbed-table"></div>
</div>
</div>
</div>
<div id="cluster-refresh-container">

View File

@ -163,6 +163,35 @@
</div>
</div>
</div>
<div id="version-tab-content" class="configuration-tab">
<div class="setting">
<div class="setting-header">NiFi</div>
<dl class="setting-attributes-list">
<dt>NiFi Version</dt><dd><span id="version-nifi"></span></dd>
<dt>Tag</dt><dd><span id="version-build-tag"></span></dd>
<dt>Build Date/Time</dt><dd><span id="version-build-timestamp"></span></dd>
<dt>Branch</dt><dd><span id="version-build-branch"></span></dd>
<dt>Revision</dt><dd><span id="version-build-revision"></span></dd>
</dl>
</div>
<div class="setting">
<div class="setting-header">Java</div>
<dl class="setting-attributes-list">
<dt>Version</dt><dd><span id="version-java-version"></span></dd>
<dt>Vendor</dt><dd><span id="version-java-vendor"></span></dd>
</dl>
</div>
<div class="setting">
<div class="setting-header">Operating System</div>
<dl class="setting-attributes-list">
<dt>Name</dt><dd><span id="version-os-name"></span></dd>
<dt>Version</dt><dd><span id="version-os-version"></span></dd>
<dt>Architecture</dt><dd><span id="version-os-arch"></span></dd>
</dl>
</div>
</div>
</div>
<div id="system-diagnostics-refresh-container">
<button id="system-diagnostics-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>

View File

@ -22,20 +22,21 @@
}
#nf-about-pic {
height: 50%;
height: 60%;
background: url(../images/nifi-logo-about.svg) #000000 no-repeat center center;
top: 25%;
top: 20%;
position: relative;
}
#nf-about-pic-container {
height: 50%;
height: 40%;
background: #000000;
}
#nf-version {
font-weight:500;
font-size: 13px;
cursor: pointer;
}
#nf-about-content p {
@ -51,3 +52,20 @@
font-weight:900;
}
#nf-version-detail {
padding: 5px 0 0 5px;
display: none;
}
#nf-version-detail-tag {
display: none;
}
#nf-version-detail-commit {
display: none;
}
#nf-about-content #nf-version-detail p {
font-size: 12px;
padding: 0;
}

View File

@ -217,6 +217,25 @@ div.storage-usage-progressbar div.ui-progressbar-value {
border-radius: 0;
}
dl.setting-attributes-list {
float: left;
font-size: 12px;
width: 100%;
padding-bottom: 20px;
}
.setting-attributes-list dt {
float: left;
clear: left;
padding: 0 0.5em 0.3em 0;
font-weight: bold;
}
.setting-attributes-list dd {
margin-left: 8em;
padding-bottom: 0.3em;
}
/* summary tabs */
#summary-tabs {

View File

@ -278,6 +278,26 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
// set the document title and the about title
document.title = aboutDetails.title;
$('#nf-version').text(aboutDetails.version);
var showVersionDetail = false;
if (aboutDetails.buildTag && aboutDetails.buildTag !== 'HEAD') {
$('#nf-about-build-tag').text(aboutDetails.buildTag);
$('#nf-version-detail-tag').show();
showVersionDetail = true;
}
if (aboutDetails.buildRevision) {
$('#nf-about-build-revision').text(aboutDetails.buildRevision);
$('#nf-about-build-branch').text(aboutDetails.buildBranch);
$('#nf-version-detail-commit').show();
showVersionDetail = true
}
if (aboutDetails.buildTimestamp) {
$('#nf-about-build-timestamp').text(aboutDetails.buildTimestamp);
$('#nf-version-detail-timestamp').show();
showVersionDetail = true;
}
if (showVersionDetail) {
$('#nf-version-detail').show();
}
// store the content viewer url if available
if (!nf.Common.isBlank(aboutDetails.contentViewerUrl)) {

View File

@ -191,7 +191,36 @@ nf.ClusterTable = (function () {
}]
};
var clusterTabs = [nodesTab, systemTab, jvmTab, flowFileTab, contentTab];
var versionTab = {
name: 'Versions',
data: {
dataSet: 'systemDiagnostics',
update: updateVersionTableData
},
tabContentId: 'cluster-version-tab-content',
tableId: 'cluster-version-table',
tableColumnModel: [
{id: 'node', field: 'node', name: 'Node Address', sortable: true, resizable: true},
{id: 'version', field: 'version', name: 'NiFi Version', sortable: true, resizable: true},
{id: 'javavendor', field: 'javaVendor', name: 'Java Vendor', sortable: true, resizable: true},
{id: 'javaversion', field: 'javaVersion', name: 'Java Version', sortable: true, resizable: true},
{id: 'osname', field: 'osName', name: 'OS Name', sortable: true, resizable: true},
{id: 'osversion', field: 'osVersion', name: 'OS Version', sortable: true, resizable: true},
{id: 'osarch', field: 'osArchitecture', name: 'OS Architecture', sortable: true, resizable: true}
],
tableIdColumn: 'id',
tableOptions: commonTableOptions,
tableOnClick: null,
init: commonTableInit,
onSort: sort,
onTabSelected: onSelectTab,
filterOptions: [{
text: 'by address',
value: 'address'
}]
};
var clusterTabs = [nodesTab, systemTab, jvmTab, flowFileTab, contentTab, versionTab];
var tabsByName = {};
var dataSetHandlers = {};
@ -769,6 +798,35 @@ nf.ClusterTable = (function () {
}
}
/**
* Applies system diagnostics data to the Versions tab.
*/
function updateVersionTableData (systemDiagnosticsResponse) {
if (nf.Common.isDefinedAndNotNull(systemDiagnosticsResponse.systemDiagnostics)
&& nf.Common.isDefinedAndNotNull(systemDiagnosticsResponse.systemDiagnostics.nodeSnapshots)) {
var versionTableRows = [];
systemDiagnosticsResponse.systemDiagnostics.nodeSnapshots.forEach(function (nodeSnapshot) {
var snapshot = nodeSnapshot.snapshot;
versionTableRows.push({
id: nodeSnapshot.nodeId,
address: nodeSnapshot.address,
node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
version: snapshot.versionInfo.niFiVersion,
javaVendor: snapshot.versionInfo.javaVendor,
javaVersion: snapshot.versionInfo.javaVersion,
osName: snapshot.versionInfo.osName,
osVersion: snapshot.versionInfo.osVersion,
osArchitecture: snapshot.versionInfo.osArchitecture
});
});
versionTab.dataView.setItems(versionTableRows);
versionTab.dataView.reSort();
versionTab.grid.invalidate();
}
}
/**
* Loads system diagnostics data for the cluster.
*/

View File

@ -2010,6 +2010,9 @@ nf.SummaryTable = (function () {
}, {
name: 'System',
tabContentId: 'system-tab-content'
}, {
name: 'Version',
tabContentId: 'version-tab-content'
}]
});
@ -2293,6 +2296,28 @@ nf.SummaryTable = (function () {
addStorageUsage(contentRepositoryUsageContainer, contentRepository);
});
// Version
var versionSpanSelectorToFieldMap = {
'#version-nifi': aggregateSnapshot.versionInfo.niFiVersion,
'#version-build-tag': aggregateSnapshot.versionInfo.buildTag,
'#version-build-timestamp': aggregateSnapshot.versionInfo.buildTimestamp,
'#version-build-branch': aggregateSnapshot.versionInfo.buildBranch,
'#version-build-revision': aggregateSnapshot.versionInfo.buildRevision,
'#version-java-version': aggregateSnapshot.versionInfo.javaVersion,
'#version-java-vendor': aggregateSnapshot.versionInfo.javaVendor,
'#version-os-name': aggregateSnapshot.versionInfo.osName,
'#version-os-version': aggregateSnapshot.versionInfo.osVersion,
'#version-os-arch': aggregateSnapshot.versionInfo.osArchitecture
};
for (versionSpanSelector in versionSpanSelectorToFieldMap) {
var dataField = versionSpanSelectorToFieldMap[versionSpanSelector];
if (dataField) {
$(versionSpanSelector).text(dataField);
} else {
$(versionSpanSelector).text('(not available)').addClass('unset');
}
}
// update the stats last refreshed timestamp
$('#system-diagnostics-last-refreshed').text(aggregateSnapshot.statsLastRefreshed);
}).fail(nf.Common.handleAjaxError);

View File

@ -1537,6 +1537,11 @@ language governing permissions and limitations under the License. -->
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.4</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>