Info page
This commit is contained in:
parent
9a451d13f5
commit
2cd18af72c
|
@ -77,6 +77,9 @@ public class MainController {
|
||||||
map.put("toDate", to);
|
map.put("toDate", to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/info")
|
||||||
|
public void wfHistory(final ModelMap map) throws Exception {}
|
||||||
|
|
||||||
@ModelAttribute("resTypes")
|
@ModelAttribute("resTypes")
|
||||||
public Iterable<ResourceType> resourceTypes() {
|
public Iterable<ResourceType> resourceTypes() {
|
||||||
return resourceTypeRepository.findAll();
|
return resourceTypeRepository.findAll();
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
package eu.dnetlib.is.info;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.maven.model.Model;
|
||||||
|
import org.apache.maven.model.Parent;
|
||||||
|
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/info")
|
||||||
|
public class InfoRestController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment configurableEnvironment;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(InfoRestController.class);
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<InfoSection<KeyValue>> info() throws Exception {
|
||||||
|
final RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
|
||||||
|
|
||||||
|
final InfoSection<KeyValue> jvm = new InfoSection<>("JVM");
|
||||||
|
jvm.getData().add(new KeyValue("JVM Name", mxbean.getVmName()));
|
||||||
|
jvm.getData().add(new KeyValue("JVM Vendor", mxbean.getVmVendor()));
|
||||||
|
jvm.getData().add(new KeyValue("JVM Version", mxbean.getVmVersion()));
|
||||||
|
jvm.getData().add(new KeyValue("JVM Spec Name", mxbean.getSpecName()));
|
||||||
|
jvm.getData().add(new KeyValue("JVM Spec Vendor", mxbean.getSpecVendor()));
|
||||||
|
jvm.getData().add(new KeyValue("JVM Spec Version", mxbean.getSpecVersion()));
|
||||||
|
jvm.getData().add(new KeyValue("Running JVM Name", mxbean.getName()));
|
||||||
|
jvm.getData().add(new KeyValue("Management Spec Version", mxbean.getManagementSpecVersion()));
|
||||||
|
|
||||||
|
final InfoSection<KeyValue> env = new InfoSection<>("Environment");
|
||||||
|
configurableEnvironment.getSystemEnvironment().forEach((k, v) -> env.getData().add(new KeyValue(k, v)));
|
||||||
|
|
||||||
|
final InfoSection<KeyValue> libs = new InfoSection<>("Libraries and arguments");
|
||||||
|
libs.getData().add(new KeyValue("Classpath", mxbean.getClassPath().replaceAll(":", " : ")));
|
||||||
|
libs.getData().add(new KeyValue("Boot ClassPath", mxbean.getBootClassPath().replaceAll(":", " : ")));
|
||||||
|
libs.getData().add(new KeyValue("Input arguments", mxbean.getInputArguments().toString()));
|
||||||
|
libs.getData().add(new KeyValue("Library Path", mxbean.getLibraryPath().replaceAll(":", " : ")));
|
||||||
|
|
||||||
|
final InfoSection<KeyValue> sysProps = new InfoSection<>("Environment");
|
||||||
|
configurableEnvironment.getSystemProperties().forEach((k, v) -> sysProps.getData().add(new KeyValue(k, v)));
|
||||||
|
|
||||||
|
return Arrays.asList(jvm, env, libs, sysProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<Map<String, Object>> modules() throws IOException {
|
||||||
|
final Map<String, Map<String, Map<String, Object>>> modules = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
final MavenXpp3Reader reader = new MavenXpp3Reader();
|
||||||
|
for (final Resource res : ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath*:/META-INF/**/pom.xml")) {
|
||||||
|
try {
|
||||||
|
final Model model = reader.read(res.getInputStream());
|
||||||
|
|
||||||
|
final String name = model.getArtifactId();
|
||||||
|
|
||||||
|
String groupId = model.getGroupId();
|
||||||
|
for (Parent parent = model.getParent(); groupId == null && model.getParent() != null; parent = model.getParent()) {
|
||||||
|
groupId = parent.getGroupId();
|
||||||
|
}
|
||||||
|
|
||||||
|
String version = model.getVersion();
|
||||||
|
for (Parent parent = model.getParent(); version == null && model.getParent() != null; parent = model.getParent()) {
|
||||||
|
version = parent.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modules.containsKey(groupId)) {
|
||||||
|
modules.put(groupId, new HashMap<String, Map<String, Object>>());
|
||||||
|
}
|
||||||
|
if (!modules.get(groupId).containsKey(name)) {
|
||||||
|
final Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
map.put("group", groupId);
|
||||||
|
map.put("name", name);
|
||||||
|
map.put("files", new ArrayList<String>());
|
||||||
|
map.put("versions", new ArrayList<String>());
|
||||||
|
modules.get(groupId).put(name, map);
|
||||||
|
} else {
|
||||||
|
// Artifact already found
|
||||||
|
modules.get(groupId).get(name).put("warning", "1");
|
||||||
|
}
|
||||||
|
((List<String>) modules.get(groupId).get(name).get("versions")).add(version);
|
||||||
|
((List<String>) modules.get(groupId).get(name).get("files")).add(res.getURI().toString());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Error evaluating pom: " + res.getURI());
|
||||||
|
log.debug("-- ERROR --", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
|
||||||
|
for (final Entry<String, Map<String, Map<String, Object>>> e : modules.entrySet()) {
|
||||||
|
for (final Entry<String, Map<String, Object>> e1 : e.getValue().entrySet()) {
|
||||||
|
list.add(e1.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(list, (o1, o2) -> {
|
||||||
|
if (o1.get("group").equals(o2.get("group"))) {
|
||||||
|
return o1.get("name").toString().compareTo(o2.get("name").toString());
|
||||||
|
} else {
|
||||||
|
return o1.get("group").toString().compareTo(o2.get("group").toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package eu.dnetlib.is.info;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InfoSection<T> {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final List<T> data;
|
||||||
|
|
||||||
|
public InfoSection(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.data = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package eu.dnetlib.is.info;
|
||||||
|
|
||||||
|
public class KeyValue {
|
||||||
|
|
||||||
|
private final String k;
|
||||||
|
private final Object v;
|
||||||
|
|
||||||
|
public KeyValue(final String k, final Object v) {
|
||||||
|
this.k = k;
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getK() {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getV() {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package eu.dnetlib.is.util;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class DateUtils {
|
||||||
|
|
||||||
|
private static final long SECOND = 1000;
|
||||||
|
private static final long MINUTE = SECOND * 60;
|
||||||
|
private static final long HOUR = MINUTE * 60;
|
||||||
|
private static final long DAY = HOUR * 24;
|
||||||
|
private static final long YEAR = DAY * 365;
|
||||||
|
private static final SimpleDateFormat ISO8601FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
|
||||||
|
|
||||||
|
public static String elapsedTime(long t) {
|
||||||
|
final StringWriter a = new StringWriter();
|
||||||
|
|
||||||
|
boolean prependBlank = false;
|
||||||
|
if (t >= YEAR) {
|
||||||
|
a.append(floor(t, YEAR));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('y');
|
||||||
|
prependBlank = true;
|
||||||
|
}
|
||||||
|
t %= YEAR;
|
||||||
|
if (t >= DAY) {
|
||||||
|
if (prependBlank) {
|
||||||
|
a.append(' ');
|
||||||
|
}
|
||||||
|
a.append(floor(t, DAY));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('d');
|
||||||
|
prependBlank = true;
|
||||||
|
}
|
||||||
|
t %= DAY;
|
||||||
|
if (t >= HOUR) {
|
||||||
|
if (prependBlank) {
|
||||||
|
a.append(' ');
|
||||||
|
}
|
||||||
|
a.append(floor(t, HOUR));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('h');
|
||||||
|
prependBlank = true;
|
||||||
|
}
|
||||||
|
t %= HOUR;
|
||||||
|
if (t >= MINUTE) {
|
||||||
|
if (prependBlank) {
|
||||||
|
a.append(' ');
|
||||||
|
}
|
||||||
|
a.append(floor(t, MINUTE));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('m');
|
||||||
|
prependBlank = true;
|
||||||
|
}
|
||||||
|
t %= MINUTE;
|
||||||
|
if (t >= SECOND) {
|
||||||
|
if (prependBlank) {
|
||||||
|
a.append(' ');
|
||||||
|
}
|
||||||
|
a.append(floor(t, SECOND));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('s');
|
||||||
|
prependBlank = true;
|
||||||
|
}
|
||||||
|
t %= SECOND;
|
||||||
|
if (t > 0) {
|
||||||
|
if (prependBlank) {
|
||||||
|
a.append(' ');
|
||||||
|
}
|
||||||
|
a.append(Integer.toString((int) t));
|
||||||
|
a.append(' ');
|
||||||
|
a.append('m');
|
||||||
|
a.append('s');
|
||||||
|
}
|
||||||
|
return a.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calculate_ISO8601(final long l) {
|
||||||
|
String result = ISO8601FORMAT.format(new Date(l));
|
||||||
|
// convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
|
||||||
|
// - note the added colon for the Timezone
|
||||||
|
result = result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String floor(final long d, final long n) {
|
||||||
|
return Long.toString(Math.floorDiv(d, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -56,6 +56,12 @@
|
||||||
<a class="dropdown-item" href="./wf_history">Workflow history</a>
|
<a class="dropdown-item" href="./wf_history">Workflow history</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Info</a>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" href="./info">Common Info</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head th:replace="fragments/mainParts.html :: htmlHeader('Info')"></head>
|
||||||
|
|
||||||
|
<body ng-app="infoApp" ng-controller="infoController">
|
||||||
|
|
||||||
|
<nav th:replace="fragments/mainParts.html :: mainMenu('Info')"></nav>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="card mb-3" ng-repeat="section in info">
|
||||||
|
<div class="card-header">{{section.name}}</div>
|
||||||
|
<table class="table table-striped table-sm small">
|
||||||
|
<tr ng-repeat="r in section.data">
|
||||||
|
<th style="width:30%">{{r.k}}</th>
|
||||||
|
<td>{{r.v}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header">Modules</div>
|
||||||
|
<table class="table table-striped table-sm small">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Group ID</th>
|
||||||
|
<th>Artifact ID</th>
|
||||||
|
<th>Version</th>
|
||||||
|
<th>POM</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="m : ${modules}" class="warning">
|
||||||
|
<td th:text="${m.group}"></td>
|
||||||
|
<td th:text="${m.name}"></td>
|
||||||
|
<td th:text="${m.versions}"></td>
|
||||||
|
<td th:text="${m.files}"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<th:block th:replace="fragments/mainParts.html :: scripts"></th:block>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var app = angular.module('infoApp', []);
|
||||||
|
|
||||||
|
app.controller('infoController', function($scope, $http) {
|
||||||
|
$scope.info = [];
|
||||||
|
$scope.modules = {};
|
||||||
|
|
||||||
|
$http.get('./api/info/?' + $.now()).then(function successCallback(res) {
|
||||||
|
$scope.info = res.data;
|
||||||
|
}, function errorCallback(res) {
|
||||||
|
alert('ERROR: ' + res.data.message);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue