Skip to content

Commit

Permalink
Merge pull request #11 from qbicsoftware/documentation
Browse files Browse the repository at this point in the history
Provides OpenAPI Documentation
  • Loading branch information
wow-such-code authored Mar 24, 2020
2 parents 2edf07f + 2c7a7c4 commit 34d2803
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 50 deletions.
105 changes: 61 additions & 44 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
<parent>
<groupId>life.qbic</groupId>
<artifactId>service-parent-pom</artifactId>
<version>1.7.0</version>
<version>2.1.0</version>
</parent>
<properties>
<swagger.version>2.1.0</swagger.version>
<jdk.version>1.8</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<exec.mainClass>life.qbic.SampleTracking</exec.mainClass>
Expand Down Expand Up @@ -93,10 +94,6 @@
<artifactId>micronaut-jdbc-dbcp</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
Expand All @@ -111,9 +108,68 @@
<artifactId>data-model-lib</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-openapi</artifactId>
<version>1.2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-runtime-groovy</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Open API documentation -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<goals>
<goal>set-system-properties</goal>
</goals>
<configuration>
<properties>
<property>
<name>groovy.target.directory</name>
<value>${project.build.directory}/classes</value>
</property>
<property>
<name>groovy.parameters</name>
<value>true</value>
</property>
<property>
<name>micronaut.openapi.views.spec</name>
<value>rapidoc.enabled=true,swagger-ui.enabled=true,swagger-ui.theme=flattop</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.6.3</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand All @@ -134,45 +190,6 @@
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${exec.mainClass}</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"
/> </transformers> </configuration> </execution> </executions> </plugin -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<debug>true</debug>
<debuglevel>lines</debuglevel>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>3.3.0-01</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-eclipse-batch -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.5.7-01</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
<version>2.0.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<pluginRepositories>
Expand Down
14 changes: 14 additions & 0 deletions src/main/groovy/life/qbic/SampleTracking.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package life.qbic

import io.swagger.v3.oas.annotations.OpenAPIDefinition
import io.swagger.v3.oas.annotations.info.Contact
import io.swagger.v3.oas.annotations.info.Info
import io.swagger.v3.oas.annotations.info.License

import javax.sql.DataSource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.core.LoggerContext
Expand All @@ -14,6 +19,15 @@ import io.micronaut.context.env.Environment
import io.micronaut.runtime.Micronaut
import java.sql.Connection

