From 2cd18af72cee52c9db05ae0d1fbb0f41ab6bdae0 Mon Sep 17 00:00:00 2001 From: "michele.artini" Date: Tue, 29 Nov 2022 10:48:20 +0100 Subject: [PATCH] Info page --- .../java/eu/dnetlib/is/MainController.java | 3 + .../dnetlib/is/info/InfoRestController.java | 132 ++++++++++++++++++ .../java/eu/dnetlib/is/info/InfoSection.java | 24 ++++ .../java/eu/dnetlib/is/info/KeyValue.java | 21 +++ .../java/eu/dnetlib/is/util/DateUtils.java | 92 ++++++++++++ .../templates/fragments/mainParts.html | 6 + .../src/main/resources/templates/info.html | 78 +++++++++++ 7 files changed, 356 insertions(+) create mode 100644 apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoRestController.java create mode 100644 apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoSection.java create mode 100644 apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/KeyValue.java create mode 100644 apps/dnet-is-application/src/main/java/eu/dnetlib/is/util/DateUtils.java create mode 100644 apps/dnet-is-application/src/main/resources/templates/info.html diff --git a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/MainController.java b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/MainController.java index 749082ad..000aa2a3 100644 --- a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/MainController.java +++ b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/MainController.java @@ -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 resourceTypes() { return resourceTypeRepository.findAll(); diff --git a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoRestController.java b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoRestController.java new file mode 100644 index 00000000..704792d1 --- /dev/null +++ b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoRestController.java @@ -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> info() throws Exception { + final RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean(); + + final InfoSection 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 env = new InfoSection<>("Environment"); + configurableEnvironment.getSystemEnvironment().forEach((k, v) -> env.getData().add(new KeyValue(k, v))); + + final InfoSection 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 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> modules() throws IOException { + final Map>> 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>()); + } + if (!modules.get(groupId).containsKey(name)) { + final Map map = new LinkedHashMap<>(); + map.put("group", groupId); + map.put("name", name); + map.put("files", new ArrayList()); + map.put("versions", new ArrayList()); + modules.get(groupId).put(name, map); + } else { + // Artifact already found + modules.get(groupId).get(name).put("warning", "1"); + } + ((List) modules.get(groupId).get(name).get("versions")).add(version); + ((List) 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> list = new ArrayList<>(); + + for (final Entry>> e : modules.entrySet()) { + for (final Entry> 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; + } + +} diff --git a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoSection.java b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoSection.java new file mode 100644 index 00000000..c63107f2 --- /dev/null +++ b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/InfoSection.java @@ -0,0 +1,24 @@ +package eu.dnetlib.is.info; + +import java.util.ArrayList; +import java.util.List; + +public class InfoSection { + + private final String name; + private final List data; + + public InfoSection(final String name) { + this.name = name; + this.data = new ArrayList<>(); + } + + public String getName() { + return name; + } + + public List getData() { + return data; + } + +} diff --git a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/KeyValue.java b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/KeyValue.java new file mode 100644 index 00000000..082e63fb --- /dev/null +++ b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/info/KeyValue.java @@ -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; + } + +} diff --git a/apps/dnet-is-application/src/main/java/eu/dnetlib/is/util/DateUtils.java b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/util/DateUtils.java new file mode 100644 index 00000000..6b3aa183 --- /dev/null +++ b/apps/dnet-is-application/src/main/java/eu/dnetlib/is/util/DateUtils.java @@ -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)); + } + +} diff --git a/apps/dnet-is-application/src/main/resources/templates/fragments/mainParts.html b/apps/dnet-is-application/src/main/resources/templates/fragments/mainParts.html index bd10295b..a08ac0b0 100644 --- a/apps/dnet-is-application/src/main/resources/templates/fragments/mainParts.html +++ b/apps/dnet-is-application/src/main/resources/templates/fragments/mainParts.html @@ -56,6 +56,12 @@ Workflow history + diff --git a/apps/dnet-is-application/src/main/resources/templates/info.html b/apps/dnet-is-application/src/main/resources/templates/info.html new file mode 100644 index 00000000..f09d8bd2 --- /dev/null +++ b/apps/dnet-is-application/src/main/resources/templates/info.html @@ -0,0 +1,78 @@ + + + + + + + + + +
+
+
+ +
+
{{section.name}}
+ + + + + +
{{r.k}}{{r.v}}
+
+ +
+
Modules
+ + + + + + + + + + + + + + + + + +
Group IDArtifact IDVersionPOM
+
+ + +
+
+
+ + + + + + + + + + + + + + + + \ No newline at end of file