Desplegar docker una app Spring Boot 1.5.x desde Gradle

Utilizaremos el plugin gradle-docker para gradle.

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '1.5.17.RELEASE'
    id 'com.palantir.docker' version '0.20.1'
    id 'com.palantir.docker-run' version '0.20.1'
}

...

jar {
    baseName = 'my-spring-boot-app'
    version = '1.0.0'
}

docker {
    dependsOn build
    name "my-docker-registry:5043/my-image-name"
    tags jar.version, 'latest'
    files jar.archivePath
    buildArgs(['JAR_FILE': jar.archiveName])
}

dockerRun {
    name "my-container-name"
    image "my-docker-registry:5043/my-image-name:${jar.version}"
    ports '8080:8080'
    env 'JAVA_OPTS': '-Xms128m -Xmx512m -server', 'SPRING_PROFILES_ACTIVE': 'my-spring-prifle'
    network 'my-docker-network'
    daemonize true
}

Dockerfile

FROM openjdk:8-jre-alpine
ARG JAR_FILE
COPY ${JAR_FILE} /app.jar
ENTRYPOINT exec java $JAVA_OPTS -jar /app.jar
EXPOSE 8080

Operaciones

Construir la imagen de docker

./gradlew clean docker dockerTag

REPOSITORY                              TAG     IMAGE ID            CREATED             SIZE
my-docker-registry:5043/my-image-name   latest  457475efc55d        9 minutes ago       145MB
my-docker-registry:5043/my-image-name   1.0.0   457475efc55d        9 minutes ago       145MB

Construir y ejecutar el contenedor

./gradlew dockerRun

Ver el estado del contenedor

./gradlew dockerRunStatus
> Task :dockerRunStatus
Docker container 'my-container-name' is STOPPED.

Ver el estado de la red

./gradlew dockerNetworkModeStatus
> Task :dockerNetworkModeStatus
Docker container 'my-container-name' is configured to run with 'my-docker-network' network mode.

Detener el contenedor

./gradlew dockerStop

Eliminar el contenedor

dockerRemoveContainer

Push imagen

./gradlew dockerPush

Spring Testing. Mostrar información de las peticiones

Cuando usamos MockMvc para testear controladores de Spring, es muy útil disponer del máximo de información referente a la petición realizada desde el test. Una forma muy sencilla es indicarle al “builder” que queremos que muestre en la salida del test dicha información.

import org.junit.Before;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

@RunWith(MockitoJUnitRunner.class)
public abstract class MyTestClass {

    MockMvc mvc;

    @Mock
    MyRepository myRepository;

    @Before
    public void initialize() {

        mvc = MockMvcBuilders.standaloneSetup(new MyController(new MyService(myRepository)));
                .alwaysDo(print()) // Esta es la línea importante
                .build();
    }
}

Esto hace que para cada petición se se hace desde un test unitario via MockMvc muestre una información detallada de la misma:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /my-request-path
       Parameters = {my-request-param=[my-request-param-value]}
          Headers = {my-header=[my-header-value]}

Handler:
             Type = com.example.MyController
           Method = public org.springframework.http.ResponseEntity<java.util.List<com.example.MyResponseClass>> com.example.MyController.myMethod(com.example.MyRequestBodyClass)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = [{"field":"value"}]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Tener en cuenta que hasta versión 5.0 de Spring Framework no se muestra el contenido de la request tal y como se puede leer en el siguiente jira:

https://jira.spring.io/browse/SPR-14717

Recomendación SDKMAN

SDKMAN es una herramienta genial que nos permite gestionar diferentes instalaciones de herramientas relacionadas con el mundo Java (JDK, Maven, Gradle, SpringBoot, …) desde la línea de comandos. Lo que es muy práctico es que permite que convivan, de forma muy fácil, diferentes versiones de estas herramientas.

$ sdk current

Using:

gradle: 3.4.1
grails: 3.2.7
groovy: 2.4.10
kotlin: 1.1.1
maven: 3.3.9
sbt: 0.13.13
scala: 2.12.1
springboot: 1.5.2.RELEASE

Si no lo estáis usando ya, os recomiendo que le echéis un ojo.

Saludos