Skip to content

Commit

Permalink
Merge pull request #146 from veraPDF/doc/swagger-dox
Browse files Browse the repository at this point in the history
DOC: Improve REST method documentation
  • Loading branch information
carlwilson authored Feb 8, 2024
2 parents 53ef00e + 6f2f9fc commit eb51387
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 306 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ public void run(VeraPdfRestConfiguration configuration,
Environment environment) {
// Create & register our REST resources
final ValidationExceptionMapper vem = new ValidationExceptionMapper();
ValidateResource validateResource = ValidateResource.getValidateResource();
validateResource.setMaxFileSize(configuration.getMaxFileSize());
ValidateResource validateResource = new ValidateResource();
ValidateResource.setMaxFileSize(configuration.getMaxFileSize());
environment.jersey().register(validateResource);
environment.jersey().register(new ApiResource());
environment.jersey().register(new HomePageResource());
Expand Down
117 changes: 53 additions & 64 deletions src/main/java/org/verapdf/rest/resources/ApiResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,75 +31,64 @@
*/
@Path("/api")
@Tag(name = "veraPDF")
@OpenAPIDefinition(info = @Info(
title = "veraPDF API",
description = "Rest API for veraPDF",
version = "V0.2.0",
license = @License(name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0")),
servers = {@Server(url = "https://demo.verapdf.org", description = "default"),
@Server(url = "https://dev.verapdf-rest.duallab.com", description = "dev"),
@Server(url = "http://localhost:8080", description = "local")}
)
@OpenAPIDefinition(info = @Info(title = "veraPDF API", description = "A REST service API for veraPDF", version = "V0.2.0", license = @License(name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0")), servers = {
@Server(url = "https://demo.verapdf.org", description = "default"),
@Server(url = "https://dev.verapdf-rest.duallab.com", description = "dev"),
@Server(url = "http://localhost:8080", description = "local") })

public final class ApiResource {
private static ReleaseDetails buildDetails = ReleaseDetails.addDetailsFromResource(
ReleaseDetails.APPLICATION_PROPERTIES_ROOT + "rest." + ReleaseDetails.PROPERTIES_EXT);
private static ReleaseDetails buildDetails = ReleaseDetails.addDetailsFromResource(
ReleaseDetails.APPLICATION_PROPERTIES_ROOT + "rest." + ReleaseDetails.PROPERTIES_EXT);

@GET
@Path("/")
@Operation(summary = "Get release details")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/json", schema =
@Schema(implementation = ReleaseDetails.class)
), @Content(mediaType = "application/xml", schema =
@Schema(implementation = ReleaseDetails.class)
)})})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public static ReleaseDetails getReleaseDetails() {
return buildDetails;
}
@GET
@Path("/")
@Operation(summary = "Returns the release details of the veraPDF library used by the server.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Release details successfully returned.", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = ReleaseDetails.class)),
@Content(mediaType = "application/xml", schema = @Schema(implementation = ReleaseDetails.class)) }) })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public static ReleaseDetails getReleaseDetails() {
return buildDetails;
}

/**
* @return the server environment information as a
* {@link org.verapdf.rest.environment.Environment}.
*/
@GET
@Path("/info")
@Operation(summary = "Get server environment information")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/json", schema =
@Schema(implementation = Environment.class)
), @Content(mediaType = "application/xml", schema =
@Schema(implementation = Environment.class)
)})})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public static Environment getEnvironment() {
return Environments.getEnvironment();
}
/**
* @return the server environment information as a
* {@link org.verapdf.rest.environment.Environment}.
*/
@GET
@Path("/info")
@Operation(summary = "Returns relavent server information, such as JDK version, OS, etc.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Server environment details successfully returned.", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = Environment.class)),
@Content(mediaType = "application/xml", schema = @Schema(implementation = Environment.class)) }) })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public static Environment getEnvironment() {
return Environments.getEnvironment();
}

/**
* @return a new {@link org.verapdf.rest.resources.ProfileResource}
*/
@Path("/profiles")
public static ProfileResource getProfileResource() {
return new ProfileResource();
}
/**
* @return a new {@link org.verapdf.rest.resources.ProfileResource}
*/
@Path("/profiles")
public static ProfileResource getProfileResource() {
return new ProfileResource();
}

/**
* @return a new {@link org.verapdf.rest.resources.ValidateResource}
*/
@Path("/validate")
public static ValidateResource getValidateResource() {
return ValidateResource.getValidateResource();
}
/**
* @return a new {@link org.verapdf.rest.resources.ValidateResource}
*/
@Path("/validate")
public static ValidateResource getValidateResource() {
return new ValidateResource();
}

/**
* @return a new {@link ByteStreamResource}
*/
@Path("/sha1")
public static ByteStreamResource getBytestreamResource() {
return new ByteStreamResource();
}
/**
* @return a new {@link ByteStreamResource}
*/
@Path("/sha1")
public static ByteStreamResource getBytestreamResource() {
return new ByteStreamResource();
}
}
173 changes: 95 additions & 78 deletions src/main/java/org/verapdf/rest/resources/ByteStreamResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,99 +3,116 @@
*/
package org.verapdf.rest.resources;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.openpreservation.bytestreams.ByteStreamId;
import org.openpreservation.bytestreams.ByteStreams;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterStyle;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.openpreservation.bytestreams.ByteStreamId;
import org.openpreservation.bytestreams.ByteStreams;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;


