Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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
1 change: 1 addition & 0 deletions docker-java-shaded/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package org.jenkinsci.plugins.docker.traceability.core;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import hudson.BulkChange;
import hudson.Extension;
import hudson.XmlFile;
Expand Down Expand Up @@ -341,16 +342,16 @@ public void doImage(StaplerRequest req, StaplerResponse rsp,
//TODO: filtering by container ID, imageID, containerName, imageName, hostName, hostID, environment
/**
* Retrieves the latest container status via API.
* The output will be retrieved in JSON. Supports filers. Missing
* "since" and "until"
* Supports filers. Missing "since" and "until"
* @param id ID of the container, for which the info should be retrieved.
* Short container IDs are not supported.
* @param format Format used in the response
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to say waht formats are acceptable (ie link to the enum?)

* @throws IOException Processing error
* @throws ServletException Servlet error
* @return Raw JSON output compatible with docker inspect
* @return Response available in different formats, including a JSON output compatible with docker inspect
*/
public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String id)
throws IOException, ServletException {
public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String id, @QueryParameter(required = false) final String format)
throws IOException, ServletException {
checkPermission(DockerTraceabilityPlugin.READ_DETAILS);

//TODO: check containerID format
Expand All @@ -364,9 +365,8 @@ public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String i
return HttpResponses.error(500, "Cannot retrieve the container's status");
}

// Return raw JSON in the response
InspectContainerResponse[] out = {inspectInfo};
return toJSONResponse(out);
return toFormattedResponse(out, format);
}

//TODO: More filtering
Expand All @@ -380,15 +380,17 @@ public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String i
* If the value equals to 0, the filter will be ignored (default in {@link QueryParameter}).
* @param until End time.
* If the value equals to 0, the filter will be ignored (default in {@link QueryParameter}).
* @param format Format used in the response.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the format of format is...

* @throws IOException Processing error
* @throws ServletException Servlet error
* @return Response containing the output JSON. may be an error if something breaks.
* @return Response available in different formats. may be an error if something breaks.
*/
public HttpResponse doQueryContainer(
@QueryParameter(required = true) String id,
@QueryParameter(required = false) String mode,
@QueryParameter(required = false) long since,
@QueryParameter(required = false) long until)
@QueryParameter(required = false) long until,
@QueryParameter(required = false) String format)
throws IOException, ServletException {
checkPermission(DockerTraceabilityPlugin.READ_DETAILS);

Expand Down Expand Up @@ -439,31 +441,32 @@ public HttpResponse doQueryContainer(
}
}

// Return raw JSON in the response
return toJSONResponse(result);
return toFormattedResponse(result, format);
}

/**
* Retrieves the latest raw status via API.
* The output will be retrieved in JSON.
*
* @param id ID of the image, for which the info should be retrieved.
* Short container IDs are not supported.
* @param format Format used in the output response.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like this in format Bob please.

*
* @throws IOException Processing error
* @throws ServletException Servlet error
* @return {@link HttpResponse}
*
* @return Response ({@link HttpResponse}) available in different formats
*/
public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id)
throws IOException, ServletException {
public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id, @QueryParameter(required = false) String format)
throws IOException, ServletException {
checkPermission(DockerTraceabilityPlugin.READ_DETAILS);

final InspectImageResponse report = DockerTraceabilityHelper.getLastInspectImageResponse(id);
if (report == null) {
return HttpResponses.error(404, "No info available for the imageId=" + id);
}

// Return raw JSON in the response
InspectImageResponse[] out = {report};
return toJSONResponse(out);
return toFormattedResponse(out, format);
}

/**
Expand Down Expand Up @@ -564,18 +567,69 @@ private synchronized void load() {
LOGGER.log(Level.SEVERE, "Failed to load the configuration from config path = "+config,e);
}
}


/**
* Represents the different response formats (JSON, pretty JSON, XML).
*/
private enum ResponseFormat {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use the enum value in the web request and get stapler to parse and covert it for you?

JSON("application/json;charset=UTF-8", false),
PRETTYJSON("application/json;charset=UTF-8", true),
XML("text/xml;charset=UTF-8", false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so wheres the PRETTYXML?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtnord XML and XMLPRETTY will be supported when this ticket is done https://issues.jenkins-ci.org/browse/JENKINS-28727


private String contentType;

private boolean pretty;

private static final ResponseFormat DEFAULT = JSON;

private ResponseFormat(final String contentType, final boolean pretty) {
this.contentType = contentType;
this.pretty = pretty;
}

public static ResponseFormat fromAlias(final String alias) {
if (alias == null) {
return DEFAULT;
}
if (alias.equals("json")) {
return JSON;
} else if (alias.equals("json-pretty")) {
return PRETTYJSON;
} else if (alias.equals("xml")) {
// Related to https://issues.jenkins-ci.org/browse/JENKINS-28727
throw new IllegalStateException("Unsupported format: " + alias);
} else {
throw new IllegalStateException("Unsupported format: " + alias);
}
}

public String getContentType() {
return contentType;
}

public boolean getPretty() {
return pretty;
}
}

/**
* Serves the JSON response.
* @param item Data to be serialized to JSON
* @return HTTP response with application/json MIME type
* Serves the response and manages its output format in the response.
*
* @param item Data to be serialized
* @param format Format used in the response
*
* @return HTTP response with MIME type
*/
private static HttpResponse toJSONResponse(final Object item) {
private static HttpResponse toFormattedResponse(final Object item, final String format) {
return new HttpResponse() {
@Override
public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
ObjectMapper mapper = new ObjectMapper();
rsp.setContentType("application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
ResponseFormat responseFormat = ResponseFormat.fromAlias(format);
rsp.setContentType(responseFormat.getContentType());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This smells to me. When you introduce a new enum (XML) this code will break but without any compile time safety.

this should be moved to a switch case to get the compile time safety - or the logic of the formatter should be moved into the enum IMHO.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtnord Sure. I'm going to think about an alternative way.

if (responseFormat.getPretty()) {
mapper.enable(SerializationFeature.INDENT_OUTPUT);
}
mapper.writeValue(rsp.getWriter(), item);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import org.jenkinsci.plugins.docker.traceability.api.DockerTraceabilityReport;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.IOException;
import org.jenkinsci.plugins.docker.traceability.samples.JSONSamples;
import static org.junit.Assert.assertEquals;
Expand All @@ -41,6 +42,7 @@ public class DockerTraceabilityReportTest {
@Test
public void jsonRoundTrip() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
DockerTraceabilityReport report = JSONSamples.submitReport.readObject(DockerTraceabilityReport.class);
assertNotNull(report.getContainer());
assertNotNull(report.getEvent());
Expand Down