diff --git a/bitrepository-core/src/main/java/org/bitrepository/common/utils/SettingsUtils.java b/bitrepository-core/src/main/java/org/bitrepository/common/utils/SettingsUtils.java index c97eb183e..4a816a984 100644 --- a/bitrepository-core/src/main/java/org/bitrepository/common/utils/SettingsUtils.java +++ b/bitrepository-core/src/main/java/org/bitrepository/common/utils/SettingsUtils.java @@ -29,6 +29,7 @@ import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -101,6 +102,26 @@ public static String getCollectionName(String collectionID) { return name; } + public static IntegrityServiceSettings getIntegrityServiceSettings() { + return settings.getReferenceSettings().getIntegrityServiceSettings(); + } + + /** + * Grab all PillarDetails from the ReferenceSettings if any are defined and return them as a list. + * Return an empty list if not defined. + * @return List of all PillarDetails defined in the ReferenceSettings + */ + public static List getPillarIntegrityDetails() { + PillarIntegrityDetails pillarIntegrityDetails = getIntegrityServiceSettings().getPillarIntegrityDetails(); + if (pillarIntegrityDetails != null) { + List pillarDetails = pillarIntegrityDetails.getPillarDetails(); + if (pillarDetails != null) { + return Collections.unmodifiableList(pillarDetails); + } + } + return List.of(); + } + /** * Get the human-readable pillar name for the given pillarID from the ReferenceSettings. * @@ -108,21 +129,14 @@ public static String getCollectionName(String collectionID) { * @return Returns the pillar name for the given pillar ID. */ public static String getPillarName(String pillarID) { - PillarIntegrityDetails details = settings.getReferenceSettings().getIntegrityServiceSettings().getPillarIntegrityDetails(); - if (details != null) { - for (PillarIntegrityDetails.PillarDetails d : details.getPillarDetails()) { - if (d.getPillarID().equals(pillarID)) { - return d.getPillarName(); - } + for (PillarIntegrityDetails.PillarDetails d : getPillarIntegrityDetails()) { + if (d.getPillarID().equals(pillarID)) { + return d.getPillarName(); } } return null; } - public static IntegrityServiceSettings getIntegrityServiceSettings() { - return settings.getReferenceSettings().getIntegrityServiceSettings(); - } - /** * Get the {@link PillarType} for the given Pillar ID. * @@ -130,12 +144,9 @@ public static IntegrityServiceSettings getIntegrityServiceSettings() { * @return Returns the {@link PillarType} for the given pillar ID. */ public static PillarType getPillarType(String pillarID) { - PillarIntegrityDetails details = settings.getReferenceSettings().getIntegrityServiceSettings().getPillarIntegrityDetails(); - if (details != null) { - for (PillarIntegrityDetails.PillarDetails d : details.getPillarDetails()) { - if (d.getPillarID().equals(pillarID)) { - return d.getPillarType(); - } + for (PillarIntegrityDetails.PillarDetails d : getPillarIntegrityDetails()) { + if (d.getPillarID().equals(pillarID)) { + return d.getPillarType(); } } return null; @@ -212,5 +223,4 @@ public static Set getStatusContributorsForCollection() { contributors.addAll(SettingsUtils.getAllPillarIDs()); return contributors; } - } diff --git a/bitrepository-core/src/main/resources/examples/settings/ReferenceSettings.xml b/bitrepository-core/src/main/resources/examples/settings/ReferenceSettings.xml index e7b13c1b8..688cb7b05 100644 --- a/bitrepository-core/src/main/resources/examples/settings/ReferenceSettings.xml +++ b/bitrepository-core/src/main/resources/examples/settings/ReferenceSettings.xml @@ -445,6 +445,7 @@ Pillar1 Alpha FILE + Anon Anonymoose anon@kb.dk diff --git a/bitrepository-integration/src/main/resources/quickstart/conf/integrityservice/ReferenceSettings.xml b/bitrepository-integration/src/main/resources/quickstart/conf/integrityservice/ReferenceSettings.xml index e01335fc6..1db9f581d 100644 --- a/bitrepository-integration/src/main/resources/quickstart/conf/integrityservice/ReferenceSettings.xml +++ b/bitrepository-integration/src/main/resources/quickstart/conf/integrityservice/ReferenceSettings.xml @@ -113,16 +113,19 @@ checksum-pillar Alpha CHECKSUM + Anon Anonymoose anon@kb.dk file1-pillar Beta FILE + Anon Anonymoose anon@kb.dk file2-pillar Gamma FILE + Anon Anonymoose anon@kb.dk diff --git a/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/PillarDetailsDto.java b/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/PillarDetailsDto.java new file mode 100644 index 000000000..8fe4dc329 --- /dev/null +++ b/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/PillarDetailsDto.java @@ -0,0 +1,63 @@ +package org.bitrepository.integrityservice.web; + +import java.io.Serializable; + +public class PillarDetailsDto implements Serializable { + private static final long serialVersionUID = 1L; + + private String pillarID; + private String pillarName; + private String pillarType; + private String pillarDeleteFileApprover; + + public PillarDetailsDto() {} + + public PillarDetailsDto(String pillarID, String pillarName, String pillarType, String pillarDeleteFileApprover) { + this.pillarID = pillarID; + this.pillarName = pillarName; + this.pillarType = pillarType; + this.pillarDeleteFileApprover = pillarDeleteFileApprover; + } + + public String getPillarID() { + return pillarID; + } + + public void setPillarID(String pillarID) { + this.pillarID = pillarID; + } + + public String getPillarName() { + return pillarName; + } + + public void setPillarName(String pillarName) { + this.pillarName = pillarName; + } + + public String getPillarType() { + return pillarType; + } + + public void setPillarType(String pillarType) { + this.pillarType = pillarType; + } + + public String getPillarDeleteFileApprover() { + return pillarDeleteFileApprover; + } + + public void setPillarDeleteFileApprover(String pillarDeleteFileApprover) { + this.pillarDeleteFileApprover = pillarDeleteFileApprover; + } + + @Override + public String toString() { + return "PillarDetailsDTO{" + + "pillarID='" + pillarID + '\'' + + ", pillarName='" + pillarName + '\'' + + ", pillarType=" + pillarType + + ", pillarDeleteFileApprover='" + pillarDeleteFileApprover + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/RestIntegrityService.java b/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/RestIntegrityService.java index db411deec..8a981a478 100644 --- a/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/RestIntegrityService.java +++ b/bitrepository-integrity-service/src/main/java/org/bitrepository/integrityservice/web/RestIntegrityService.java @@ -42,6 +42,7 @@ import org.bitrepository.service.workflow.Workflow; import org.bitrepository.service.workflow.WorkflowManager; import org.bitrepository.service.workflow.WorkflowStatistic; +import org.bitrepository.settings.referencesettings.PillarIntegrityDetails; import org.bitrepository.settings.referencesettings.PillarType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -261,6 +262,20 @@ public String getIntegrityStatus(@QueryParam("collectionID") String collectionID return writer.toString(); } + @GET + @Path("/getPillarDetails") + @Produces(MediaType.APPLICATION_JSON) + public List getPillarDetails() { + List pillarDetails = SettingsUtils.getPillarIntegrityDetails(); + List result = new ArrayList<>(pillarDetails.size()); + for (PillarIntegrityDetails.PillarDetails details : pillarDetails) { + PillarDetailsDto detailsDTO = new PillarDetailsDto(details.getPillarID(), details.getPillarName(), + details.getPillarType().value(), details.getPillarDeleteFileApprover()); + result.add(detailsDTO); + } + return result; + } + /*** * Get the current workflow’s setup as a JSON array */ diff --git a/bitrepository-integrity-service/src/test/java/org/bitrepository/integrityservice/web/PillarDetailsDtoTest.java b/bitrepository-integrity-service/src/test/java/org/bitrepository/integrityservice/web/PillarDetailsDtoTest.java new file mode 100644 index 000000000..b25ef9a33 --- /dev/null +++ b/bitrepository-integrity-service/src/test/java/org/bitrepository/integrityservice/web/PillarDetailsDtoTest.java @@ -0,0 +1,24 @@ +package org.bitrepository.integrityservice.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.testng.annotations.Test; + +import java.io.IOException; + +import static org.testng.Assert.*; + +public class PillarDetailsDtoTest { + private final ObjectMapper objectMapper = new ObjectMapper(); // Use ObjectMapper for JSON + + @Test + void testSerialization() throws IOException { + PillarDetailsDto dto = new PillarDetailsDto("id", "pillar", "TYPE", "admin"); + + String jsonOutput = objectMapper.writeValueAsString(dto); + + assertTrue(jsonOutput.contains("\"pillarID\":\"id\"")); + assertTrue(jsonOutput.contains("\"pillarName\":\"pillar\"")); + assertTrue(jsonOutput.contains("\"pillarType\":\"TYPE\"")); + assertTrue(jsonOutput.contains("\"pillarDeleteFileApprover\":\"admin\"")); + } +} \ No newline at end of file diff --git a/bitrepository-reference-settings/src/main/resources/xsd/ReferenceSettings.xsd b/bitrepository-reference-settings/src/main/resources/xsd/ReferenceSettings.xsd index d6db153a6..4fd7583af 100644 --- a/bitrepository-reference-settings/src/main/resources/xsd/ReferenceSettings.xsd +++ b/bitrepository-reference-settings/src/main/resources/xsd/ReferenceSettings.xsd @@ -398,6 +398,14 @@ + + + + Free text field for name/email/contact-info of the person responsible for approving any deletions + on this pillar prior to running an actual DeleteFile-operation. + + + diff --git a/bitrepository-webclient/src/main/webapp/dashboard.html b/bitrepository-webclient/src/main/webapp/dashboard.html index 2bcc30dea..e6abb6b45 100644 --- a/bitrepository-webclient/src/main/webapp/dashboard.html +++ b/bitrepository-webclient/src/main/webapp/dashboard.html @@ -38,7 +38,7 @@ - + @@ -52,6 +52,19 @@
Collection nameCollection name Number of files Latest Ingest Collection size
+
+ + + + + + + + + + +
Pillar IDPillar namePillar typeDeletion approver
+
@@ -106,6 +119,7 @@

Data distributed on pillars

+ diff --git a/bitrepository-webclient/src/main/webapp/static/css/dashboard.css b/bitrepository-webclient/src/main/webapp/static/css/dashboard.css index 7c0dad911..5b6684275 100644 --- a/bitrepository-webclient/src/main/webapp/static/css/dashboard.css +++ b/bitrepository-webclient/src/main/webapp/static/css/dashboard.css @@ -4,7 +4,7 @@ margin-top: 0.9em; } -.collectionStatus, .dataSizeGraph, .collectionPieBox, .legPieBox { +.collectionStatus, .pillarDetails, .dataSizeGraph, .collectionPieBox, .legPieBox { border: 1px solid #cccccc; float: left; margin: 0 0 2em; @@ -15,18 +15,10 @@ box-sizing: border-box; } -.collectionStatus, .collectionPieBox, .legPieBox { +.collectionStatus, .pillarDetails, .collectionPieBox, .legPieBox { background-color: #F9FCFF; } -.collectionStatus td, .collectionStatus th { - text-align: right; -} - -td.collectionName, th.collectionName { - text-align: left; -} - td.error { background-color: #CC0000; color: white; diff --git a/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/collectionStatus.js b/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/collectionStatus.js index ea7e52144..d45389f16 100644 --- a/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/collectionStatus.js +++ b/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/collectionStatus.js @@ -111,15 +111,15 @@ function makeCollectionRow(collection) { let id = collection.collectionID; let html = ""; html += ""; - html += "" + id + "
"; - html += ""; - html += ""; - html += ""; - html += ""; - html += ""; - html += " "; - html += " "; - html += ""; + html += "" + id + "
"; + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; return html; } diff --git a/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/pillar-details.js b/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/pillar-details.js new file mode 100644 index 000000000..3c62b66bf --- /dev/null +++ b/bitrepository-webclient/src/main/webapp/static/js/dashboard_components/pillar-details.js @@ -0,0 +1,27 @@ +/** + * Appends the information from the pillar details JSON as rows to a table with the given ID. + * @param pillarDetails JSON containing the pillar details to build the rows from + * @param tableBodyId ID of the table to append the rows to + */ +function fillInPillarDetailsTable(pillarDetails, tableBodyId) { + pillarDetails.forEach((detail) => { + $(tableBodyId).append(makePillarDetailsRow(detail)); + }); +} + +/** + * Make a row in the pillar details table given the pillar details JSON. + * @param details Pillar details from ReferenceSettings-file as JSON + * @returns {string} HTML table row containing the pillar details + */ +function makePillarDetailsRow(details) { + let html = ""; + html += ""; + html += "" + details.pillarID + ""; + html += "" + details.pillarName + ""; + html += "" + details.pillarType + ""; + html += "" + details.pillarDeleteFileApprover + ""; + html += ""; + return html; +} + diff --git a/bitrepository-webclient/src/main/webapp/static/js/views/dashboard-page.js b/bitrepository-webclient/src/main/webapp/static/js/views/dashboard-page.js index 2c7a9e9cb..66daf2c31 100644 --- a/bitrepository-webclient/src/main/webapp/static/js/views/dashboard-page.js +++ b/bitrepository-webclient/src/main/webapp/static/js/views/dashboard-page.js @@ -4,8 +4,8 @@ let nameMapper; let dsGraph; function init() { - $.get('repo/urlservice/integrityService', {}, function (url) { - setIntegrityServiceUrl(url); + $.get('repo/urlservice/integrityService', {}, function (integrityUrlBase) { + setIntegrityServiceUrl(integrityUrlBase); $.get("repo/reposervice/getRepositoryName/", {}, function (j) { $("#pageHeader").html("Overview of " + j); }, "html"); @@ -14,11 +14,11 @@ function init() { nameMapper = new CollectionNameMapper(collections); setNameMapper(nameMapper); initiateCollectionStatus(collections, "#collectionStatusBody", 10000); - let dataUrl = url + "/integrity/Statistics/getDataSizeHistory/?collectionID="; + let dataUrl = integrityUrlBase + "/integrity/Statistics/getDataSizeHistory/?collectionID="; dsGraph = new DataSizeGraph(collections, colorMapper, new FileSizeUtils(), dataUrl, "#graphType", "#dataSizeGraphPlaceholder"); makeCollectionSelectionCheckboxes("#dataSizeGraphCollectionSelection", dsGraph, colorMapper, nameMapper); - drawPillarDataSizePieChart(url + "/integrity/Statistics/getLatestPillarDataSize/"); - drawCollectionDataSizePieChart(url + "/integrity/Statistics/getLatestcollectionDataSize/", colorMapper); + drawPillarDataSizePieChart(integrityUrlBase + "/integrity/Statistics/getLatestPillarDataSize/"); + drawCollectionDataSizePieChart(integrityUrlBase + "/integrity/Statistics/getLatestcollectionDataSize/", colorMapper); $("#graphType").on("change", function (event) { event.preventDefault(); dsGraph.graphTypeChanged(); }); @@ -26,10 +26,13 @@ function init() { // Update graphs every hour update_data_size_graph = setInterval(function () { dsGraph.updateData(); - drawPillarDataSizePieChart(url + "/integrity/Statistics/getLatestPillarDataSize/"); - drawCollectionDataSizePieChart(url + "/integrity/Statistics/getLatestcollectionDataSize/", colorMapper); + drawPillarDataSizePieChart(integrityUrlBase + "/integrity/Statistics/getLatestPillarDataSize/"); + drawCollectionDataSizePieChart(integrityUrlBase + "/integrity/Statistics/getLatestcollectionDataSize/", colorMapper); }, 3600000); }); + $.getJSON(integrityUrlBase + "/integrity/IntegrityService/getPillarDetails", {}, function (details) { + fillInPillarDetailsTable(details, "#pillarDetailsBody") + }); }, 'html'); }