From 9b80a4e889965802e1e8a3f60c49ba6c73a554ba Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sat, 9 May 2020 18:31:57 +0200 Subject: [PATCH] introduce UraClientConfiguration class to encapsulate client config Legacy constructors use new pattern internally. --- CHANGELOG.md | 1 + .../de/stklcode/pubtrans/ura/UraClient.java | 42 +++--- .../pubtrans/ura/UraClientConfiguration.java | 121 ++++++++++++++++++ .../ura/UraClientConfigurationTest.java | 34 +++++ 4 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 src/main/java/de/stklcode/pubtrans/ura/UraClientConfiguration.java create mode 100644 src/test/java/de/stklcode/pubtrans/ura/UraClientConfigurationTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ba50fdf..3691156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Changes * Using native Java 11 HTTP client +* Client configuration with separate `UraClientConfiguration` class and builder ## 1.3.0 - 2019-12-04 diff --git a/src/main/java/de/stklcode/pubtrans/ura/UraClient.java b/src/main/java/de/stklcode/pubtrans/ura/UraClient.java index 016bca0..114f8cd 100644 --- a/src/main/java/de/stklcode/pubtrans/ura/UraClient.java +++ b/src/main/java/de/stklcode/pubtrans/ura/UraClient.java @@ -46,9 +46,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; public class UraClient implements Serializable { private static final long serialVersionUID = -1183740075816686611L; - private static final String DEFAULT_INSTANT_URL = "/interfaces/ura/instant_V1"; - private static final String DEFAULT_STREAM_URL = "/interfaces/ura/stream_V1"; - private static final String PAR_STOP_ID = "StopID"; private static final String PAR_STOP_NAME = "StopPointName"; private static final String PAR_STOP_STATE = "StopPointState"; @@ -81,32 +78,43 @@ public class UraClient implements Serializable { private static final String[] REQUEST_MESSAGE = {PAR_STOP_NAME, PAR_STOP_ID, PAR_STOP_INDICATOR, PAR_STOP_STATE, PAR_GEOLOCATION, PAR_MSG_UUID, PAR_MSG_TYPE, PAR_MSG_PRIORITY, PAR_MSG_TEXT}; - private final String baseURL; - private final String instantURL; - private final String streamURL; + private final UraClientConfiguration config; private final ObjectMapper mapper; + /** + * Constructor from {@link UraClientConfiguration}. + * + * @param config The configuration. + * @since 2.0 + */ + public UraClient(final UraClientConfiguration config) { + this.config = config; + this.mapper = new ObjectMapper(); + } + /** * Constructor with base URL and default API paths. * * @param baseURL The base URL (with protocol, without trailing slash). */ public UraClient(final String baseURL) { - this(baseURL, DEFAULT_INSTANT_URL, DEFAULT_STREAM_URL); + this(UraClientConfiguration.forBaseURL(baseURL).build()); } /** * Constructor with base URL and custom API paths. * - * @param baseURL The base URL (including protocol). - * @param instantURL The path for instant requests. - * @param streamURL The path for stream requests. + * @param baseURL The base URL (including protocol). + * @param instantPath The path for instant requests. + * @param streamPath The path for stream requests. */ - public UraClient(final String baseURL, final String instantURL, final String streamURL) { - this.baseURL = baseURL; - this.instantURL = instantURL; - this.streamURL = streamURL; - this.mapper = new ObjectMapper(); + public UraClient(final String baseURL, final String instantPath, final String streamPath) { + this( + UraClientConfiguration.forBaseURL(baseURL) + .withInstantPath(instantPath) + .withStreamPath(streamPath) + .build() + ); } /** @@ -283,7 +291,7 @@ public class UraClient implements Serializable { public AsyncUraTripReader getTripsStream(final Query query, final List> consumers) throws IOException { // Create the reader. AsyncUraTripReader reader = new AsyncUraTripReader( - new URL(requestURL(baseURL + streamURL, REQUEST_TRIP, query)), + new URL(requestURL(config.getBaseURL() + config.getStreeamPath(), REQUEST_TRIP, query)), consumers ); @@ -391,7 +399,7 @@ public class UraClient implements Serializable { * @throws IOException on errors */ private InputStream requestInstant(final String[] returnList, final Query query) throws IOException { - return request(requestURL(baseURL + instantURL, returnList, query)); + return request(requestURL(config.getBaseURL() + config.getInstantPath(), returnList, query)); } /** diff --git a/src/main/java/de/stklcode/pubtrans/ura/UraClientConfiguration.java b/src/main/java/de/stklcode/pubtrans/ura/UraClientConfiguration.java new file mode 100644 index 0000000..5ba3bc6 --- /dev/null +++ b/src/main/java/de/stklcode/pubtrans/ura/UraClientConfiguration.java @@ -0,0 +1,121 @@ +package de.stklcode.pubtrans.ura; + +import java.io.Serializable; + +/** + * Configurstion Object for the {@link UraClient}. + * + * @author Stefan Kalscheuer + * @since 2.0 + */ +public class UraClientConfiguration implements Serializable { + private static final long serialVersionUID = 1L; + + private static final String DEFAULT_INSTANT_PATH = "/interfaces/ura/instant_V1"; + private static final String DEFAULT_STREAM_PATH = "/interfaces/ura/stream_V1"; + + private final String baseURL; + private final String instantPath; + private final String streamPath; + + /** + * Get new configuration {@link Builder} for given base URL. + * This URL is the only option required. + * + * @param baseURL The base URL (with protocol, without trailing slash). + * @return Configuration Builder instance. + */ + public static Builder forBaseURL(final String baseURL) { + return new Builder(baseURL); + } + + /** + * Construct new configuration object from Builder. + * + * @param builder The builder instance. + */ + private UraClientConfiguration(Builder builder) { + this.baseURL = builder.baseURL; + this.instantPath = builder.instantPath; + this.streamPath = builder.streamPath; + } + + /** + * Get the API base URL. + * + * @return Base URL. + */ + public String getBaseURL() { + return baseURL; + } + + /** + * Get the API instant endpoint path. + * + * @return Instant endpoint path. + */ + public String getInstantPath() { + return this.instantPath; + } + + /** + * Get the API stream endpoint path. + * + * @return Stream endpoint path. + */ + public String getStreeamPath() { + return this.streamPath; + } + + /** + * Builder for {@link UraClientConfiguration} objects. + */ + public static class Builder { + private final String baseURL; + private String instantPath; + private String streamPath; + + /** + * Initialize the builder with mandatory base URL. + * Use {@link UraClientConfiguration#forBaseURL(String)} to get a builder instance. + * + * @param baseURL The base URL. + */ + private Builder(String baseURL) { + this.baseURL = baseURL; + this.instantPath = DEFAULT_INSTANT_PATH; + this.streamPath = DEFAULT_STREAM_PATH; + } + + /** + * Specify a custom path to the instant API. + * + * @param instantPath Instant endpoint path. + * @return The builder. + */ + public Builder withInstantPath(String instantPath) { + this.instantPath = instantPath; + return this; + } + + /** + * Specify a custom path to the stream API. + * + * @param streamPath Stream endpoint path. + * @return The builder. + */ + public Builder withStreamPath(String streamPath) { + this.streamPath = streamPath; + return this; + } + + /** + * Finally build the configuration object. + * + * @return The configuration. + */ + public UraClientConfiguration build() { + return new UraClientConfiguration(this); + } + } +} diff --git a/src/test/java/de/stklcode/pubtrans/ura/UraClientConfigurationTest.java b/src/test/java/de/stklcode/pubtrans/ura/UraClientConfigurationTest.java new file mode 100644 index 0000000..749b37f --- /dev/null +++ b/src/test/java/de/stklcode/pubtrans/ura/UraClientConfigurationTest.java @@ -0,0 +1,34 @@ +package de.stklcode.pubtrans.ura; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Unit test for {@link UraClientConfiguration}. + * + * @author Stefan Kalscheuer + */ +public class UraClientConfigurationTest { + @Test + public void configBuilderTest() { + final String baseURL = "https://ura.example.com"; + final String instantPath = "/path/to/instant"; + final String streamPath = "/path/to/stream"; + + // With Base-URL only. + UraClientConfiguration config = UraClientConfiguration.forBaseURL(baseURL).build(); + assertEquals(baseURL, config.getBaseURL(), "Unexpected base URL"); + assertEquals("/interfaces/ura/instant_V1", config.getInstantPath(), "Unexpected default instant path"); + assertEquals("/interfaces/ura/stream_V1", config.getStreeamPath(), "Unexpected default stream path"); + + // With custom paths. + config = UraClientConfiguration.forBaseURL(baseURL) + .withInstantPath(instantPath) + .withStreamPath(streamPath) + .build(); + assertEquals(baseURL, config.getBaseURL(), "Unexpected base URL"); + assertEquals(instantPath, config.getInstantPath(), "Unexpected custom instant path"); + assertEquals(streamPath, config.getStreeamPath(), "Unexpected custom stream path"); + } +}