Sunday, December 30, 2018

Swagger getting started

At first I tried to go to http://editor.swagger.io/ , generate the Maven project to generate a RestEasy-EAP server, build and deploy to Wildfly 12.

There I got this error:


ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "swagger-jaxrs-resteasy-eap-server-1.0.0.war")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => [
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService",
"jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START",
"jboss.undertow.deployment.default-server.default-host./v2",
"jboss.naming.context.java.jboss.datasources.ExampleDS",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START"
],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService is missing [jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.undertow.deployment.default-server.default-host./v2 is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]",
"jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource is missing [jboss.naming.context.java.jboss.datasources.ExampleDS]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".deploymentCompleteService is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.undertow.deployment.default-server.default-host./v2, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]"
]
}



and the deployment fails. I felt discouraged and I turned to something simpler.

First I will implement my own Rest Service:

https://spring.io/guides/gs/rest-service/

then I run as http://localhost:8080/greeting

Then I move to adding Swagger to this REST webapp https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api.
I add the SwaggerConfig class with the @EnableSwagger2

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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()                                  
          .apis(RequestHandlerSelectors.any())              
          .paths(PathSelectors.any())                          
          .build();                                           
    }
}



Here I see something comforting


s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/greeting]}" onto public org.springframework.gsrestservice.Greeting org.springframework.gsrestservice.GreetingController.greeting(java.lang.String)
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/ui]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources]}" onto public org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/security]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public


so now the endpoints are:

http://localhost:8080/greeting

http://localhost:8080/swagger-resources/configuration/ui

http://localhost:8080/swagger-resources/

http://localhost:8080/swagger-resources/configuration/security

http://localhost:8080/v2/api-docs


Then I add the io.springfox:springfox-swagger-ui:2.9.2 dependency

and I get the Swagger-UI at http://localhost:8080/swagger-ui.html

My code is available here https://github.com/vernetto/springbootrestswagger

The Baeldung code is here https://github.com/eugenp/tutorials/tree/master/spring-security-rest







Monday, December 24, 2018

Maven Artifact Resolver

https://github.com/shrinkwrap/resolver#introduction-to-shrinkwrap-resolvers

add dependency org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-depchain:3.1.3 (default scope, not test scope)

package org.pierre.artifactresolver;

import java.io.File;

import org.jboss.shrinkwrap.resolver.api.maven.Maven;

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        File[] files = Maven.resolver().resolve("org.apache.commons:commons-lang3:3.8.1").withTransitivity().asFile();
        for (File file : files) {
         System.out.println(file.getAbsolutePath());
        }
        
    }
}



this prints:


Hello World!
c:\pierre\.m2\repository\org\apache\commons\commons-lang3\3.8.1\commons-lang3-3.8.1.jar




Friday, December 14, 2018

Cleaning up old releases in Nexus 2 and 3

In Nexus 2 there is the task "remove releases from repository", where you can further refine the scope by specifying a "repository target" (=a filter).... problem is, the only option you have is the number of the most recent versions to retain.... there is no way to specify "delete all versions older than 2 years, but in any case keep the last 10".

I have written this Spring Boot utility https://github.com/vernetto/nexusclean to generate curl commands to delete artifacts based on multiple selection criteria. But it doesn't handle parent pom, which is a limitation.

Also, be aware that the curl command to delete a component, like

curl -u admin:admin123 -X "DELETE" -w "%{http_code}" http://localhost:8281/nexus/service/local/repositories/central/content/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7

every time rebuilds the index, which is very CPU intensive. There is no way to batch multiple deletes in a single transaction.


In Nexus 3

https://github.com/xninjaxelitex/nexus3-cleanup-release-artifact





Monday, December 10, 2018

Docker broken after upgrade

sudo systemctl start docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.


sudo journalctl -xe


Error starting daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers: devicemapper, overlay2; Please cleanup or explicit

sudo vi /etc/docker/daemon.json

append this at the end and before the closed curly brace:

,"storage-driver": "devicemapper"



sudo systemctl reset-failed docker.service
sudo systemctl start docker.service