From 8dda800abc0e39e2acf4a3ad5f2ab9b6f0d0d3eb Mon Sep 17 00:00:00 2001 From: Mark Elliot Date: Fri, 23 Jul 2021 14:06:23 -0400 Subject: [PATCH] Add logging and a basic smoke test --- barista/build.gradle.kts | 7 ++- barista/src/main/java/barista/Logging.java | 48 ++++++++++++++++ barista/src/main/java/barista/Server.java | 18 ++++-- .../src/test/java/barista/ServerTests.java | 55 +++++++++++++++++++ versions.lock | 5 ++ versions.props | 2 + 6 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 barista/src/main/java/barista/Logging.java create mode 100644 barista/src/test/java/barista/ServerTests.java diff --git a/barista/build.gradle.kts b/barista/build.gradle.kts index d5b2283..5d43974 100644 --- a/barista/build.gradle.kts +++ b/barista/build.gradle.kts @@ -16,6 +16,12 @@ dependencies { implementation("com.google.guava:guava") implementation("io.undertow:undertow-core") + implementation("org.apache.logging.log4j:log4j-core") + implementation("org.apache.logging.log4j:log4j-jul") + implementation("org.apache.logging.log4j:log4j-slf4j-impl") + // users of this library should have access to the slf4j api for their own logging + api("org.slf4j:slf4j-api") + testImplementation(platform("org.junit:junit-bom")) testImplementation("org.junit.jupiter:junit-jupiter-engine") testImplementation("org.assertj:assertj-core") @@ -29,7 +35,6 @@ tasks.test { } java { - withJavadocJar() withSourcesJar() } diff --git a/barista/src/main/java/barista/Logging.java b/barista/src/main/java/barista/Logging.java new file mode 100644 index 0000000..04abfa2 --- /dev/null +++ b/barista/src/main/java/barista/Logging.java @@ -0,0 +1,48 @@ +package barista; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Filter.Result; +import org.apache.logging.log4j.core.appender.ConsoleAppender; +import org.apache.logging.log4j.core.config.Configurator; +import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; +import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; +import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; + +final class Logging { + private static final String STDOUT = "stdout"; + + public static void configure() { + ConfigurationBuilder builder = + ConfigurationBuilderFactory.newConfigurationBuilder() + .setStatusLevel(Level.ERROR) + .setConfigurationName("barista"); + + LayoutComponentBuilder layout = + builder.newLayout("PatternLayout") + .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"); + FilterComponentBuilder filter = + builder.newFilter("MarkerFilter", Result.DENY, Result.NEUTRAL) + .addAttribute("marker", "FLOW"); + + AppenderComponentBuilder appenderBuilder = + builder.newAppender(STDOUT, "CONSOLE") + .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT) + .add(layout) + .add(filter); + + LoggerComponentBuilder logger = + builder.newLogger("org.apache.logging.log4j", Level.DEBUG) + .add(builder.newAppenderRef(STDOUT)) + .addAttribute("additivity", false); + + builder.add(appenderBuilder) + .add(logger) + .add(builder.newRootLogger(Level.INFO).add(builder.newAppenderRef(STDOUT))); + + Configurator.initialize(builder.build()); + } +} diff --git a/barista/src/main/java/barista/Server.java b/barista/src/main/java/barista/Server.java index a059896..e2db6c3 100644 --- a/barista/src/main/java/barista/Server.java +++ b/barista/src/main/java/barista/Server.java @@ -10,6 +10,7 @@ import io.undertow.Undertow; import java.nio.file.Paths; import java.util.LinkedHashSet; +import java.util.Objects; import java.util.Set; public final class Server { @@ -31,42 +32,49 @@ public static Builder builder() { public static final class Builder { private int port = 8443; - private Set> openEndpoints = new LinkedHashSet<>(); - private Set> authEndpoints = new LinkedHashSet<>(); - private Set allowedOrigins = new LinkedHashSet<>(); + private final Set> openEndpoints = new LinkedHashSet<>(); + private final Set> authEndpoints = new LinkedHashSet<>(); + private final Set allowedOrigins = new LinkedHashSet<>(); private SerDe serde = new SerDe.ObjectMapperSerDe(); - private Authz authz = null; + private Authz authz = Authz.denyAll(); private boolean tls = true; private Builder() {} public Builder port(int port) { + Preconditions.checkArgument( + 0 < port && port < 65536, "Port must be in range [1, 65535]"); this.port = port; return this; } public Builder endpoint(Endpoints.Open endpoint) { + Objects.requireNonNull(endpoint); openEndpoints.add(endpoint); return this; } public Builder endpoint( Endpoints.VerifiedAuth endpoint) { + Objects.requireNonNull(endpoint); authEndpoints.add(endpoint); return this; } public Builder allowOrigin(String origin) { + Objects.requireNonNull(origin); allowedOrigins.add(origin); return this; } public Builder serde(SerDe serde) { + Objects.requireNonNull(serde); this.serde = serde; return this; } public Builder authz(Authz authz) { + Objects.requireNonNull(authz); this.authz = authz; return this; } @@ -77,6 +85,8 @@ public Builder disableTls() { } public Server start() { + Logging.configure(); + Preconditions.checkNotNull(authz); EndpointHandlerBuilder handler = new EndpointHandlerBuilder(serde, authz); diff --git a/barista/src/test/java/barista/ServerTests.java b/barista/src/test/java/barista/ServerTests.java new file mode 100644 index 0000000..76ba0bd --- /dev/null +++ b/barista/src/test/java/barista/ServerTests.java @@ -0,0 +1,55 @@ +package barista; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import org.junit.jupiter.api.Test; + +final class ServerTests { + private static final HttpClient CLIENT = HttpClient.newHttpClient(); + + @Test + void smokeTest() throws IOException, InterruptedException { + Server.builder().port(8080).disableTls().endpoint(new HelloWorldEndpoint()).start(); + + assertResponse("http://localhost:8080/hello-world", 200, "\"Hello World\""); + assertResponse("http://localhost:8080/missing", 404, "Unknown API Endpoint"); + } + + private void assertResponse(String uri, int statusCode, String expectedResponseText) + throws IOException, InterruptedException { + HttpResponse helloWorldResult = + CLIENT.send( + HttpRequest.newBuilder().uri(URI.create(uri)).GET().build(), + BodyHandlers.ofString()); + assertThat(helloWorldResult.statusCode()).isEqualTo(statusCode); + assertThat(helloWorldResult.body()).isEqualTo(expectedResponseText); + } + + private static final class HelloWorldEndpoint implements Endpoints.Open { + @Override + public String call(Void unused) { + return "Hello World"; + } + + @Override + public Class requestClass() { + return Void.class; + } + + @Override + public String path() { + return "/hello-world"; + } + + @Override + public HttpMethod method() { + return HttpMethod.GET; + } + } +} diff --git a/versions.lock b/versions.lock index d60588c..2afe8b6 100644 --- a/versions.lock +++ b/versions.lock @@ -17,12 +17,17 @@ com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava (1 c com.google.j2objc:j2objc-annotations:1.1 (1 constraints: b609eba0) com.jakewharton.nopen:nopen-annotations:1.0.1 (1 constraints: 0405f135) io.undertow:undertow-core:2.1.0.Final (1 constraints: 1d07a45a) +org.apache.logging.log4j:log4j-api:2.14.1 (3 constraints: ea2dae0e) +org.apache.logging.log4j:log4j-core:2.14.1 (2 constraints: 0d16b624) +org.apache.logging.log4j:log4j-jul:2.14.1 (1 constraints: 3a053c3b) +org.apache.logging.log4j:log4j-slf4j-impl:2.14.1 (1 constraints: 3a053c3b) org.checkerframework:checker-qual:3.12.0 (2 constraints: 461aeb59) org.codehaus.mojo:animal-sniffer-annotations:1.17 (1 constraints: ed09d8aa) org.jboss.logging:jboss-logging:3.4.1.Final (3 constraints: f03036d7) org.jboss.threads:jboss-threads:3.1.0.Final (2 constraints: 531a8642) org.jboss.xnio:xnio-api:3.8.0.Final (2 constraints: 691ac544) org.jboss.xnio:xnio-nio:3.8.0.Final (1 constraints: c10d9a30) +org.slf4j:slf4j-api:1.7.32 (2 constraints: 1916cc25) org.wildfly.client:wildfly-client-config:1.0.1.Final (1 constraints: 940c6308) org.wildfly.common:wildfly-common:1.5.2.Final (3 constraints: c62f0652) org.yaml:snakeyaml:1.27 (1 constraints: 7217fa27) diff --git a/versions.props b/versions.props index dddfe07..45ef352 100644 --- a/versions.props +++ b/versions.props @@ -5,6 +5,8 @@ com.google.errorprone:error_prone_core = 2.7.1 com.google.guava:guava = 27.0.1-jre com.jakewharton.nopen:* = 1.0.1 io.undertow:undertow-core = 2.1.0.Final +org.apache.logging.log4j:* = 2.14.1 org.assertj:assertj-core = 3.12.2 org.junit:junit-bom = 5.7.2 org.junit.jupiter:junit-jupiter-engine = 5.7.2 +org.slf4j:* = 1.7.32