Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow router customizers #15

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 28 additions & 19 deletions citrus-remote-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<properties>
<!-- Plugin versions -->
<docker-maven-plugin.version>0.45.0</docker-maven-plugin.version>
<download-maven-plugin.version>1.9.0</download-maven-plugin.version>

<!-- Dependency versions -->
<citrus.version>4.3.1</citrus.version>
Expand All @@ -27,11 +28,12 @@
<citrus.remote.verify.phase>none</citrus.remote.verify.phase>

<docker.build.phase>none</docker.build.phase>
<docker.copy.phase>none</docker.copy.phase>
<docker.remove.phase>none</docker.remove.phase>
<docker.start.phase>none</docker.start.phase>
<docker.stop.phase>none</docker.stop.phase>

<download.wget.phase>none</download.wget.phase>

<failsafe.phase>verify</failsafe.phase>
</properties>

Expand Down Expand Up @@ -96,6 +98,27 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>${download-maven-plugin.version}</version>
<executions>
<execution>
<id>get-citrus-logs</id>
<goals>
<goal>wget</goal>
</goals>
<phase>${download.wget.phase}</phase>
<configuration>
<outputDirectory>${project.build.directory}/container-logs</outputDirectory>
<outputFileName>citrus.log</outputFileName>
<overwrite>true</overwrite>
<skipCache>true</skipCache>
<url>http://localhost:4567/citrus-logs?reset=true</url>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand All @@ -121,14 +144,6 @@
<contextDir>${project.basedir}</contextDir>
<dockerFile>${project.basedir}/src/test/container/Containerfile.temurin</dockerFile>
</build>
<copy>
<entries>
<entry>
<containerPath>/deployment/target/logs/citrus.log</containerPath>
<hostDirectory>${project.build.directory}/container-logs</hostDirectory>
</entry>
</entries>
</copy>
<run>
<autoRemove>true</autoRemove>
<ports>
Expand Down Expand Up @@ -171,13 +186,6 @@
</goals>
<phase>${docker.start.phase}</phase>
</execution>
<execution>
<id>docker-copy-logs</id>
<goals>
<goal>copy</goal>
</goals>
<phase>${docker.copy.phase}</phase>
</execution>
<execution>
<id>stop-container</id>
<goals>
Expand Down Expand Up @@ -312,11 +320,12 @@
<citrus.remote.verify.phase>verify</citrus.remote.verify.phase>

<docker.build.phase>pre-integration-test</docker.build.phase>
<docker.copy.phase>post-integration-test</docker.copy.phase>
<docker.remove.phase>post-integration-test</docker.remove.phase>
<docker.start.phase>pre-integration-test</docker.start.phase>
<docker.stop.phase>post-integration-test</docker.stop.phase>

<download.wget.phase>post-integration-test</download.wget.phase>

<failsafe.phase>none</failsafe.phase>
</properties>
</profile>
Expand All @@ -326,13 +335,13 @@
<citrus.remote.test.phase>none</citrus.remote.test.phase>
<citrus.remote.verify.phase>none</citrus.remote.verify.phase>

<docker.copy.phase>none</docker.copy.phase>
<download.wget.phase>none</download.wget.phase>
</properties>
</profile>
<profile>
<id>skip-docker-build</id>
<properties>
<docker.build.pahse>none</docker.build.pahse>
<docker.build.phase>none</docker.build.phase>
</properties>
</profile>
<profile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,79 @@
package org.citrusframework.remote.sample.entrypoint;

import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.io.IoBuilder;
import org.citrusframework.remote.CitrusRemoteApplication;
import org.citrusframework.remote.CitrusRemoteServer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

public class CustomEntrypoint {
private static final Path CITRUS_LOG_PATH = Path.of("target/logs/citrus.log");
public static final RollingFileAppender FILE_ROLLER =
((LoggerContext) LogManager.getContext())
.getConfiguration()
.getAppender("FILE_ROLLER");

public static void main(String... args) {
System.setOut(IoBuilder
.forLogger(LogManager.getLogger("system.out"))
.buildPrintStream());
CitrusRemoteServer.main(args);
CitrusRemoteServer.entrypoint(
args, List.of(CustomEntrypoint::getLogHandler, CustomEntrypoint::rorateLogHandler));
}

private static void getLogHandler(Router router) {
router.get("/citrus-logs")
.handler(CitrusRemoteApplication.wrapThrowingHandler(ctx -> {
HttpServerResponse response = ctx.response();
if (Files.exists(CITRUS_LOG_PATH)) {
response.setStatusCode(HttpStatus.OK.value())
.putHeader(
HttpHeaders.CONTENT_TYPE,
MediaType.TEXT_PLAIN_VALUE)
.putHeader(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"citrus.log\"")
.end(Files.readString(
CITRUS_LOG_PATH,
Charset.defaultCharset()))
.onSuccess(unused -> {
if (Optional.ofNullable(ctx.request().params().get("reset"))
.map(Boolean::parseBoolean)
.orElse(false)) {
rotateCitrusLog();
}
});
} else {
response.setStatusCode(HttpStatus.NOT_FOUND.value()).end();
}
}));
}

private static void rorateLogHandler(Router router) {
router.delete("/citrus-logs")
.handler(CitrusRemoteApplication.wrapThrowingHandler(ctx -> {
HttpServerResponse response = ctx.response();
rotateCitrusLog();
response.setStatusCode(HttpStatus.NO_CONTENT.value())
.end();
}));
}

private static void rotateCitrusLog() {
if (Files.exists(CITRUS_LOG_PATH)) {
FILE_ROLLER.getManager().rollover();
}
}
}
25 changes: 17 additions & 8 deletions citrus-remote-sample/src/test/resources/log4j2.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ status = info
property.LOG_DATEFORMAT_PATTERN = yyyy-MM-dd HH:mm:ss.SSS
property.CONSOLE_LOG_PATTERN = %d{${sys:LOG_DATEFORMAT_PATTERN}} %highlight{%5p} --- [%15.15t] %-40.40c{1.} : %msg%n%throwable
property.FILE_LOG_PATTERN = %d{${sys:LOG_DATEFORMAT_PATTERN}} %5p --- [%15.15t] %-40.40c{1.} : %msg%n%throwable
property.LOG_DIR = target/logs
property.LOG_NAME = citrus