/**
* The REST resource definition for byte stream identification services, these
* are JERSEY REST services and it's the annotations that perform the magic of
* handling content types and serialisation.
*
* @author <a href="mailto:[email protected]">Carl Wilson</a>.</p>
* @author <a href="mailto:[email protected]">Carl Wilson</a>.
* </p>
*/
public class ByteStreamResource {
/**
* Default public constructor required by Jersey / Dropwizard
*/
public ByteStreamResource() {
/** Intentionally blank */
}
private static final String EMPTY_SHA_XML = "<ByteStreamId>\n" + //
" <hexSHA1>da39a3ee5e6b4b0d3255bfef95601890afd80709</hexSHA1>\n" + //
" <length>0</length>\n" + //
"</ByteStreamId>" + //
"";
private static final String EMPTY_SHA_JSON = "{\n" + //
" \"hexSHA1\": \"da39a3ee5e6b4b0d3255bfef95601890afd80709\",\n" + //
" \"length\": 0\n" + //
"}";
private static final String TEST_SHA_XML = "<ByteStreamId>\n" + //
" <hexSHA1>a94a8fe5ccb19ba61c4c0873d391e987982fbbd3</hexSHA1>\n" + //
" <length>4</length>\n" + //
"</ByteStreamId>" + //
"";
private static final String TEST_SHA_JSON = "{\n" + //
" \"hexSHA1\": \"a94a8fe5ccb19ba61c4c0873d391e987982fbbd3\",\n" + //
" \"length\": 4\n" + //
"}";

/**
* Default public constructor required by Jersey / Dropwizard
*/
public ByteStreamResource() {
/** Intentionally blank */
}

/**
* @param uploadedInputStream
* InputStream for the uploaded file
* @param contentDispositionHeader
* extra info about the uploaded file, currently unused.
* @return the {@link org.openpreservation.bytestreams.ByteStreamId} of
* the uploaded file's byte stream serialised according to requested
* content type.
*/
@POST
@Operation(summary = "Upload file's byte stream and serialise according to requested content type")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/xml", schema =
@Schema(implementation = ByteStreamId.class)),
@Content(mediaType = "application/json", schema =
@Schema(implementation = ByteStreamId.class)),
@Content(mediaType = "text/xml", schema =
@Schema(implementation = ByteStreamId.class))
})})
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML})
public static ByteStreamId getSha1(
@Parameter(name = "file", schema = @Schema(implementation = File.class), style = ParameterStyle.FORM,
description = "InputStream for the uploaded file")
@FormDataParam("file") InputStream uploadedInputStream,
@Parameter(hidden = true) @FormDataParam("file") final FormDataContentDisposition contentDispositionHeader) {
try {
ByteStreamId id = ByteStreams.idFromStream(uploadedInputStream);
uploadedInputStream.close();
return id;// return
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ByteStreams.nullByteStreamId();
}
/**
* @param uploadedInputStream
* InputStream for the uploaded file
* @param contentDispositionHeader
* extra info about the uploaded file, currently
* unused.
* @return the {@link org.openpreservation.bytestreams.ByteStreamId} of
* the uploaded file's byte stream serialised according to requested
* content type.
* @throws IOException
*/
@POST
@Operation(summary = "Calculates and returns the SHA1 and length of the uploaded file.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/xml", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Test file.", value = TEST_SHA_XML, summary = "Test file SHA1 as XML", externalValue = "/examples/test.txt")),
@Content(mediaType = "application/json", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Test file.", value = TEST_SHA_JSON, summary = "Test file SHA1 as JSON", externalValue = "/examples/test.txt")),
@Content(mediaType = "text/xml", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Test file.", value = TEST_SHA_XML, summary = "Test file SHA1 as XML", externalValue = "/examples/test.txt"))
}),
@ApiResponse(responseCode = "500", description = "Server error when processing the request.")
})
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML })
public static ByteStreamId getSha1(
@Parameter(name = "file", schema = @Schema(implementation = File.class), style = ParameterStyle.FORM, description = "File uploaded for SHA1 calculation.") @FormDataParam("file") InputStream uploadedInputStream,
@Parameter(hidden = true) @FormDataParam("file") final FormDataContentDisposition contentDispositionHeader)
throws IOException {
ByteStreamId id = ByteStreams.idFromStream(uploadedInputStream);
uploadedInputStream.close();
return id;// return
}

/**
* @return the {@link org.openpreservation.bytestreams} of
* an empty (0 byte) byte stream serialised according to requested
* content type.
*/
@GET
@Path("/null")
@Operation(summary = "Get byte streams of an empty byte stream serialised according to requested content type")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/xml", schema =
@Schema(implementation = ByteStreamId.class)),
@Content(mediaType = "application/json", schema =
@Schema(implementation = ByteStreamId.class)),
@Content(mediaType = "text/xml", schema =
@Schema(implementation = ByteStreamId.class))
})})
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML})
public static ByteStreamId getEmptySha1() {
return ByteStreams.nullByteStreamId();
}
/**
* @return the {@link org.openpreservation.bytestreams} of
* an empty (0 byte) byte stream serialised according to requested
* content type.
*/
@GET
@Path("/null")
@Operation(summary = "Returns the SHA1 and zero length of a null byte stream.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/xml", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Empty SHA1", value = EMPTY_SHA_XML, summary = "Empty SHA1 as XML")),
@Content(mediaType = "application/json", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Empty SHA1", value = EMPTY_SHA_JSON, summary = "Empty SHA1 as JSON")),
@Content(mediaType = "text/xml", schema = @Schema(implementation = ByteStreamId.class), examples = @ExampleObject(name = "Empty SHA1", value = EMPTY_SHA_XML, summary = "Empty SHA1 as XML"))
}) })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML })
public static ByteStreamId getEmptySha1() {
return ByteStreams.nullByteStreamId();
}
}
Loading

0 comments on commit eb51387

Please sign in to comment.