From 1e43da7b41b39c286ea52c3e51117a4bd8e3de94 Mon Sep 17 00:00:00 2001 From: Brian Long Date: Thu, 2 Feb 2023 22:42:38 -0500 Subject: [PATCH] added swagger docs --- pom.xml | 30 +++- .../java/com/poststats/golf/api/EventApi.java | 38 ++--- .../poststats/golf/api/EventFinanceApi.java | 70 +++++---- .../poststats/golf/api/EventPersonApi.java | 147 ++++++++++-------- .../com/poststats/golf/api/GolferApi.java | 24 +-- .../com/poststats/golf/api/SeriesApi.java | 49 +++--- 6 files changed, 205 insertions(+), 153 deletions(-) diff --git a/pom.xml b/pom.xml index 16f5cbe..0d780c4 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,8 @@ 11 true lines,vars,source + + 2.2.8 @@ -31,11 +33,6 @@ commons-csv 1.5 - - com.webcohesion.enunciate - enunciate-core-annotations - 2.14.0 - junit @@ -47,6 +44,29 @@ + + io.swagger.core.v3 + swagger-maven-plugin-jakarta + ${swagger.version} + + + com.poststats.golf.api + + ${project.build.outputDirectory}/META-INF + golf-swagger + JSONANDYAML + true + + + + swagger-generate + + resolve + + compile + + + io.repaint.maven tiles-maven-plugin diff --git a/src/main/java/com/poststats/golf/api/EventApi.java b/src/main/java/com/poststats/golf/api/EventApi.java index 78301ec..cffe2e8 100644 --- a/src/main/java/com/poststats/golf/api/EventApi.java +++ b/src/main/java/com/poststats/golf/api/EventApi.java @@ -2,11 +2,18 @@ package com.poststats.golf.api; import com.brianlong.sql.DataSet; import com.fasterxml.jackson.core.JsonProcessingException; -import com.poststats.api.BaseApi; +import com.poststats.api.Constants; import com.poststats.golf.api.model.Event; import com.poststats.golf.api.model.EventDetail; import com.poststats.golf.service.EventService; import com.poststats.golf.transformer.EventTransformer; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -15,19 +22,18 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This API provides access to PostStats Golf Event meta-data and features. - * * @author brian.long@poststats.com */ @RequestScoped -@Path(BaseApi.BASE_PATH + "/golf/event/{eventId}") -public class EventApi extends BaseApi { +@Path("/golf/event/{eventId}") +@Tag(name = "Event API") +@OpenAPIDefinition(info = @Info(contact = @Contact(name = "Brian Long", email = "brian.long@poststats.com"), title = "PostStats Golf API", description = "An API providing access to PostStats Golf objects.")) +public class EventApi { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -45,13 +51,11 @@ public class EventApi extends BaseApi { this.logger.debug("EventApi init: {}", this.eventId); } - /** - * @return An event model object. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified event was not found. - */ @GET - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves limited meta-data about an event.", description = "Retreives name, location, dates, and other direct meta-data about the specified event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) public Event get() throws JsonProcessingException { DataSet row = this.eventService.get(this.eventId); if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); @@ -59,14 +63,12 @@ public class EventApi extends BaseApi { return this.eventTransformer.toModel(row); } - /** - * @return An event model object. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified event was not found. - */ @GET @Path("/detail") - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves detailed meta-data about an event.", description = "Retreives name, location, dates, courses, and other indirect meta-data about the specified event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) public EventDetail getDetail() throws JsonProcessingException { DataSet row = this.eventService.getDetail(this.eventId); if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); diff --git a/src/main/java/com/poststats/golf/api/EventFinanceApi.java b/src/main/java/com/poststats/golf/api/EventFinanceApi.java index 69da446..4e8a94d 100644 --- a/src/main/java/com/poststats/golf/api/EventFinanceApi.java +++ b/src/main/java/com/poststats/golf/api/EventFinanceApi.java @@ -2,9 +2,12 @@ package com.poststats.golf.api; import com.brianlong.sql.DataSet; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.poststats.api.BaseApi; +import com.poststats.api.Constants; import com.poststats.golf.service.EventFinanceService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -12,10 +15,13 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.core.StreamingOutput; import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -24,10 +30,9 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; @RequestScoped -@Path(BaseApi.BASE_PATH + "/golf/event/{eventId}/finance") -public class EventFinanceApi extends BaseApi { - - private final ObjectMapper mapper = new ObjectMapper(); +@Path("/golf/event/{eventId}/finance") +@Tag(name = "Event Finance API") +public class EventFinanceApi { @PathParam("eventId") private long eventId; @@ -37,9 +42,12 @@ public class EventFinanceApi extends BaseApi { @GET @Path("/balance/persons") - @Produces(MediaType.APPLICATION_JSON) @RolesAllowed("member") - public String getBalanceByPersonsAsJson(@Context SecurityContext securityContext) throws JsonProcessingException { + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves the balances of all participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public List> getBalanceByPersonsAsJson(@Context SecurityContext securityContext) throws JsonProcessingException { if (!securityContext.isUserInRole(this.eventId + "~finance")) throw new SecurityException("Not permitted"); List personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); @@ -54,35 +62,41 @@ public class EventFinanceApi extends BaseApi { personsBalancesJson.add(personBalanceJson); } - return this.mapper.writeValueAsString(personsBalancesJson); + return personsBalancesJson; } @GET - @Path("/balance/persons/csv") - @Produces("text/csv") + @Path("/balance/persons") @RolesAllowed("member") - public String getBalanceByPersonsAsCsv(@Context SecurityContext securityContext) throws IOException { + @Produces("text/csv") + @Operation(summary = "Retrieves the balances of all participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public StreamingOutput getBalanceByPersonsAsCsv(@Context SecurityContext securityContext) throws IOException { if (!securityContext.isUserInRole(this.eventId + "~finance")) throw new SecurityException("Not permitted"); List personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); - StringBuilder personsBalancesCsvBuilder = new StringBuilder(); - CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(personsBalancesCsvBuilder, CSVFormat.DEFAULT); - try { - personsBalancesCsvPrinter.printRecord("personID", "lname", "fname", "suffix", "expense", "paid", "balance"); + return new StreamingOutput() { + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + PrintStream pstream = new PrintStream(output); + CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); + try { + personsBalancesCsvPrinter.printRecord("personID", "lname", "fname", "suffix", "expense", "paid", "balance"); - for (DataSet personBalance : personsBalances) { - personsBalancesCsvPrinter.printRecord(personBalance.getLong("personID"), personBalance.getString("lname"), personBalance.getString("fname"), - personBalance.getString("suffix"), personBalance.getFloat("expense"), personBalance.getFloat("paid"), - personBalance.getFloat("balance")); + for (DataSet personBalance : personsBalances) { + personsBalancesCsvPrinter.printRecord(personBalance.getLong("personID"), personBalance.getString("lname"), + personBalance.getString("fname"), personBalance.getString("suffix"), personBalance.getFloat("expense"), + personBalance.getFloat("paid"), personBalance.getFloat("balance")); + } + + personsBalancesCsvPrinter.flush(); + } finally { + personsBalancesCsvPrinter.close(); + } } - - personsBalancesCsvPrinter.flush(); - } finally { - personsBalancesCsvPrinter.close(); - } - - return personsBalancesCsvBuilder.toString(); + }; } } diff --git a/src/main/java/com/poststats/golf/api/EventPersonApi.java b/src/main/java/com/poststats/golf/api/EventPersonApi.java index 58056cd..679fd6e 100644 --- a/src/main/java/com/poststats/golf/api/EventPersonApi.java +++ b/src/main/java/com/poststats/golf/api/EventPersonApi.java @@ -2,11 +2,15 @@ package com.poststats.golf.api; import com.brianlong.sql.DataSet; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.poststats.api.BaseApi; +import com.poststats.api.Constants; +import com.poststats.api.model.Person; import com.poststats.golf.service.EventPersonService; import com.poststats.golf.service.EventService; -import com.poststats.security.Person; +import com.poststats.transformer.PersonTransformer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -15,25 +19,25 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.core.StreamingOutput; import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; @RequestScoped -@Path(BaseApi.BASE_PATH + "/golf/event/{eventId}") -public class EventPersonApi extends BaseApi { - - private final ObjectMapper mapper = new ObjectMapper(); +@Path("/golf/event/{eventId}") +@Tag(name = "Event Participant API") +public class EventPersonApi { @PathParam("eventId") private long eventId; @@ -44,44 +48,75 @@ public class EventPersonApi extends BaseApi { @Inject private EventPersonService eventPersonService; + @Inject + private PersonTransformer personTransformer; + @GET @Path("/people") - @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) @RolesAllowed("member") - public String get(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves the administrators and participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public List get(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); List persons = this.eventPersonService.getPeople(this.eventId); + return this.toAddressBookAsJson(persons); + } - if ("csv".equals(format)) { - return this.toAddressBookAsCsv(persons); - } else { - return this.toAddressBookAsJson(persons); - } + @GET + @Path("/people") + @RolesAllowed("member") + @Produces("text/csv") + @Operation(summary = "Retrieves the administrators and participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public StreamingOutput getAsCsv(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { + if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); + + List persons = this.eventPersonService.getPeople(this.eventId); + return this.toAddressBookAsCsv(persons); } @GET @Path("/participants") - @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) @RolesAllowed("member") - public String getParticipants(@Context SecurityContext securityContext, @Context @QueryParam("format") String format) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves the participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public List getParticipants(@Context SecurityContext securityContext, @Context @QueryParam("format") String format) throws JsonProcessingException, IOException { if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); List persons = this.eventPersonService.getParticipants(this.eventId); - - if ("csv".equals(format)) { - return this.toAddressBookAsCsv(persons); - } else { - return this.toAddressBookAsJson(persons); - } + return this.toAddressBookAsJson(persons); } @GET @Path("/participants") - @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) @RolesAllowed("member") - public String getSeriesParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) + @Produces("text/csv") + @Operation(summary = "Retrieves the participants in an event.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public StreamingOutput getParticipantsAsCsv(@Context SecurityContext securityContext, @Context @QueryParam("format") String format) + throws JsonProcessingException, IOException { + if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); + + List persons = this.eventPersonService.getParticipants(this.eventId); + return this.toAddressBookAsCsv(persons); + } + + @GET + @Path("/series/participants") + @RolesAllowed("member") + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves all the participants in an event series.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) + public List getSeriesParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); @@ -98,46 +133,36 @@ public class EventPersonApi extends BaseApi { if (personIds.add(person.getLong("personID"))) persons.add(person); } - if ("csv".equals(format)) { - return this.toAddressBookAsCsv(persons); - } else { - return this.toAddressBookAsJson(persons); - } + return this.toAddressBookAsJson(persons); } - private String toAddressBookAsJson(List persons) throws JsonProcessingException { - List> personsJson = new ArrayList<>(persons.size()); - for (DataSet person : persons) { - Map personJson = new HashMap<>(5); - personJson.put("personId", person.getLong("personID")); - personJson.put("prefix", person.getString("prefix")); - personJson.put("lastName", person.getString("lname")); - personJson.put("firstName", person.getString("fname")); - personJson.put("suffix", person.getString("suffix")); - personJson.put("emailAddress", person.getString("email")); - personsJson.add(personJson); - } - - return this.mapper.writeValueAsString(personsJson); + private List toAddressBookAsJson(List persons) throws JsonProcessingException { + List personsJson = new ArrayList<>(persons.size()); + for (DataSet person : persons) + personsJson.add(this.personTransformer.toModel(person)); + return personsJson; } - private String toAddressBookAsCsv(List persons) throws IOException { - StringBuilder personsCsvBuilder = new StringBuilder(); - CSVPrinter personsCsvPrinter = new CSVPrinter(personsCsvBuilder, CSVFormat.DEFAULT); - try { - personsCsvPrinter.printRecord("ID", "Prefix", "Last Name", "First Name", "Suffix", "Email Address"); + private StreamingOutput toAddressBookAsCsv(List persons) throws IOException { + return new StreamingOutput() { + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + PrintStream pstream = new PrintStream(output); + CSVPrinter personsCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); + try { + personsCsvPrinter.printRecord("ID", "Prefix", "Last Name", "First Name", "Suffix", "Email Address"); - for (DataSet person : persons) { - personsCsvPrinter.printRecord(person.getLong("personID"), person.getString("prefix"), person.getString("lname"), person.getString("fname"), - person.getString("suffix"), person.getString("email")); + for (DataSet person : persons) { + personsCsvPrinter.printRecord(person.getLong("personID"), person.getString("prefix"), person.getString("lname"), + person.getString("fname"), person.getString("suffix"), person.getString("email")); + } + + personsCsvPrinter.flush(); + } finally { + personsCsvPrinter.close(); + } } - - personsCsvPrinter.flush(); - } finally { - personsCsvPrinter.close(); - } - - return personsCsvBuilder.toString(); + }; } } diff --git a/src/main/java/com/poststats/golf/api/GolferApi.java b/src/main/java/com/poststats/golf/api/GolferApi.java index b547bb8..d824f2f 100644 --- a/src/main/java/com/poststats/golf/api/GolferApi.java +++ b/src/main/java/com/poststats/golf/api/GolferApi.java @@ -2,10 +2,14 @@ package com.poststats.golf.api; import com.brianlong.sql.DataSet; import com.fasterxml.jackson.core.JsonProcessingException; -import com.poststats.api.BaseApi; +import com.poststats.api.Constants; import com.poststats.api.model.Person; import com.poststats.golf.transformer.GolferTransformer; import com.poststats.service.PersonService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -14,19 +18,17 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This API provides access to PostStats Golfer meta-data and features. - * * @author brian.long@poststats.com */ @RequestScoped -@Path(BaseApi.BASE_PATH + "/golfer/{personId}") -public class GolferApi extends BaseApi { +@Path("/golfer/{personId}") +@Tag(name = "Golfer API") +public class GolferApi { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -44,13 +46,11 @@ public class GolferApi extends BaseApi { this.logger.debug("GolferApi init: {}", this.personId); } - /** - * @return An person model object. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified event was not found. - */ @GET - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves limited meta-data about a golfer.", description = "Retreives name, location, and other direct meta-data about the specified golfer.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "A golfer with the specified ID could not be found") }) public Person get() throws JsonProcessingException { DataSet row = this.personService.get(this.personId); if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); diff --git a/src/main/java/com/poststats/golf/api/SeriesApi.java b/src/main/java/com/poststats/golf/api/SeriesApi.java index fdb941a..e099ae6 100644 --- a/src/main/java/com/poststats/golf/api/SeriesApi.java +++ b/src/main/java/com/poststats/golf/api/SeriesApi.java @@ -2,13 +2,17 @@ package com.poststats.golf.api; import com.brianlong.sql.DataSet; import com.fasterxml.jackson.core.JsonProcessingException; -import com.poststats.api.BaseApi; +import com.poststats.api.Constants; import com.poststats.golf.api.model.Event; import com.poststats.golf.api.model.Series; import com.poststats.golf.service.EventService; import com.poststats.golf.service.SeriesService; import com.poststats.golf.transformer.EventTransformer; import com.poststats.golf.transformer.SeriesTransformer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -18,7 +22,6 @@ import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response.Status; import java.util.LinkedList; import java.util.List; @@ -28,14 +31,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This API provides access to PostStats Golf Event Series meta-data and - * features. - * * @author brian.long@poststats.com */ @RequestScoped -@Path(BaseApi.BASE_PATH + "/golf/series/{seriesId}") -public class SeriesApi extends BaseApi { +@Path("/golf/series/{seriesId}") +@Tag(name = "Event Series API") +public class SeriesApi { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -59,13 +60,11 @@ public class SeriesApi extends BaseApi { this.logger.debug("SeriesApi init: {}", this.seriesId); } - /** - * @return An event series model object. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified series was not found. - */ @GET - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves meta-data about an event series.", description = "Retreives name and other direct meta-data about the specified event series.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) public Series get() throws JsonProcessingException { DataSet row = this.seriesService.get(this.seriesId); if (row == null) throw new WebApplicationException("Series not found", Status.NOT_FOUND); @@ -73,32 +72,24 @@ public class SeriesApi extends BaseApi { return this.seriesTransformer.toModel(row); } - /** - * @return An event series model object. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified series was not found or it had - * no associated events. - */ @GET @Path("/eventIds") - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves event IDs under an event series.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) public Set getEventIds() throws JsonProcessingException { Set eventIds = this.eventService.getIds(this.seriesId); if (eventIds.isEmpty()) throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); return eventIds; } - /** - * @param reverse `true` to sort events in reverse chronological order; `false` - * (default) otherwise. - * @return A list of event model objects. - * @throws JsonProcessingException A JSON parsing issue occurred. - * @throws http-404 The specified series was not found or it had - * no associated events. - */ @GET @Path("/events") - @Produces(MediaType.APPLICATION_JSON) + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves limited event meta-data about all events in an event series.", description = "Retreives name, location, dates, and other direct meta-data about all events in the specified event series.") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) public List getEvents(@QueryParam("reverse") Boolean reverse) throws JsonProcessingException { Map rows = this.eventService.get(this.seriesId, !Boolean.TRUE.equals(reverse)); if (rows.isEmpty()) throw new WebApplicationException("Series or events not found", Status.NOT_FOUND);