diff --git a/Dockerfile b/Dockerfile index cd09136..419ae5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,11 @@ #Build jar file -FROM openjdk:13-jdk-alpine as build-jar -COPY . / +FROM eclipse-temurin:latest as build-jar +WORKDIR /app +COPY . /app/ +RUN ./gradlew clean RUN ./gradlew build #Run jar file -FROM openjdk:13-jdk-alpine -COPY --from=build-jar build/libs/*.jar app.jar +FROM eclipse-temurin:latest +COPY --from=build-jar /app/build/libs/factoid-converters-0.4.1.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] \ No newline at end of file diff --git a/README.md b/README.md index 3cf56e3..6def205 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ java -jar build/libs/factoid-converters*.jar --server.port=8080 RESTful API (Swagger docs): Once the app is built and running, -the auto-generated documentation is available at +the auto-generated OpenAPI/Swagger documentation is available at (ending with '/') `http://localhost:8080/convert/` ## Docker @@ -33,7 +33,7 @@ docker run -it --rm --name factoid-converters -p :8080 pathwaycommons/fact ``` Optionally, a member of 'pathwaycommons' group can now push (upload) the latest Docker image there: - +(BTW: the latest Docker image is built automatically by Dockerhub on every git push to the master branch) ```commandline docker login docker push pathwaycommons/factoid-converters diff --git a/build.gradle b/build.gradle index ec82353..f7a08dc 100644 --- a/build.gradle +++ b/build.gradle @@ -12,8 +12,8 @@ buildscript { } } -apply plugin: 'idea' apply plugin: 'java' +apply plugin: 'idea' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' @@ -30,14 +30,17 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-web' - runtimeOnly 'org.springframework.boot:spring-boot-devtools' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation "org.springframework.boot:spring-boot-configuration-processor" + implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' + implementation 'org.biopax.paxtools:sbgn-converter:5.3.0' implementation 'com.google.code.gson:gson:2.9.0' implementation 'org.apache.commons:commons-collections4:4.4' - implementation 'io.springfox:springfox-swagger2:2.7.0' - implementation 'io.springfox:springfox-swagger-ui:2.7.0' + runtimeOnly 'org.springframework.boot:spring-boot-devtools' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + //java 9+ does not have Jax B Dependents implementation 'javax.xml.bind:jaxb-api:2.3.1' implementation 'com.sun.xml.bind:jaxb-core:2.3.0.1' implementation 'com.sun.xml.bind:jaxb-impl:2.3.6' @@ -46,4 +49,4 @@ dependencies { sourceCompatibility = 8 group = 'pathwaycommons' -version = '0.2.2' +version = '0.4.1' diff --git a/src/main/java/factoid/web/Application.java b/src/main/java/factoid/web/Application.java index 0313300..5bc4848 100644 --- a/src/main/java/factoid/web/Application.java +++ b/src/main/java/factoid/web/Application.java @@ -2,6 +2,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -14,6 +15,15 @@ public void addViewControllers(ViewControllerRegistry registry) { registry.addRedirectViewController("/", "/swagger-ui.html"); } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + } + public static void main(String[] args) { SpringApplication.run(Application.class, args); } diff --git a/src/main/java/factoid/web/Controller.java b/src/main/java/factoid/web/Controller.java index c8bc35e..59a39c0 100644 --- a/src/main/java/factoid/web/Controller.java +++ b/src/main/java/factoid/web/Controller.java @@ -5,8 +5,8 @@ import factoid.converter.BiopaxToFactoid; import factoid.converter.FactoidToBiopax; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import org.biopax.paxtools.io.SimpleIOHandler; import org.biopax.paxtools.io.sbgn.L3ToSBGNPDConverter; import org.biopax.paxtools.model.Model; @@ -31,13 +31,13 @@ @RequestMapping(value = "/v2", method = {RequestMethod.POST}) public class Controller { - @ApiOperation(value = "json-to-biopax", notes = "Converts a Factoid model to BioPAX.") + @Operation(summary = "json-to-biopax", description = "Converts a Factoid model to BioPAX.") @RequestMapping(path = "/json-to-biopax", consumes = MediaType.APPLICATION_JSON_VALUE, produces = "application/vnd.biopax.rdf+xml" ) public String jsonToBiopax( - @ApiParam("Factoid document content (JSON string)") @RequestBody String body) { + @Parameter(description = "Factoid document content (JSON string)") @RequestBody String body) { // Add templates to converter by the reader FactoidToBiopax converter = new FactoidToBiopax(); try { @@ -52,13 +52,13 @@ public String jsonToBiopax( return converter.convertToBiopax(); } - @ApiOperation(value = "json-to-sbgn", notes = "Converts a Factoid model to SBGN-ML (via BioPAX).") + @Operation(summary = "json-to-sbgn", description = "Converts a Factoid model to SBGN-ML (via BioPAX).") @RequestMapping(path = "/json-to-sbgn", consumes = MediaType.APPLICATION_JSON_VALUE, produces = "application/xml" ) public String jsonToSbgn( - @ApiParam("Factoid document (JSON string)") @RequestBody String body) { + @Parameter(description = "Factoid document (JSON string)") @RequestBody String body) { try { InputStream is = new ByteArrayInputStream(jsonToBiopax(body).getBytes(StandardCharsets.UTF_8)); Model model = new SimpleIOHandler().convertFromOWL(is); @@ -73,13 +73,13 @@ public String jsonToSbgn( } } - @ApiOperation(value = "biopax-to-sbgn", notes = "Converts a factoid BioPAX model to SBGN-ML (SBGN PD).") + @Operation(summary = "biopax-to-sbgn", description = "Converts a factoid BioPAX model to SBGN-ML (SBGN PD).") @RequestMapping(path = "/biopax-to-sbgn", consumes = "application/vnd.biopax.rdf+xml", produces = "application/xml" ) public String biopaxToSbgn( - @ApiParam("A factoid (small) BioPAX RDF/XML model") @RequestBody String body) { + @Parameter(description = "A factoid (small) BioPAX RDF/XML model") @RequestBody String body) { try { InputStream is = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); Model model = new SimpleIOHandler().convertFromOWL(is); @@ -94,13 +94,13 @@ public String biopaxToSbgn( } } - @ApiOperation(value = "biopax-to-json", notes = "Converts a BioPAX model to Factoid JSON.") + @Operation(summary = "biopax-to-json", description = "Converts a BioPAX model to Factoid JSON.") @RequestMapping(path = "/biopax-to-json", consumes = "application/vnd.biopax.rdf+xml", produces = "application/json" ) public String biopaxToFactoid( - @ApiParam("A BioPAX RDF/XML model") @RequestBody String body) { + @Parameter(description = "A BioPAX RDF/XML model") @RequestBody String body) { BiopaxToFactoid converter = new BiopaxToFactoid(); try { InputStream is = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); @@ -113,13 +113,13 @@ public String biopaxToFactoid( } } - @ApiOperation(value = "biopax-url-to-json", notes = "Converts a BioPAX model to Factoid JSON.") + @Operation(summary = "biopax-url-to-json", description = "Converts a BioPAX model to Factoid JSON.") @RequestMapping(path = "/biopax-url-to-json", consumes = "text/plain", produces = "application/json" ) public String biopaxUrlToFactoid( - @ApiParam("URL of a TAR-GZ compressed BioPAX RDF/XML file") @RequestBody String url) { + @Parameter(description = "URL of a TAR-GZ compressed BioPAX RDF/XML file") @RequestBody String url) { BiopaxToFactoid converter = new BiopaxToFactoid(); try { String body = getContentFromUrl(url); diff --git a/src/main/java/factoid/web/OpenApiConfig.java b/src/main/java/factoid/web/OpenApiConfig.java new file mode 100644 index 0000000..e57e3a7 --- /dev/null +++ b/src/main/java/factoid/web/OpenApiConfig.java @@ -0,0 +1,42 @@ +package factoid.web; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenApiConfig { + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .info(apiInfo()); + } + + private Info apiInfo() { + return new Info() + .title("Factoid data converters") + .description("A RESTful web service, built with Spring Boot and Paxtools java libraries, that converts " + + "Factoid documents to BioPAX or SBGN formats.") + .version("2") + .contact(apiContact()) + .license(apiLicence()); + } + + private License apiLicence() { + return new License() + .name("MIT Licence") + .url("https://opensource.org/licenses/mit-license.php"); + } + + private Contact apiContact() { + return new Contact() + .name("Pathway Commons") + .email("pathway-commons-help@googlegroups.com") + .url("https://www.pathwaycommons.org"); + } + +} diff --git a/src/main/java/factoid/web/SpringFoxConfig.java b/src/main/java/factoid/web/SpringFoxConfig.java deleted file mode 100644 index c3591c1..0000000 --- a/src/main/java/factoid/web/SpringFoxConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -package factoid.web; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.Collections; - -@Configuration -@EnableSwagger2 -//@Import(BeanValidatorPluginsConfiguration.class) //JSR-303 (if controllers have bean args and validation annotations) -public class SpringFoxConfig { - @Bean - public Docket apiDocket() { - return new Docket(DocumentationType.SWAGGER_2) - .select() -// .apis(RequestHandlerSelectors.any()) //this then shows built-in Spring actuators, e.g., health, devel. - .apis(RequestHandlerSelectors.basePackage("factoid.web")) -// .paths(PathSelectors.any()) - .paths(PathSelectors.ant("/v2/**")) - .build() - .useDefaultResponseMessages(false) - .apiInfo(getApiInfo()); - } - - private ApiInfo getApiInfo() { - return new ApiInfo( - "Factoid data converters", - "A RESTful web service, built with Spring Boot and Paxtools java libraries, that converts " + - "Factoid documents to BioPAX, SBGN formats.", - "2", //api - "free", - new Contact("Pathway Commons", - "http://www.pathwaycommons.org", - "pathway-commons-help@googlegroups.com" - ), - "MIT", - "https://raw.githubusercontent.com/PathwayCommons/factoid-converters/master/LICENSE", - Collections.emptyList() - ); - } -} diff --git a/src/main/resources/config/application.properties b/src/main/resources/config/application.properties index deac6ea..fd82513 100644 --- a/src/main/resources/config/application.properties +++ b/src/main/resources/config/application.properties @@ -5,3 +5,10 @@ server.servlet.context-path = /convert # * - enables all actuator endpoints management.endpoints.web.exposure.include=health #management.endpoints.web.exposure.exclude= + +# OpenAPI/Swagger3 (feature and /v3/api-docs endpoint) +springdoc.api-docs.enabled=true +springdoc.swagger-ui.enabled=true +#springdoc.packagesToScan=? +#springdoc.pathsToMatch=? + diff --git a/src/test/java/factoid/web/ControllerT.java b/src/test/java/factoid/web/ControllerT.java index 2745348..e240515 100644 --- a/src/test/java/factoid/web/ControllerT.java +++ b/src/test/java/factoid/web/ControllerT.java @@ -1,7 +1,6 @@ package factoid.web; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -9,7 +8,6 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.nio.file.Files; @@ -18,7 +16,6 @@ import static org.junit.jupiter.api.Assertions.*; -@ExtendWith(SpringExtension.class) @Import(Application.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class ControllerT { @@ -73,7 +70,7 @@ public void testBiopaxToFactoid() throws IOException { } @Test - public void testBiopaxUrlToFactoid() throws IOException { + public void testBiopaxUrlToFactoid() { String url = "https://www.pathwaycommons.org/archives/PC2/v12/PathwayCommons12.psp.BIOPAX.owl.gz"; HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "text/plain");