@OpenAPIDefinition(
info = @Info(
title = "Sample Tracking Service",
version = "1.0.3",
description = "Information about sample status and location information for QBiC's data management platform.",
license = @License(name = "", url = ""),
contact = @Contact(url = "https://github.com/sven1103", name = "Sven Fillinger", email = "sven.filliner@qbic.uni-tuebingen.de")
)
)
@CompileStatic
@Log4j2
class SampleTracking {
Expand Down
39 changes: 37 additions & 2 deletions src/main/groovy/life/qbic/controller/LocationsController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.context.annotation.Parameter
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.PathVariable
import io.micronaut.security.annotation.Secured
import io.micronaut.security.rules.SecurityRule
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.ArraySchema
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse
import life.qbic.datamodel.services.Sample
import life.qbic.micronaututils.auth.Authentication

import javax.annotation.security.RolesAllowed
Expand All @@ -30,7 +37,17 @@ class LocationsController {

@Get(uri = "/contacts/{email}", produces = MediaType.APPLICATION_JSON)
@RolesAllowed(["READER", "WRITER"])
HttpResponse<Contact> contacts(@Parameter('email') String email){
@Operation(summary = "Provides the contact information linked to an e-mail",
description = "Provides detailed contact information that is linked to an e-mail",
tags = "Contact")
@ApiResponse(responseCode = "200", description = "Current contact associated with the email address",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = Contact.class)))
@ApiResponse(responseCode = "400", description = "Invalid e-mail address")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Contact not found")
HttpResponse<Contact> contacts(@PathVariable('email') String email){
if(!RegExValidator.isValidMail(email)) {
HttpResponse<Contact> res = HttpResponse.badRequest("Not a valid email address!")
return res
Expand All @@ -48,8 +65,18 @@ class LocationsController {
}

@Get(uri = "/{contact_email}", produces = MediaType.APPLICATION_JSON)
@Operation(summary = "Provides the locations information linked to an e-mail",
description = "Provides detailed locations information that is linked to an e-mail",
tags = "Contact")
@ApiResponse(responseCode = "200", description = "Current locations associated with the email address",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = Location.class)))
@ApiResponse(responseCode = "400", description = "Invalid e-mail address")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Location not found")
@RolesAllowed(["READER", "WRITER"])
HttpResponse<List<Location>> locations(@Parameter('contact_email') String contact_email){
HttpResponse<List<Location>> locations(@PathVariable('contact_email') String contact_email){
if(!RegExValidator.isValidMail(contact_email)) {
HttpResponse<Contact> res = HttpResponse.badRequest("Not a valid email address!")
return res
Expand All @@ -60,6 +87,14 @@ class LocationsController {
}

@Get(uri = "/", produces = MediaType.APPLICATION_JSON)
@Operation(summary = "Provides all available locations",
description = "Provides all available locations",
tags = "Location")
@ApiResponse(responseCode = "200", description = "All available locations",
content = @Content(
mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = Location.class))))
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@RolesAllowed(["READER", "WRITER"])
HttpResponse<List<Location>> listLocations() {
List<Location> res = locService.listLocations()
Expand Down
44 changes: 40 additions & 4 deletions src/main/groovy/life/qbic/controller/SamplesController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import io.micronaut.http.HttpResponse
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.PathVariable
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Put
import io.micronaut.security.annotation.Secured
import io.micronaut.security.rules.SecurityRule
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse
import life.qbic.micronaututils.auth.Authentication

import javax.annotation.security.RolesAllowed
Expand All @@ -29,9 +34,19 @@ class SamplesController {
this.sampleService = sampleService
}

@Operation(summary = "Request a sample's tracking information",
description = "Requests a sample resource with the given identifier.",
tags = "Sample")
@ApiResponse(
responseCode = "200", description = "Returns a sample with tracking information", content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = Sample.class)))
@ApiResponse(responseCode = "400", description = "Sample identifier format does not match")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Sample not found")
@Get(uri = "/{sampleId}", produces = MediaType.APPLICATION_JSON)
@RolesAllowed([ "READER", "WRITER"])
HttpResponse<Sample> sample(@Parameter('sampleId') String code) {
HttpResponse<Sample> sample(@PathVariable('sampleId') String code) {
if(!RegExValidator.isValidSampleCode(code)) {
return HttpResponse.badRequest("Not a valid sample code!");
} else {
Expand All @@ -45,8 +60,15 @@ class SamplesController {
}

@Post("/{sampleId}/currentLocation/")
@Operation(summary = "Sets a sample's current location",
description = "Sets a sample current location with the given identifier.",
tags = "Sample Location")
@ApiResponse(responseCode = "200", description = "Current location for sample set successfully")
@ApiResponse(responseCode = "400", description = "Sample identifier format does not match")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Sample not found")
@RolesAllowed("WRITER")
HttpResponse<Location> newLocation(@Parameter('sampleId') String sampleId, Location location) {
HttpResponse<Location> newLocation(@PathVariable('sampleId') String sampleId, Location location) {
if(!RegExValidator.isValidSampleCode(sampleId)) {
return HttpResponse.badRequest("Not a valid sample code!");
} else {
Expand All @@ -61,8 +83,15 @@ class SamplesController {
* @return
*/
@Put("/{sampleId}/currentLocation/")
@Operation(summary = "Updates a sample's current location",
description = "Updates a sample current location with the given identifier.",
tags = "Sample Location")
@ApiResponse(responseCode = "200", description = "Current location for sample set successfully")
@ApiResponse(responseCode = "400", description = "Sample identifier format does not match")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Sample not found")
@RolesAllowed("WRITER")
HttpResponse<Location> updateLocation(@Parameter('sampleId') String sampleId, Location location) {
HttpResponse<Location> updateLocation(@PathVariable('sampleId') String sampleId, Location location) {
if(!RegExValidator.isValidSampleCode(sampleId)) {
return HttpResponse.badRequest("Not a valid sample code!");
} else {
Expand All @@ -71,8 +100,15 @@ class SamplesController {
}

@Put("/{sampleId}/currentLocation/{status}")
@Operation(summary = "Sets a sample's current location status",
description = "Sets a sample current location status with the given identifier.",
tags = "Sample Status")
@ApiResponse(responseCode = "200", description = "Current location for sample set successfully")
@ApiResponse(responseCode = "400", description = "Sample identifier format does not match")
@ApiResponse(responseCode = "401", description = "Unauthorized access")
@ApiResponse(responseCode = "404", description = "Sample not found")
@RolesAllowed("WRITER")
HttpResponse sampleStatus(@Parameter('sampleId') String sampleId, @Parameter('status') Status status) {
HttpResponse sampleStatus(@PathVariable('sampleId') String sampleId, @PathVariable('status') Status status) {
if(!RegExValidator.isValidSampleCode(sampleId)) {
return HttpResponse.badRequest("Not a valid sample code!");
}
Expand Down
19 changes: 19 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ micronaut:
name: sampletracking
server:
port: ${tr-server-port:8080}
router:
static-resources:
swagger:
paths: classpath:META-INF/swagger
mapping: /swagger/**
swagger-ui:
paths: classpath:META-INF/swagger/views/swagger-ui
mapping: /swagger-ui/**
rapidoc:
paths: classpath:META-INF/swagger/views/rapidoc
mapping: /rapidoc/**
security:
enabled: true
endpoints:
Expand All @@ -18,3 +29,11 @@ userroles:
config: ${domain-userroles:/etc/micronaut.d/userroles.yml}
database:
name: ${tr-db-name}
endpoints:
health:
enabled: true
sensitive: false
details-visible: ANONYMOUS
routes:
enabled: true
sensitive: false

0 comments on commit 34d2803

Please sign in to comment.