appender.console.type = Console
appender.console.layout.pattern = ${sys:CONSOLE_LOG_PATTERN}
appender.console.layout.type = PatternLayout
appender.console.name = STDOUT

appender.file.layout.type = PatternLayout
appender.file.layout.pattern = ${sys:FILE_LOG_PATTERN}
appender.file.fileName = target/logs/citrus.log
appender.file.type = File
appender.file.append = false
appender.file.name = FILE
appender.fileRoller.type = RollingFile
appender.fileRoller.layout.type = PatternLayout
appender.fileRoller.layout.pattern = ${sys:FILE_LOG_PATTERN}
appender.fileRoller.fileName = ${LOG_DIR}/${LOG_NAME}.log
appender.fileRoller.filePattern = ${LOG_DIR}/${LOG_NAME}-%i.log
appender.fileRoller.strategy.type = DefaultRolloverStrategy
appender.fileRoller.strategy.action.type = DELETE
appender.fileRoller.strategy.action.basePath = ${LOG_DIR}
appender.fileRoller.strategy.action.condition.type = IfFileName
appender.fileRoller.strategy.action.condition.regex = citrus-.+\.log
appender.fileRoller.policies.type = Policies
appender.fileRoller.append = false
appender.fileRoller.name = FILE_ROLLER

rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRef.file.ref = FILE
rootLogger.appenderRefs = stdout, file
rootLogger.appenderRef.fileRoller.ref = FILE_ROLLER
rootLogger.appenderRefs = stdout, fileRoller
rootLogger.level = info
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
Expand Down Expand Up @@ -81,23 +82,23 @@ public class CitrusRemoteApplication extends AbstractVerticle {
/** Latest test reports */
private final RemoteTestResultReporter remoteTestResultReporter = new RemoteTestResultReporter();

/** Router customizations */
private final List<Consumer<Router>> routerCustomizations;

private final JsonRequestTransformer requestTransformer = new JsonRequestTransformer();
private final JsonResponseTransformer responseTransformer = new JsonResponseTransformer();

/**
* Default constructor using default configuration.
*/
@SuppressWarnings("unused")
public CitrusRemoteApplication() {
this(new CitrusRemoteConfiguration());
}

/**
* Constructor with given application configuration.
* Constructor with given application configuration and route customizations.
* @param configuration
* @param routerCustomizations
*/
public CitrusRemoteApplication(CitrusRemoteConfiguration configuration) {
public CitrusRemoteApplication(
CitrusRemoteConfiguration configuration,
List<Consumer<Router>> routerCustomizations) {
this.configuration = configuration;
this.routerCustomizations = Optional.ofNullable(routerCustomizations)
.orElse(Collections.emptyList());
}

@Override
Expand All @@ -120,6 +121,7 @@ public void start() {
addResultsEndpoints(router);
addRunEndpoints(router);
addConfigEndpoints(router);
routerCustomizations.forEach(customization -> customization.accept(router));

getVertx().createHttpServer()
.requestHandler(router)
Expand All @@ -139,14 +141,16 @@ private static void addFilesEndpoint(Router router) {
router.get("/files/:name")
.handler(wrapThrowingHandler(ctx -> {
HttpServerResponse response = ctx.response();
response.putHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_OCTET_STREAM);
String fileName = ctx.pathParam("name");
Path file = Path.of(fileName);
if (Files.isRegularFile(file)) {
response.putHeader(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFileName() + "\"")
response.putHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_OCTET_STREAM)
.putHeader(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFileName() + "\"")
.sendFile(fileName);
} else {
response.setStatusCode(HttpResponseStatus.NOT_FOUND.code()).end();
}
}));
}
Expand All @@ -163,11 +167,11 @@ private void addResultsEndpoints(Router router) {
if (remoteResultFuture != null) {
response.putHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON);
remoteResultFuture.timeout(timeout, TimeUnit.MILLISECONDS)
.onSuccess(results ->
response.end(responseTransformer.render(results)))
.onFailure(throwable -> response
.setStatusCode(HttpResponseStatus.PARTIAL_CONTENT.code())
.end(responseTransformer.render(Collections.emptyList())));
.onSuccess(results ->
response.end(responseTransformer.render(results)))
.onFailure(throwable -> response
.setStatusCode(HttpResponseStatus.PARTIAL_CONTENT.code())
.end(responseTransformer.render(Collections.emptyList())));
} else {
final List<RemoteResult> results = new ArrayList<>();
remoteTestResultReporter.getLatestResults().doWithResults(result ->
Expand Down Expand Up @@ -291,8 +295,8 @@ private void addConfigEndpoints(Router router) {
CitrusAppConfiguration.class))));
}


private static Handler<RoutingContext> wrapThrowingHandler(ThrowingHandler<RoutingContext> handler) {
public static Handler<RoutingContext> wrapThrowingHandler(
ThrowingHandler<RoutingContext> handler) {
return ctx -> {
try {
handler.handle(ctx);
Expand Down Expand Up @@ -371,8 +375,4 @@ private boolean isPresent(String className) {
return false;
}
}

interface ThrowingHandler<T> {
void handle(T t) throws Exception;
}
}
Loading