Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
Expand Down Expand Up @@ -75,7 +76,10 @@ public class KscRestService extends OnmsRestService {
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML})
@Transactional
public KscReportCollection getReports() throws ParseException {
final KscReportCollection reports = new KscReportCollection(m_kscReportService.getReportMap(), true);
// Non-terse: include each report's graphs so the list can show a graph
// count and callers can edit a report from the list without a broken,
// graph-less copy (a terse list once caused edits to overwrite graphs).
final KscReportCollection reports = new KscReportCollection(m_kscReportService.getReportMap(), false);
reports.setTotalCount(reports.size());
return reports;
}
Expand Down Expand Up @@ -165,46 +169,97 @@ public Response addGraph(@PathParam("kscReportId") final Integer kscReportId, @Q
}

@POST
@Consumes(MediaType.APPLICATION_XML)
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response addKscReport(@Context final UriInfo uriInfo, final KscReport kscReport) {
writeLock();
try {
LOG.debug("addKscReport: Adding KSC Report {}", kscReport);
Report report = m_kscReportFactory.getReportByIndex(kscReport.getId());
if (report != null) {
// A supplied id must not collide with an existing report; a null id
// means "assign the next available one" (addReport does that on save).
if (kscReport.getId() != null && m_kscReportFactory.getReportByIndex(kscReport.getId()) != null) {
throw getException(Status.CONFLICT, "Invalid request: Existing KSC report found with ID: {}.", Integer.toString(kscReport.getId()));
}
report = new Report();
report.setId(kscReport.getId());
report.setTitle(kscReport.getLabel());
if (kscReport.getShowGraphtypeButton() != null) {
report.setShowGraphtypeButton(kscReport.getShowGraphtypeButton());
}
if (kscReport.getShowTimespanButton() != null) {
report.setShowTimespanButton(kscReport.getShowTimespanButton());
}
if (kscReport.getGraphsPerLine() != null) {
report.setGraphsPerLine(kscReport.getGraphsPerLine());
}
if (kscReport.hasGraphs()) {
for (KscGraph kscGraph : kscReport.getGraphs()) {
final Graph graph = kscGraph.buildGraph();
report.addGraph(graph);
}
final Report report = new Report();
if (kscReport.getId() != null) {
report.setId(kscReport.getId());
}
applyReportFields(kscReport, report);

m_kscReportFactory.addReport(report);
try {
m_kscReportFactory.saveCurrent();
} catch (final Exception e) {
throw getException(Status.BAD_REQUEST, e.getMessage());
}
return Response.created(getRedirectUri(uriInfo, kscReport.getId())).build();
return Response.created(getRedirectUri(uriInfo, report.getId())).build();
} finally {
writeUnlock();
}
}

@POST
@Path("{reportId}")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Transactional
public Response updateKscReport(@PathParam("reportId") final Integer reportId, final KscReport kscReport) {
writeLock();
try {
if (m_kscReportFactory.getReportByIndex(reportId) == null) {
throw getException(Status.NOT_FOUND, "No such report id {}.", Integer.toString(reportId));
}
final Report report = new Report();
report.setId(reportId);
applyReportFields(kscReport, report);
m_kscReportFactory.setReport(reportId, report);
try {
m_kscReportFactory.saveCurrent();
} catch (final Exception e) {
throw getException(Status.INTERNAL_SERVER_ERROR, "Cannot save report with Id {} : {} ", reportId.toString(), e.getMessage());
}
return Response.noContent().build();
} finally {
writeUnlock();
}
}

@DELETE
@Path("{reportId}")
@Transactional
public Response deleteKscReport(@PathParam("reportId") final Integer reportId) {
writeLock();
try {
if (m_kscReportFactory.getReportByIndex(reportId) == null) {
throw getException(Status.NOT_FOUND, "No such report id {}.", Integer.toString(reportId));
}
try {
m_kscReportFactory.deleteReportAndSave(reportId);
} catch (final Exception e) {
throw getException(Status.INTERNAL_SERVER_ERROR, "Cannot delete report with Id {} : {} ", reportId.toString(), e.getMessage());
}
return Response.noContent().build();
} finally {
writeUnlock();
}
}

private static void applyReportFields(final KscReport source, final Report target) {
target.setTitle(source.getLabel());
if (source.getShowGraphtypeButton() != null) {
target.setShowGraphtypeButton(source.getShowGraphtypeButton());
}
if (source.getShowTimespanButton() != null) {
target.setShowTimespanButton(source.getShowTimespanButton());
}
if (source.getGraphsPerLine() != null) {
target.setGraphsPerLine(source.getGraphsPerLine());
}
if (source.hasGraphs()) {
for (final KscGraph kscGraph : source.getGraphs()) {
target.addGraph(kscGraph.buildGraph());
}
}
}

@XmlRootElement(name = "kscReports")
public static final class KscReportCollection extends JaxbListWrapper<KscReport> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@
{
"id": "kscReports",
"name": "Graph Collections",
"url": "ui/index.html#/graph-collections",
"locationMatch": "graph-collections",
"roles": null
},
{
"id": "kscReportsLegacy",
"name": "Graph Collections (Legacy)",
"url": "KSC/index.jsp",
"locationMatch": "ksc",
"roles": null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,66 @@ public void testAddNewGraph() throws Exception {
assertTrue(xml, xml.contains("title=\"foo2\""));
}

@Test
public void testListIncludesGraphs() throws Exception {
// The list is non-terse: each report carries its graphs, not just id/label.
final String xml = sendRequest(GET, "/ksc", 200);
assertTrue(xml, xml.contains("graphtype=\"ssh\""));
}

@Test
public void testCreateAssignsId() throws Exception {
// No id attribute -> the server assigns the next available id.
final String body = "<kscReport label=\"AutoId\">"
+ "<kscGraph title=\"auto\" resourceId=\"node[1].nodeSnmp[]\" timespan=\"1_hour\" graphtype=\"mib2.tcpopen\"/>"
+ "</kscReport>";
sendPost("/ksc", body, 201);

// The config file uses the JAXB Report's "title" attribute, not the DTO's "label".
final String xml = slurp(m_configFile);
assertTrue(xml, xml.contains("title=\"AutoId\""));
}

@Test
public void testUpdateReportReplacesContents() throws Exception {
final String create = "<kscReport id=\"7\" label=\"ToEdit\">"
+ "<kscGraph title=\"g1\" resourceId=\"node[1].nodeSnmp[]\" timespan=\"7_day\" graphtype=\"mib2.tcpopen\"/>"
+ "</kscReport>";
sendPost("/ksc", create, 201, "/ksc/7");

final String update = "<kscReport id=\"7\" label=\"Edited\" graphs_per_line=\"3\">"
+ "<kscGraph title=\"g2\" resourceId=\"node[1].nodeSnmp[]\" timespan=\"1_day\" graphtype=\"mib2.tcpopen\"/>"
+ "</kscReport>";
sendPost("/ksc/7", update, 204);

final String xml = slurp(m_configFile);
assertTrue(xml, xml.contains("title=\"Edited\""));
assertTrue(xml, xml.contains("title=\"g2\""));
// Full replace: the previous graph is gone.
assertTrue(xml, !xml.contains("title=\"g1\""));
}

@Test
public void testUpdateMissingReport() throws Exception {
sendPost("/ksc/99", "<kscReport id=\"99\" label=\"nope\"/>", 404);
}

@Test
public void testDeleteReport() throws Exception {
final String create = "<kscReport id=\"8\" label=\"ToDelete\">"
+ "<kscGraph title=\"g\" resourceId=\"node[1].nodeSnmp[]\" timespan=\"7_day\" graphtype=\"mib2.tcpopen\"/>"
+ "</kscReport>";
sendPost("/ksc", create, 201, "/ksc/8");
sendRequest(GET, "/ksc/8", 200);
sendRequest(DELETE, "/ksc/8", 204);
sendRequest(GET, "/ksc/8", 404);
}

@Test
public void testDeleteMissingReport() throws Exception {
sendRequest(DELETE, "/ksc/99", 404);
}

private static String slurp(final File file) throws Exception {
Reader fileReader = null;
BufferedReader reader = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public void testMenuEntries() throws Exception {
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@class='card-header']/span")));

clickMenuItem("Dashboards", "Graph Collections");
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@class='card-header']/span[text()='Customized Reports']")));
// now the Vue page (ui/index.html)
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@id='app']//div[@class='card-title' and text()='Graph Collections']")));

clickMenuItem("Dashboards", "Surveillance Dashboard");
driver.switchTo().frame(findElementByXpath("/html/body/div//iframe"));
Expand Down
Loading
Loading