From 77ef086fe03ee45ec5804dafb15a9c16897360c8 Mon Sep 17 00:00:00 2001 From: "I.Alfer" Date: Thu, 2 Nov 2023 16:57:46 +0100 Subject: [PATCH] BT-4349 Java docs for configurations --- .../fauna/common/configuration/Endpoint.java | 21 ++++ .../common/configuration/FaunaConfig.java | 109 +++++++++++++++++- .../configuration/HttpClientConfig.java | 48 ++++++++ .../fauna/common/configuration/Version.java | 13 +++ .../com/fauna/common/connection/Auth.java | 16 +++ .../fauna/common/connection/Connection.java | 66 ++++++++++- .../common/connection/RequestBuilder.java | 44 +++++++ .../common/connection/ConnectionTest.java | 14 ++- .../java/com/fauna/client/FaunaClient.java | 64 +++++++++- 9 files changed, 383 insertions(+), 12 deletions(-) diff --git a/common/src/main/java/com/fauna/common/configuration/Endpoint.java b/common/src/main/java/com/fauna/common/configuration/Endpoint.java index 6dd414a4..2acf224a 100644 --- a/common/src/main/java/com/fauna/common/configuration/Endpoint.java +++ b/common/src/main/java/com/fauna/common/configuration/Endpoint.java @@ -1,16 +1,37 @@ package com.fauna.common.configuration; +/** + * Endpoint enumerates the various endpoints available for connecting to Fauna. + * It includes the default cloud endpoint and a local endpoint for development purposes. + */ public enum Endpoint { + /** + * The default cloud endpoint for connecting to Fauna. + */ DEFAULT("https://db.fauna.com"), + + /** + * A local endpoint for connecting to a Fauna instance running on localhost. + */ LOCAL("http://localhost:8443"); private final String stringValue; + /** + * Constructs a new Endpoint enum instance. + * + * @param stringValue The string representation of the endpoint URL. + */ Endpoint(String stringValue) { this.stringValue = stringValue; } + /** + * Returns the string representation of the endpoint URL. + * + * @return A string representing the endpoint URL. + */ @Override public String toString() { return this.stringValue; diff --git a/common/src/main/java/com/fauna/common/configuration/FaunaConfig.java b/common/src/main/java/com/fauna/common/configuration/FaunaConfig.java index 86e7256f..834ede43 100644 --- a/common/src/main/java/com/fauna/common/configuration/FaunaConfig.java +++ b/common/src/main/java/com/fauna/common/configuration/FaunaConfig.java @@ -3,6 +3,10 @@ import java.time.Duration; import java.util.Map; +/** + * FaunaConfig is a configuration class used to set up and configure a connection to Fauna. + * It encapsulates various settings such as the endpoint URL, secret key, query timeout, and others. + */ public class FaunaConfig { private final String endpoint; @@ -19,6 +23,11 @@ public class FaunaConfig { private static final Duration DEFAULT_QUERY_TIMEOUT = Duration.ofSeconds(5); + /** + * Private constructor for FaunaConfig. + * + * @param builder The builder used to create the FaunaConfig instance. + */ private FaunaConfig(Builder builder) { this.endpoint = builder.endpoint; this.secret = builder.secret; @@ -29,38 +38,83 @@ private FaunaConfig(Builder builder) { this.traceParent = builder.traceParent; } + /** + * Gets the Fauna endpoint URL. + * + * @return A String representing the endpoint URL. + * The default is https://db.fauna.com + */ public String getEndpoint() { return endpoint; } + /** + * Gets the secret key used for authentication. + * + * @return A String representing the secret key. + */ public String getSecret() { return secret; } + /** + * Gets the query timeout setting. + * + * @return A Duration representing the maximum amount of time Fauna will execute the query before marking it failed. + * The default is 5 sec + */ public Duration getQueryTimeout() { return queryTimeout; } + /** + * Gets the linearized setting. + * + * @return A Boolean indicating whether to unconditionally run the query as strictly serialized. + */ public Boolean getLinearized() { return linearized; } + /** + * Gets the type check setting. + * + * @return A Boolean indicating whether to enable or disable type checking of the query before evaluation. + */ public Boolean getTypeCheck() { return typeCheck; } + /** + * Gets the query tags. + * + * @return A Map of Strings representing tags associated with the query. + */ public Map getQueryTags() { return queryTags; } + /** + * Gets the trace parent setting. + * + * @return A String representing a traceparent associated with the query. + */ public String getTraceParent() { return traceParent; } + /** + * Creates a new builder for FaunaConfig. + * + * @return A new instance of Builder. + */ public static Builder builder() { return new Builder(); } + /** + * Builder class for FaunaConfig. Follows the Builder Design Pattern. + */ public static class Builder { private String endpoint = Endpoint.DEFAULT.toString(); private String secret; @@ -70,45 +124,98 @@ public static class Builder { private Map queryTags; private String traceParent; + /** + * Sets the endpoint URL. + * + * @param endpoint A String representing the endpoint URL. + * @return The current Builder instance. + */ public Builder endpoint(String endpoint) { this.endpoint = endpoint; return this; } + /** + * Sets the secret key. + * + * @param secret A String representing the secret key. + * @return The current Builder instance. + */ public Builder secret(String secret) { this.secret = secret; return this; } + /** + * Sets the query timeout. + * + * @param queryTimeout A Duration representing the query timeout. + * Controls the maximum amount of time Fauna will execute your query before marking it failed. + * @return The current Builder instance. + */ public Builder queryTimeout(Duration queryTimeout) { this.queryTimeout = queryTimeout; return this; } + /** + * Sets the linearized setting. + * + * @param linearized A Boolean indicating whether to run the query as strictly serialized. + * This affects read-only transactions. + * Transactions which write will always be strictly serialized. + * @return The current Builder instance. + */ public Builder linearized(Boolean linearized) { this.linearized = linearized; return this; } + /** + * Sets the type check setting. + * + * @param typeCheck A Boolean indicating whether to enable or disable type checking of the query. + * If not set, the value configured on the Client will be used. + * If neither is set, Fauna will use the value of the "typechecked" flag on the database configuration. + * @return The current Builder instance. + */ public Builder typeCheck(Boolean typeCheck) { this.typeCheck = typeCheck; return this; } + /** + * Sets the query tags. + * + * @param queryTags A Map of Strings representing the query tags. + * Tags to associate with the query. See `logging <...>`_ + * @return The current Builder instance. + */ public Builder queryTags(Map queryTags) { this.queryTags = queryTags; return this; } + /** + * Sets the trace parent. + * + * @param traceParent A String representing the traceparent associated with the query. + * See `logging <...>`_ Must match format: ... + * @return The current Builder instance. + */ public Builder traceParent(String traceParent) { this.traceParent = traceParent; return this; } + /** + * Builds and returns a new FaunaConfig instance. + * + * @return A new instance of FaunaConfig. + */ public FaunaConfig build() { return new FaunaConfig(this); } } - } diff --git a/common/src/main/java/com/fauna/common/configuration/HttpClientConfig.java b/common/src/main/java/com/fauna/common/configuration/HttpClientConfig.java index 38796c75..3ef52527 100644 --- a/common/src/main/java/com/fauna/common/configuration/HttpClientConfig.java +++ b/common/src/main/java/com/fauna/common/configuration/HttpClientConfig.java @@ -2,6 +2,10 @@ import java.time.Duration; +/** + * HttpClientConfig encapsulates configuration settings for an HTTP client. + * It includes settings such as connection timeout and maximum number of connections. + */ public class HttpClientConfig { private final Duration connectTimeout; @@ -11,38 +15,82 @@ public class HttpClientConfig { private static final int DEFAULT_MAX_CONNECTIONS = 20; + /** + * Private constructor for HttpClientConfig. + * + * @param builder The builder used to create the HttpClientConfig instance. + */ private HttpClientConfig(Builder builder) { this.connectTimeout = builder.connectTimeout; this.maxConnections = builder.maxConnections; } + /** + * Gets the connection timeout setting. + * + * @return A Duration representing the maximum time to wait for a connection to be established. + * The default is 5 seconds. + */ public Duration getConnectTimeout() { return connectTimeout; } + /** + * Gets the maximum number of connections setting. + * + * @return An integer representing the maximum number of simultaneous connections. + * The default is 20. + */ public int getMaxConnections() { return maxConnections; } + /** + * Creates a new builder for HttpClientConfig. + * + * @return A new instance of Builder. + */ public static Builder builder() { return new Builder(); } + /** + * Builder class for HttpClientConfig. Follows the Builder Design Pattern. + */ public static class Builder { private Duration connectTimeout = DEFAULT_CONNECT_TIMEOUT; private int maxConnections = DEFAULT_MAX_CONNECTIONS; + /** + * Sets the connection timeout. + * + * @param connectTimeout A Duration representing the connection timeout. + * The default is 5 seconds. + * @return The current Builder instance. + */ public Builder connectTimeout(Duration connectTimeout) { this.connectTimeout = connectTimeout; return this; } + /** + * Sets the maximum number of connections. + * + * @param maxConnections An integer representing the maximum number of connections. + * The default is 20. + * @return The current Builder instance. + */ public Builder maxConnections(int maxConnections) { this.maxConnections = maxConnections; return this; } + /** + * Builds and returns a new HttpClientConfig instance. + * + * @return A new instance of HttpClientConfig. + */ public HttpClientConfig build() { return new HttpClientConfig(this); } diff --git a/common/src/main/java/com/fauna/common/configuration/Version.java b/common/src/main/java/com/fauna/common/configuration/Version.java index 39590c44..c1a2ef30 100644 --- a/common/src/main/java/com/fauna/common/configuration/Version.java +++ b/common/src/main/java/com/fauna/common/configuration/Version.java @@ -4,11 +4,24 @@ import java.io.InputStream; import java.util.Properties; +/** + * The Version class is a utility class that provides functionality to retrieve the software version. + * It reads the version information from a properties file. + */ public final class Version { + /** + * Private constructor to prevent instantiation of this utility class. + */ private Version() { } + /** + * Retrieves the software version from the "version.properties" file. + * + * @return A String representing the software version. + * @throws RuntimeException If the "version.properties" file is not found or if there is an issue reading the file. + */ public static String getVersion() { Properties properties = new Properties(); try (InputStream input = Version.class.getClassLoader().getResourceAsStream("version.properties")) { diff --git a/common/src/main/java/com/fauna/common/connection/Auth.java b/common/src/main/java/com/fauna/common/connection/Auth.java index f2da686e..d8c50aa3 100644 --- a/common/src/main/java/com/fauna/common/connection/Auth.java +++ b/common/src/main/java/com/fauna/common/connection/Auth.java @@ -1,13 +1,29 @@ package com.fauna.common.connection; +/** + * The Auth class is responsible for handling authentication, providing functionality to generate bearer tokens. + */ class Auth { private final String secret; + /** + * Constructs a new Auth instance with the provided secret. + * + * @param secret The secret key used for authentication. + */ public Auth(String secret) { + if (secret == null || secret.trim().isEmpty()) { + throw new IllegalArgumentException("Secret cannot be null or empty"); + } this.secret = secret; } + /** + * Generates a bearer token using the secret provided during construction. + * + * @return A string representing the bearer token. + */ public String bearer() { return "Bearer " + secret; } diff --git a/common/src/main/java/com/fauna/common/connection/Connection.java b/common/src/main/java/com/fauna/common/connection/Connection.java index fddff27d..b8f3bccb 100644 --- a/common/src/main/java/com/fauna/common/connection/Connection.java +++ b/common/src/main/java/com/fauna/common/connection/Connection.java @@ -7,22 +7,33 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; +/** + * The Connection class is responsible for establishing and managing the connection to Fauna. + * It utilizes the Java HTTP client to send requests and receive responses. + */ public class Connection { private final RequestBuilder requestBuilder; private final HttpClientConfig httpClientConfig; private final HttpClient httpClient; - private final JvmDriver jvmDriver; - + /** + * Creates a new builder for Connection. + * + * @return A new instance of Builder. + */ public static Builder builder() { return new Builder(); } + /** + * Private constructor for Connection. + * + * @param builder The builder used to create the Connection instance. + */ private Connection(Builder builder) { this.httpClientConfig = builder.httpClientConfig; this.requestBuilder = RequestBuilder.builder() @@ -30,16 +41,26 @@ private Connection(Builder builder) { .jvmDriver(builder.jvmDriver) .build(); this.httpClient = createHttpClient(); - this.jvmDriver = builder.jvmDriver; } - Connection(RequestBuilder requestBuilder, HttpClientConfig httpClientConfig, HttpClient httpClient, JvmDriver jvmDriver) { + /** + * Secondary constructor for Connection, primarily used for testing. + * + * @param requestBuilder The request builder. + * @param httpClientConfig The HTTP client configuration. + * @param httpClient The HTTP client. + */ + Connection(RequestBuilder requestBuilder, HttpClientConfig httpClientConfig, HttpClient httpClient) { this.requestBuilder = requestBuilder; this.httpClientConfig = httpClientConfig; this.httpClient = httpClient; - this.jvmDriver = jvmDriver; } + /** + * Creates and configures the HTTP client. + * + * @return An instance of HttpClient. + */ private HttpClient createHttpClient() { return HttpClient.newBuilder() .connectTimeout(httpClientConfig.getConnectTimeout()) @@ -47,30 +68,63 @@ private HttpClient createHttpClient() { .build(); } + /** + * Performs an asynchronous HTTP request to Fauna with the provided FQL query. + * + * @param fql The Fauna Query Language query to be executed. + * @return A CompletableFuture that, when completed, will return the HttpResponse. + */ public CompletableFuture> performRequest(String fql) { HttpRequest request = requestBuilder.buildRequest(fql); return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()); } + /** + * Builder class for Connection. Follows the Builder Design Pattern. + */ public static class Builder { private FaunaConfig faunaConfig; private HttpClientConfig httpClientConfig; private JvmDriver jvmDriver; + /** + * Sets the FaunaConfig for the Connection. + * + * @param faunaConfig The configuration settings for Fauna. + * @return The current Builder instance. + */ public Builder faunaConfig(FaunaConfig faunaConfig) { this.faunaConfig = faunaConfig; return this; } + /** + * Sets the HttpClientConfig for the Connection. + * + * @param httpClientConfig The HTTP client configuration. + * @return The current Builder instance. + */ public Builder httpClientConfig(HttpClientConfig httpClientConfig) { this.httpClientConfig = httpClientConfig; return this; } + + /** + * Sets the JvmDriver for the Connection. + * + * @param jvmDriver The JVM driver information. + * @return The current Builder instance. + */ public Builder jvmDriver(JvmDriver jvmDriver) { this.jvmDriver = jvmDriver; return this; } + /** + * Builds and returns a new Connection instance. + * + * @return A new instance of Connection. + */ public Connection build() { return new Connection(this); } diff --git a/common/src/main/java/com/fauna/common/connection/RequestBuilder.java b/common/src/main/java/com/fauna/common/connection/RequestBuilder.java index 78297ec7..4a88560e 100644 --- a/common/src/main/java/com/fauna/common/connection/RequestBuilder.java +++ b/common/src/main/java/com/fauna/common/connection/RequestBuilder.java @@ -21,6 +21,9 @@ import static com.fauna.common.connection.Headers.TRACE_PARENT; import static com.fauna.common.connection.Headers.TYPE_CHECK; +/** + * The RequestBuilder class is responsible for building HTTP requests for communicating with Fauna. + */ class RequestBuilder { private final FaunaConfig faunaConfig; @@ -28,10 +31,20 @@ class RequestBuilder { private final DriverEnvironment driverEnvironment; private final URI uri; + /** + * Creates a new builder for RequestBuilder. + * + * @return A new instance of Builder. + */ public static Builder builder() { return new Builder(); } + /** + * Private constructor for RequestBuilder. + * + * @param builder The builder used to create the RequestBuilder instance. + */ private RequestBuilder(Builder builder) { this.faunaConfig = builder.faunaConfig; uri = URI.create(faunaConfig.getEndpoint()); @@ -39,6 +52,12 @@ private RequestBuilder(Builder builder) { this.driverEnvironment = new DriverEnvironment(builder.jvmDriver); } + /** + * Builds and returns an HTTP request for a given Fauna query string (FQL). + * + * @param fql The Fauna query string. + * @return An HttpRequest object configured for the Fauna query. + */ public HttpRequest buildRequest(String fql) { Map headers = buildHeaders(); HttpRequest.Builder httpRequestBuilder = HttpRequest.newBuilder() @@ -48,6 +67,11 @@ public HttpRequest buildRequest(String fql) { return httpRequestBuilder.build(); } + /** + * Builds and returns a map of HTTP headers required for the Fauna request. + * + * @return A Map of header names to header values. + */ private Map buildHeaders() { Map headers = new HashMap<>(); headers.put(AUTHORIZATION, auth.bearer()); @@ -77,20 +101,40 @@ private Map buildHeaders() { return headers; } + /** + * Builder class for RequestBuilder. Follows the Builder Design Pattern. + */ public static class Builder { private FaunaConfig faunaConfig; private JvmDriver jvmDriver; + /** + * Sets the FaunaConfig for the RequestBuilder. + * + * @param faunaConfig The configuration settings for Fauna. + * @return The current Builder instance. + */ public Builder faunaConfig(FaunaConfig faunaConfig) { this.faunaConfig = faunaConfig; return this; } + /** + * Sets the JvmDriver for the RequestBuilder. + * + * @param jvmDriver The JVM driver information. + * @return The current Builder instance. + */ public Builder jvmDriver(JvmDriver jvmDriver) { this.jvmDriver = jvmDriver; return this; } + /** + * Builds and returns a new RequestBuilder instance. + * + * @return A new instance of RequestBuilder. + */ RequestBuilder build() { return new RequestBuilder(this); } diff --git a/common/src/test/java/com/fauna/common/connection/ConnectionTest.java b/common/src/test/java/com/fauna/common/connection/ConnectionTest.java index b6ed0412..9d08f54c 100644 --- a/common/src/test/java/com/fauna/common/connection/ConnectionTest.java +++ b/common/src/test/java/com/fauna/common/connection/ConnectionTest.java @@ -1,5 +1,6 @@ package com.fauna.common.connection; +import com.fauna.common.configuration.Endpoint; import com.fauna.common.configuration.FaunaConfig; import com.fauna.common.configuration.HttpClientConfig; import com.fauna.common.configuration.JvmDriver; @@ -43,13 +44,18 @@ class ConnectionTest { @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - when(httpClientConfig.getConnectTimeout()).thenReturn(Duration.ofSeconds(10)); - when(httpClientConfig.getMaxConnections()).thenReturn(5); - when(faunaConfig.getEndpoint()).thenReturn("http://localhost:8443"); // Return a valid URL string here + httpClientConfig = HttpClientConfig.builder() + .connectTimeout(Duration.ofSeconds(10)) + .maxConnections(5) + .build(); + faunaConfig = FaunaConfig.builder() + .endpoint(Endpoint.LOCAL.toString()) + .secret("secret") + .build(); RequestBuilder requestBuilder = RequestBuilder.builder().faunaConfig(faunaConfig).build(); spyRequestBuilder = spy(requestBuilder); - connection = new Connection(spyRequestBuilder, httpClientConfig, httpClient, JvmDriver.JAVA); + connection = new Connection(spyRequestBuilder, httpClientConfig, httpClient); } @Test diff --git a/faunaJava/src/main/java/com/fauna/client/FaunaClient.java b/faunaJava/src/main/java/com/fauna/client/FaunaClient.java index 3eebc403..96027b38 100644 --- a/faunaJava/src/main/java/com/fauna/client/FaunaClient.java +++ b/faunaJava/src/main/java/com/fauna/client/FaunaClient.java @@ -12,10 +12,20 @@ import java.net.http.HttpResponse; import java.util.concurrent.CompletableFuture; +/** + * FaunaClient is the main client for interacting with Fauna. + * It provides functionality to send queries and receive responses. + */ public class FaunaClient { private final Connection connection; + /** + * Constructs a new FaunaClient instance with the provided FaunaConfig and HttpClientConfig. + * + * @param faunaConfig The Fauna configuration settings. + * @param httpClientConfig The HTTP client configuration. + */ public FaunaClient(FaunaConfig faunaConfig, HttpClientConfig httpClientConfig) { this.connection = Connection.builder() .faunaConfig(faunaConfig) @@ -24,15 +34,35 @@ public FaunaClient(FaunaConfig faunaConfig, HttpClientConfig httpClientConfig) { .build(); } + /** + * Secondary constructor for FaunaClient, primarily used for testing. + * + * @param faunaConfig The Fauna configuration settings. + * @param httpClientConfig The HTTP client configuration. + * @param connection The Connection instance to be used. + */ FaunaClient(FaunaConfig faunaConfig, HttpClientConfig httpClientConfig, Connection connection) { super(); this.connection = connection; } + /** + * Constructs a new FaunaClient instance with the provided FaunaConfig. + * It uses the default HTTP client configuration. + * + * @param faunaConfig The Fauna configuration settings. + */ public FaunaClient(FaunaConfig faunaConfig) { this(faunaConfig, HttpClientConfig.builder().build()); } + /** + * Sends a Fauna Query Language (FQL) query to Fauna. + * + * @param fql The FQL query to be executed. + * @return A CompletableFuture that, when completed, will return the HttpResponse. + * @throws IllegalArgumentException If the provided FQL query is null. + */ public CompletableFuture> query(String fql) { if (fql == null) { @@ -42,7 +72,16 @@ public CompletableFuture> query(String fql) { return connection.performRequest(fql).thenApply(this::processResponse); } - + /** + * Processes the HTTP response from Fauna, checking for errors and ensuring protocol compliance. + * + * @param response The HTTP response from Fauna. + * @return The original HttpResponse if no errors were detected. + * @throws ProtocolException If the response is in an unknown format. + * @throws AuthenticationException If there was an authentication error. + * @throws InvalidQueryException If the query was invalid. + * @throws ServiceErrorException For other types of errors. + */ private HttpResponse processResponse(HttpResponse response) { int statusCode = response.statusCode(); checkProtocol(response.body(), statusCode); @@ -52,12 +91,28 @@ private HttpResponse processResponse(HttpResponse response) { return response; } + /** + * Checks if the response body is in the expected format based on the status code. + * + * @param body The response body. + * @param statusCode The HTTP status code. + * @throws ProtocolException If the response is in an unknown format. + */ private void checkProtocol(String body, int statusCode) { if ((statusCode <= 399 && !body.contains("data")) || (statusCode > 399 && !body.contains("error"))) { throw new ProtocolException("Response is in an unknown format: " + body); } } + /** + * Handles errors based on the HTTP status code and response body. + * + * @param body The response body. + * @param statusCode The HTTP status code. + * @throws AuthenticationException If there was an authentication error. + * @throws InvalidQueryException If the query was invalid. + * @throws ServiceErrorException For other types of errors. + */ private void handleErrorResponse(String body, int statusCode) { //TODO: code and message from body @@ -76,6 +131,13 @@ private void handleErrorResponse(String body, int statusCode) { } } + /** + * Handles exceptions during the HTTP request processing. + * + * @param ex The exception that was thrown. + * @return Does not return anything as it always throws an exception. + * @throws ServiceErrorException Wrapping the original exception, indicating a failure to process the request. + */ private HttpResponse handleException(Throwable ex) { throw new ServiceErrorException("Failed to process the request" + ex); }