Info page

This commit is contained in:
Michele Artini 2022-11-29 10:48:20 +01:00
parent 9a451d13f5
commit 2cd18af72c
7 changed files with 356 additions and 0 deletions

View File

@ -77,6 +77,9 @@ public class MainController {
map.put("toDate", to);
}
@GetMapping("/info")
public void wfHistory(final ModelMap map) throws Exception {}
@ModelAttribute("resTypes")
public Iterable<ResourceType> resourceTypes() {
return resourceTypeRepository.findAll();

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -56,6 +56,12 @@
<a class="dropdown-item" href="./wf_history">Workflow history</a>
</div>
</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>
</div>
</nav>

View File

@ -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>