Permalink
Browse files

Dockerized REST API and make sure container labels are compatible wit…

…h traefik
  • Loading branch information...
schrieveslaach committed Nov 30, 2018
1 parent fe3e2f4 commit 9e66f9a1f46b8f6fbece3d2f693953d36728b604
@@ -0,0 +1,46 @@
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.aixigo.preview.servant</groupId>
<artifactId>parent</artifactId>
<version>0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

<artifactId>api-tests</artifactId>
<name>PREvant REST API Integration Tests</name>

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,77 @@
package com.aixigo.preview.servant.rest;

/*-
* ========================LICENSE_START=================================
* PREvant REST API Integration Tests
* %%
* Copyright (C) 2018 aixigo AG
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* =========================LICENSE_END==================================
*/

import com.aixigo.preview.servant.rest.junit.extension.PREvantRestApiExtension;
import com.aixigo.preview.servant.rest.model.ServiceConfiguration;
import io.restassured.response.ValidatableResponse;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import java.net.URI;

import static io.restassured.RestAssured.given;
import static java.util.Collections.singletonList;

@ExtendWith(PREvantRestApiExtension.class)
class PREvantRestApiDockerTest {

@Test
void shouldDeployDockerContainer_WhenRequestToDeployService(URI restApiURI) throws Exception {
String uri = postServiceConfiguration(restApiURI, "master", "nginx", "library", "nginx")
.extract()
.body()
.path("[0].url");

given().baseUri(uri)
.get()
.then()
.statusCode(200);

deleteApp(restApiURI, "master")
.statusCode(200);
}

private ValidatableResponse postServiceConfiguration(URI restApiURI, String appName, String serviceName, String imageUser, String imageRepository) {
return given()
.contentType("application/json")
.baseUri(restApiURI.toString())
.body(singletonList(new ServiceConfiguration(serviceName, imageUser, imageRepository)))
.when()
.post("api/apps/" + appName)
.then();
}

private ValidatableResponse deleteApp(URI restApiURI, String appName) {
return given()
.contentType("application/json")
.baseUri(restApiURI.toString())
.delete("api/apps/" + appName)
.then();
}

}
@@ -0,0 +1,94 @@
package com.aixigo.preview.servant.rest.junit.extension;

/*-
* ========================LICENSE_START=================================
* PREvant REST API Integration Tests
* %%
* Copyright (C) 2018 aixigo AG
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* =========================LICENSE_END==================================
*/

import org.junit.jupiter.api.extension.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.OutputFrame;

import java.net.URI;
import java.util.Objects;
import java.util.function.Consumer;

import static org.apache.commons.lang3.StringUtils.isBlank;

public class PREvantRestApiExtension implements BeforeAllCallback, AfterAllCallback, ParameterResolver {

private final GenericContainer prevantRestApiContainer = new GenericContainer("aixigo/prevant-api")
.withFileSystemBind("/var/run/docker.sock", "/var/run/docker.sock", BindMode.READ_WRITE)
.withLabel("traefik.frontend.rule", "ReplacePathRegex: ^/api(.*) /$1;PathPrefix:/api;")
.withLogConsumer(new Consumer<OutputFrame>() {

private final Logger LOGGER = LoggerFactory.getLogger("rest api");

@Override
public void accept(OutputFrame outputFrame) {
log(LOGGER, outputFrame);
}
});

private final GenericContainer traefikContainer = new GenericContainer("traefik")
.withFileSystemBind("/var/run/docker.sock", "/var/run/docker.sock", BindMode.READ_WRITE)
.withCommand("--api --docker")
.withLogConsumer(new Consumer<OutputFrame>() {

private final Logger LOGGER = LoggerFactory.getLogger("traefik");

@Override
public void accept(OutputFrame outputFrame) {
log(LOGGER, outputFrame);
}
});

private static void log(Logger logger, OutputFrame outputFrame) {
String utf8String = outputFrame.getUtf8String();
if (!isBlank(utf8String)) {
logger.info(outputFrame.getUtf8String().trim());
}
}

public void afterAll(ExtensionContext extensionContext) {
prevantRestApiContainer.stop();
traefikContainer.stop();
}

public void beforeAll(ExtensionContext extensionContext) {
prevantRestApiContainer.start();
traefikContainer.start();
}

public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return Objects.equals(parameterContext.getParameter().getType(), URI.class);
}

public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return URI.create("http://localhost:" + traefikContainer.getMappedPort(80));
}
}
@@ -0,0 +1,45 @@
package com.aixigo.preview.servant.rest.model;

/*-
* ========================LICENSE_START=================================
* PREvant REST API Integration Tests
* %%
* Copyright (C) 2018 aixigo AG
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* =========================LICENSE_END==================================
*/

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;

@AllArgsConstructor
@Data
public class ServiceConfiguration {

@NonNull
private final String serviceName;

@NonNull
private final String imageUser;

@NonNull
private final String imageRepository;
}
@@ -0,0 +1,22 @@
FROM docker.io/library/rust:1.30.0-slim as builder
RUN apt update ; \
apt install -y libssl-dev pkg-config
WORKDIR /usr/src/api
COPY . .
RUN rustup default nightly ; \
cargo install --path . ; \
chown root:root /usr/local/cargo/bin/api

FROM docker.io/library/debian:stretch-slim
LABEL maintainer="marc.schreiber@aixigo.de"

RUN set -eux ; \
apt-get update ; \
apt-get install -y openssl ca-certificates

WORKDIR /app
COPY --from=builder /usr/local/cargo/bin/api .
COPY res/Rocket.toml /app/Rocket.toml
EXPOSE 80
ENV ROCKET_ENV=staging
CMD ["./api"]
@@ -1,6 +1,5 @@
<project>
<modelVersion>4.0.0</modelVersion>
<name>PREvant</name>

<parent>
<groupId>com.aixigo.preview.servant</groupId>
@@ -10,6 +9,15 @@
</parent>

<artifactId>api</artifactId>
<name>PREvant REST API</name>

<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
@@ -0,0 +1,4 @@
[staging]
address = "0.0.0.0"
port = 80
log = "normal"
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -10,10 +10,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Oops, something went wrong.

0 comments on commit 9e66f9a

Please sign in to comment.