Single download link for the entire page. Added date range begin and end fields. Pass timestamp to controller to filter reports. Format file in CSV.

This commit is contained in:
chubtub 2021-01-14 08:22:11 -05:00
parent 3cd9e06f97
commit 4acfbf3026
2 changed files with 158 additions and 94 deletions

View File

@ -10,6 +10,7 @@ import hirs.data.persist.certificate.PlatformCredential;
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.persist.CertificateManager;
import hirs.persist.DeviceManager;
import org.apache.logging.log4j.Logger;
import static org.apache.logging.log4j.LogManager.getLogger;
import org.hibernate.Criteria;
@ -20,7 +21,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@ -35,6 +35,10 @@ import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.UUID;
@ -47,21 +51,26 @@ public class ValidationReportsPageController extends PageController<NoPageParams
private final CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager;
private final CertificateManager certificateManager;
private final DeviceManager deviceManager;
private static final Logger LOGGER = getLogger(ValidationReportsPageController.class);
private static final String DEFAULT_COMPANY = "AllDevices";
/**
* Constructor providing the Page's display and routing specification.
* @param supplyChainValidatorSummaryManager the manager
* @param certificateManager the certificate manager
* @param deviceManager the device manager
*/
@Autowired
public ValidationReportsPageController(
final CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager,
final CertificateManager certificateManager) {
final CertificateManager certificateManager,
final DeviceManager deviceManager) {
super(VALIDATION_REPORTS);
this.supplyChainValidatorSummaryManager = supplyChainValidatorSummaryManager;
this.certificateManager = certificateManager;
this.deviceManager = deviceManager;
}
/**
@ -128,70 +137,127 @@ public class ValidationReportsPageController extends PageController<NoPageParams
* - Component Status column is 8 component classes names listed above
* (Component Status data is taken from the pass/fail status of the report summary)
* - Device Status is the overall pass/fail of the report summary
* @param id of the validated device
* @param deviceName name of the validated device
* @param request object
* @param response object
* @throws IOException thrown by BufferedWriter object
*/
@RequestMapping(value = "download", method = RequestMethod.POST)
public void download(@RequestParam final String id,
@RequestParam final String deviceName,
final HttpServletRequest request,
public void download(final HttpServletRequest request,
final HttpServletResponse response) throws IOException {
LOGGER.info("Downloading validation report for " + id);
response.setHeader("Content-Type", "text/plain");
response.setHeader("Content-Disposition",
"attachment;filename=\"" + deviceName + "_validation_report.txt\"");
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
LOGGER.info("Downloading validation report");
String company = "";
String contractNumber = "";
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("MM/dd/uuuu");
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
LocalDate startDate = null;
LocalDate endDate = null;
ArrayList<LocalDate> createTimes = new ArrayList<LocalDate>();
String[] deviceNames = new String[]{};
Enumeration parameters = request.getParameterNames();
while (parameters.hasMoreElements()) {
String parameter = (String) parameters.nextElement();
bufferedWriter.append(parameter + ": " + request.getParameter(parameter) + "\n");
LOGGER.info(parameter + ": " + request.getParameter(parameter));
String parameterValue = request.getParameter(parameter);
switch (parameter) {
case "company":
company = parameterValue;
break;
case "contract":
contractNumber = parameterValue;
break;
case "dateStart":
if (parameterValue != null && !parameterValue.isEmpty()) {
startDate = LocalDate.parse(parameterValue, dateFormat);
}
break;
case "dateEnd":
if (parameterValue != null && !parameterValue.isEmpty()) {
endDate = LocalDate.parse(parameterValue, dateFormat);
}
break;
case "createTimes":
String[] timestamps = parameterValue.split(",");
for (String timestamp : timestamps) {
createTimes.add(LocalDateTime.parse(timestamp,
dateTimeFormat).toLocalDate());
LOGGER.info("Create time added: "
+ createTimes.get(createTimes.size() - 1));
}
break;
case "deviceNames":
deviceNames = parameterValue.split(",");
break;
default:
}
LOGGER.info(parameter + ": " + parameterValue);
}
// String columnHeaders = "Company, Contract Number, Date Range, Verified Manufacturer, "
// + "Model, SN, Verification Date, Component Statuses, Device Status";
// bufferedWriter.append(columnHeaders + "\n");
// LOGGER.info(columnHeaders);
UUID uuid = UUID.fromString(id);
PlatformCredential pc = PlatformCredential.select(certificateManager)
.byDeviceId(uuid).getCertificate();
bufferedWriter.append("Verified manufacturer: " + pc.getManufacturer() + "\n");
bufferedWriter.append("Model: " + pc.getModel() + "\n");
bufferedWriter.append("SN: " + pc.getChassisSerialNumber() + "\n");
bufferedWriter.append("Verification date: " + pc.getBeginValidity() + "\n");
LOGGER.info("Verified manufacturer: " + pc.getManufacturer());
LOGGER.info("Model: " + pc.getModel());
LOGGER.info("SN: " + pc.getChassisSerialNumber());
LOGGER.info("Verification date: " + pc.getBeginValidity());
if (pc.getComponentIdentifiers() != null
&& pc.getComponentIdentifiers().size() > 0) {
for (ComponentIdentifier ci : pc.getComponentIdentifiers()) {
if (ci instanceof ComponentIdentifierV2) {
bufferedWriter.append(((ComponentIdentifierV2) ci).getComponentClass()
+ "\nComponent status: "
+ ((ComponentIdentifierV2) ci).getAttributeStatus() + "\n");
LOGGER.info(((ComponentIdentifierV2) ci).getComponentClass()
+ "\nComponent status: "
+ ((ComponentIdentifierV2) ci).getAttributeStatus());
} else {
bufferedWriter.append("Platform Components" + "\n");
LOGGER.info("Platform Components");
if (company.equals("")) {
company = DEFAULT_COMPANY;
}
if (contractNumber.equals("")) {
contractNumber = "none";
}
if (startDate == null) {
startDate = LocalDate.ofEpochDay(0);
}
if (endDate == null) {
endDate = LocalDate.now();
}
LOGGER.info("Start date: " + startDate.toString() + ", end date: " + endDate.toString());
response.setHeader("Content-Type", "text/csv");
response.setHeader("Content-Disposition",
"attachment;filename=\"validation_report.csv\"");
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
String columnHeaders = "Verified Manufacturer, "
+ "Model, SN, Verification Date, Component Statuses, Device Status";
bufferedWriter.append("Contract number: " + contractNumber + "\n");
bufferedWriter.append(columnHeaders + "\n");
LOGGER.info(columnHeaders);
for (int i = 0; i < deviceNames.length; i++) {
if ((createTimes.get(i).isAfter(startDate) || createTimes.get(i).isEqual(startDate))
&& (createTimes.get(i).isBefore(endDate)
|| createTimes.get(i).isEqual(endDate))) {
UUID deviceId = deviceManager.getDevice(deviceNames[i]).getId();
LOGGER.info(deviceId);
PlatformCredential pc = PlatformCredential.select(certificateManager)
.byDeviceId(deviceId).getCertificate();
LOGGER.info("Found platform credential: " + pc.toString());
bufferedWriter.append(pc.getManufacturer() + ","
+ pc.getModel() + ","
+ pc.getChassisSerialNumber() + ","
+ pc.getBeginValidity() + ",");
LOGGER.info("Verified manufacturer: " + pc.getManufacturer());
LOGGER.info("Model: " + pc.getModel());
LOGGER.info("SN: " + pc.getChassisSerialNumber());
LOGGER.info("Verification date: " + pc.getBeginValidity());
if (pc.getComponentIdentifiers() != null
&& pc.getComponentIdentifiers().size() > 0) {
String attributeStatuses = "";
for (ComponentIdentifier ci : pc.getComponentIdentifiers()) {
if (ci instanceof ComponentIdentifierV2) {
attributeStatuses += ((ComponentIdentifierV2) ci)
.getAttributeStatus() + ",";
LOGGER.info(((ComponentIdentifierV2) ci).getComponentClass()
+ "\nComponent status: "
+ ((ComponentIdentifierV2) ci).getAttributeStatus());
} else {
//("Platform Components" + "\n");
LOGGER.info("\nPlatform Components");
}
LOGGER.info("Component manufacturer : "
+ ci.getComponentManufacturer().getString()
+ "\nComponent model: " + ci.getComponentModel().getString()
+ "\nComponent revision: " + ci.getComponentRevision().getString());
}
attributeStatuses = attributeStatuses.substring(0,
attributeStatuses.length() - 1);
bufferedWriter.append("(" + attributeStatuses + "),");
}
bufferedWriter.append("Component manufacturer : "
+ ci.getComponentManufacturer().getString()
+ "\nComponent model: " + ci.getComponentModel().getString()
+ "\nComponent revision: " + ci.getComponentRevision().getString() + "\n");
LOGGER.info("Component manufacturer : "
+ ci.getComponentManufacturer().getString()
+ "\nComponent model: " + ci.getComponentModel().getString()
+ "\nComponent revision: " + ci.getComponentRevision().getString());
bufferedWriter.append("" + pc.getDevice().getSupplyChainStatus() + "\n");
}
}
bufferedWriter.flush();
}
}

View File

@ -25,6 +25,17 @@
<c:set var="errorText" value="Validation Error"/>
<c:set var="unknownText" value="Unknown Validation Status"/>
<form:form id="download" method="POST" action="${portal}/validation-reports/download">
Download Validation Reports
<my:download-info id="validationReportsDownload" label="Download Validation Reports">
<label>Company<input id="company" type="text" name="company" /></label>
<label>Contract #<input id="contract" type="text" name="contract" /></label>
<br>
<label>Date range start (mm/dd/yyyy)<input id="dateStart" type="text" name="dateStart" /></label>
<label>Date range end (mm/dd/yyyy)<input id="dateEnd" type="text" name="dateEnd" /></label>
</my:download-info>
</form:form>
<div class="aca-data-table">
<table id="reportTable" class="display" width="100%">
<thead>
@ -93,10 +104,7 @@
{
// TODO render a link to a device details page,
// passing the device.id
data: 'device.name',
render: function (data, type, full, meta) {
return createDownloadLink(full);
}
data: 'device.name'
},
{
data: 'id',
@ -129,44 +137,34 @@
dataTable.order([1, 'desc']).draw(); //order by createTime
});
/**
* This method builds a url to download the device validation report.
*/
function createDownloadLink(full) {
var device = full.device;
var deviceStatus = full.overallValidationResult;
var html = '<form method="POST" action="${portal}/validation-reports/download?id=' + device.id +
'&deviceName=' + device.name + '">' +
device.name +
'<a href="#downloadValidationReport" data-toggle="modal" title="Download Validation Report">' +
'<img src="${icons}/ic_file_download_black_24dp.png"/>' +
'</a>' +
'<div id="downloadValidationReport" class="modal fade" role="dialog" style="top:30%">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h1 id="modal-title">Download Validation Report</h1>' +
'</div>' +
'<div class="modal-body">' +
'<label>Company<input id="company" type="text" name="company" /></label>' +
'<label>Contract #<input id="contract" type="text" name="contract" /></label>' +
'<label>Date range end<input id="date" type="text" name="date" /></label>' +
'<input id="deviceStatus" type="hidden" name="deviceStatus" value="' +
deviceStatus + '" />' +
'</div>' +
'<div class="modal-footer">' +
'<div class="modal-custom-buttons">' +
'</div>' +
'<button class="btn btn-secondary" data-dismiss="modal">Cancel</button>' +
'<input class="btn btn-primary" type="submit" value="Save">' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</form>';
return html;
}
$("#download").submit(function(e) {
var tableLength = $("#reportTable").rows;
var createTimes = "";
var deviceNames = "";
$('#reportTable tr').not('thead tr').each(function() {
createTimes += $(this).find("td").eq(1).html() + ",";
deviceNames += $(this).find("td").eq(2).html() + ",";
});
createTimes = createTimes.substring(0, createTimes.length - 1);
deviceNames = deviceNames.substring(0, deviceNames.length - 1);
var params = [
{
name: 'createTimes',
value: createTimes
},
{
name: 'deviceNames',
value: deviceNames
}
];
$(this).append($.map(params, function(param) {
return $('<input>', {
type: 'hidden',
name: param.name,
value: param.value
});
}));
});
/**
* Gets HTML to display (icon tag) for the specified validation type.