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

refactor: decouple HTTP and WebSocket engines #1032

Merged
merged 3 commits into from
Oct 7, 2024
Merged

Conversation

ttypic
Copy link
Contributor

@ttypic ttypic commented Sep 24, 2024

  • Extracted HTTP calls and WebSocket listeners into a separate module.
  • Introduced an abstraction layer for easier implementation swapping.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new section in the contributing guide for adding new network engine implementations, detailing integration processes.
    • Introduced new interfaces for managing HTTP and WebSocket connections, enhancing network communication capabilities.
    • Implemented methods for cancelable HTTP requests and WebSocket management, improving user control over network operations.
  • Bug Fixes

    • Updated method signatures to improve handling of HTTP requests and responses.
  • Refactor

    • Refactored project structure to improve modularity and maintainability.
  • Chores

    • Updated project settings to include new modules for better organization.
    • Enhanced metadata in gradle.properties files for improved project management.
    • Updated .gitignore to include lombok.config for better version control.

Copy link

coderabbitai bot commented Sep 24, 2024

Walkthrough

The changes include updates to the CONTRIBUTING.md file, which now features a new section on adding network engine implementations. Additionally, several new interfaces have been introduced in the io.ably.lib.network package, including HttpCall, HttpEngine, WebSocketClient, WebSocketEngine, WebSocketEngineFactory, and WebSocketListener. These interfaces define the structures and methods for managing HTTP requests and WebSocket connections, enhancing the library's network functionality.

Changes

File/Path Change Summary
CONTRIBUTING.md Added a new section titled "Adding a New Network Engine Implementation," detailing the support for Default and OkHttp engines, including implementation processes and code snippets.
network-client-core/src/main/java/io/ably/lib/network/HttpCall.java Introduced HttpCall interface with methods execute() and cancel(), designed for cancelable HTTP requests.
network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java Introduced HttpEngine interface with methods call(HttpRequest request) and isUsingProxy(), defining an HTTP engine for cancelable requests.
network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java Added HttpEngineFactory interface with static methods for retrieving available HTTP engine factories and instance methods for creating engines based on configuration.
network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java Introduced WebSocketClient interface with methods for managing WebSocket connections, including connect(), close(), cancel(), and send().
network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java Introduced WebSocketEngine interface with a method create(String url, WebSocketListener listener) for creating WebSocket clients.
network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java Added WebSocketEngineFactory interface with static methods for retrieving WebSocket engine factories and instance methods for creating engines based on configuration.
network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java Introduced WebSocketListener interface with callback methods for handling WebSocket events, including connection open, message reception, and error handling.

Poem

🐇 In the meadow where code does play,
New classes hop and dance all day.
With WebSockets and HTTP calls,
Our project now stands tall,
Lombok's magic, less code to sway,
In this vibrant code ballet! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 24, 2024 12:24 Inactive
@ttypic ttypic requested a review from sacOO7 September 24, 2024 12:33
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 24

Outside diff range and nitpick comments (45)
network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1)

1-6: LGTM! Consider adding documentation.

The EngineType enum is well-structured and follows Java naming conventions. It aligns with the PR objectives of decoupling HTTP and WebSocket engines.

To improve maintainability and clarity, consider adding documentation:

/**
 * Represents the type of network engine used in the Ably client.
 */
public enum EngineType {
    /** The default network engine implementation. */
    DEFAULT,
    /** The OkHttp-based network engine implementation. */
    OKHTTP
}
network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java (1)

1-6: LGTM! Consider adding Javadoc for better documentation.

The introduction of the ProxyAuthType enum is a good addition to the codebase. It provides a clear and type-safe way to represent proxy authentication types, which aligns well with the refactoring objectives of the PR.

Consider adding Javadoc comments to the enum and its constants for better documentation. Here's a suggested improvement:

 package io.ably.lib.network;

+/**
+ * Represents the types of proxy authentication supported.
+ */
 public enum ProxyAuthType {
+    /** Basic authentication for proxies. */
     BASIC,
+    /** Digest authentication for proxies. */
     DIGEST
 }

This addition would provide more context for developers using this enum in the future.

network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (3)

4-4: LGTM: Well-designed method signature. Consider adding Javadoc.

The call method is well-structured with appropriate parameter and return types. It aligns with the PR objective of abstracting HTTP calls.

Consider adding Javadoc to provide more details about the method's behavior, parameters, and return value. For example:

/**
 * Initiates an HTTP call with the given request.
 *
 * @param request The HTTP request to be executed.
 * @return An HttpCall object representing the executed call.
 */
HttpCall call(HttpRequest request);

5-5: LGTM: Clear and concise method for proxy usage check. Consider adding Javadoc.

The isUsingProxy method is well-named and has an appropriate return type. It provides useful information about the network configuration.

Consider adding Javadoc to clarify the method's behavior. For example:

/**
 * Checks if the HTTP engine is configured to use a proxy.
 *
 * @return true if a proxy is being used, false otherwise.
 */
boolean isUsingProxy();

1-6: Overall, excellent interface design. Consider adding a package-level comment.

The HttpEngine interface is well-structured and aligns perfectly with the PR objectives of decoupling HTTP functionality and providing an abstraction layer. The methods are appropriately designed for their purposes.

To further enhance the code, consider adding a package-level comment at the top of the file to provide an overview of the interface's role in the broader system. For example:

/**
 * This package contains core networking interfaces for the Ably Java library.
 * The HttpEngine interface defines the contract for HTTP request handling,
 * allowing for flexible implementations and easier testing.
 */
package io.ably.lib.network;

// ... rest of the file
network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1)

1-5: LGTM! Well-designed interface for WebSocket client creation.

The WebSocketEngine interface is well-designed and aligns with the PR objectives. It provides a clean abstraction for creating WebSocket clients, which will facilitate easier swapping of implementations in the future.

Consider adding Javadoc comments to improve documentation:

 package io.ably.lib.network;

+/**
+ * An interface for creating WebSocket clients.
+ */
 public interface WebSocketEngine {
+    /**
+     * Creates a new WebSocket client.
+     *
+     * @param url The WebSocket server URL.
+     * @param listener A listener for WebSocket events.
+     * @return A new WebSocket client instance.
+     */
     WebSocketClient create(String url, WebSocketListener listener);
 }
network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java (1)

1-7: LGTM! Consider adding documentation and a custom message.

The NotConnectedException class is well-structured and follows Java conventions. It correctly extends RuntimeException and provides a constructor for exception chaining.

Consider the following improvements:

  1. Add JavaDoc to the class and constructor for better documentation.
  2. Include a custom message in the exception for more informative error reporting.

Here's a suggested implementation with these improvements:

package io.ably.lib.network;

/**
 * Exception thrown when a network operation is attempted but no connection is available.
 */
public class NotConnectedException extends RuntimeException {
    private static final String DEFAULT_MESSAGE = "Operation failed due to lack of network connection";

    /**
     * Constructs a new NotConnectedException with the specified cause and a default message.
     *
     * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
     */
    public NotConnectedException(Throwable cause) {
        super(DEFAULT_MESSAGE, cause);
    }
}

This version includes JavaDoc and a default message, making the exception more self-explanatory and easier to use.

network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java (1)

1-7: LGTM! Consider enhancing with JavaDoc and additional information.

The HttpConnectionException class is well-structured and follows good practices for custom exceptions. It properly extends RuntimeException and provides a constructor for exception chaining.

Consider the following enhancements:

  1. Add JavaDoc to the class and constructor for better documentation:
/**
 * Exception thrown when an HTTP connection error occurs.
 */
public class HttpConnectionException extends RuntimeException {
    /**
     * Constructs a new HttpConnectionException with the specified cause.
     *
     * @param cause the cause of this exception
     */
    public HttpConnectionException(Throwable cause) {
        super(cause);
    }
}
  1. Consider adding more specific information or methods to provide details about the HTTP connection error. For example:
public class HttpConnectionException extends RuntimeException {
    private final int statusCode;

    public HttpConnectionException(Throwable cause, int statusCode) {
        super(cause);
        this.statusCode = statusCode;
    }

    public int getStatusCode() {
        return statusCode;
    }
}

These additions would make the exception more informative and useful for error handling and debugging.

network-client-core/build.gradle.kts (1)

6-9: Consider upgrading Java version in the future.

The configuration for Java 1.8 compatibility is correct and ensures broad compatibility. However, Java 8 is quite old now. While this configuration is acceptable, it might be beneficial to consider upgrading to a newer Java version in the future for improved performance and access to newer language features.

network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java (1)

1-14: Consider additional components for a complete implementation.

While the basic structure of the OkHttpEngine class is in place, there are several components that might be needed for a complete and efficient implementation:

  1. Add a private OkHttpClient field, which can be reused for multiple requests.
  2. Implement a constructor that initializes the OkHttpClient with any necessary configurations.
  3. Add methods to handle different types of HTTP requests (GET, POST, PUT, DELETE, etc.).
  4. Implement error handling and exception translation to maintain consistency with the HttpEngine interface.
  5. Consider adding logging for debugging purposes.
  6. Implement any necessary cleanup methods (e.g., to close connections when the engine is no longer needed).

Here's a skeleton of what the complete class might look like:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public class OkHttpEngine implements HttpEngine {
    private final OkHttpClient client;

    public OkHttpEngine() {
        this.client = new OkHttpClient.Builder()
            // Add any necessary configurations
            .build();
    }

    @Override
    public HttpCall call(HttpRequest request) {
        Request okHttpRequest = buildOkHttpRequest(request);
        return new OkHttpCall(client.newCall(okHttpRequest));
    }

    @Override
    public boolean isUsingProxy() {
        return client.proxy() != null;
    }

    private Request buildOkHttpRequest(HttpRequest request) {
        // Convert HttpRequest to OkHttp's Request
        // ...
    }

    // Additional methods as needed
}

This structure provides a more complete foundation for the OkHttpEngine class.

build.gradle (1)

5-5: LGTM! Consider checking for the latest stable version.

The addition of the Lombok plugin (io.freefair.lombok) is a good choice for reducing boilerplate code and aligns well with the PR's refactoring objectives. The 'apply false' directive allows for selective application to subprojects, which is a flexible approach.

While version 5.0.1 is specified, it's worth verifying if this is the latest stable version of the Lombok plugin. You might want to check https://plugins.gradle.org/plugin/io.freefair.lombok for the most recent version to ensure you're getting the latest features and bug fixes.

network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (1)

12-13: LGTM: Appropriate field declarations with a suggestion for null safety

The fields contentType (String) and content (byte[]) are well-chosen to represent an HTTP body. The use of final ensures immutability, which is a good practice for thread safety and preventing unintended modifications.

Consider adding null checks in the constructor or using @NonNull annotations to ensure null safety, especially for the content field. This can prevent potential NullPointerExceptions when working with the HTTP body data.

Example implementation:

@NonNull
private final String contentType;
@NonNull
private final byte[] content;

public HttpBody(@NonNull String contentType, @NonNull byte[] content) {
    this.contentType = contentType;
    this.content = content.clone(); // Defensive copy for immutability
}
network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (1)

13-15: Consider future extensibility of HttpEngineConfig.

The class structure is clean and supports immutability, which is good. The single proxy field of type ProxyConfig is appropriate for the current requirements.

However, consider the potential need for additional HTTP engine configuration options in the future. While it's generally good to start with a minimal design, it might be worth discussing if there are any foreseeable additional configuration options that could be included now to avoid future breaking changes.

network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (1)

10-13: LGTM: Engine type getter is implemented correctly.

The getEngineType method is correctly implemented:

  1. It returns the appropriate engine type (EngineType.DEFAULT).
  2. The method name clearly describes its purpose.

Consider making EngineType.DEFAULT a private static final field of the class for better maintainability:

 public class DefaultHttpEngineFactory implements HttpEngineFactory {
+    private static final EngineType ENGINE_TYPE = EngineType.DEFAULT;
 
     // ... other methods ...
 
     @Override
     public EngineType getEngineType() {
-        return EngineType.DEFAULT;
+        return ENGINE_TYPE;
     }
 }

This change would centralize the engine type definition, making it easier to update if needed in the future.

network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (1)

1-14: Consider adding class-level documentation.

The implementation looks good and aligns well with the Factory pattern and PR objectives. To further enhance maintainability, consider adding class-level documentation (JavaDoc) to explain the purpose of this factory and its role in the WebSocket engine abstraction.

Here's a suggested JavaDoc comment to add above the class declaration:

/**
 * A factory for creating default WebSocket engine instances.
 * This class is part of the WebSocket engine abstraction layer,
 * allowing for easy swapping of WebSocket implementations.
 */
public class DefaultWebSocketEngineFactory implements WebSocketEngineFactory {
    // ... existing code ...
}
network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1)

6-12: LGTM with suggestions: Methods cover essential WebSocket events.

The interface methods effectively cover the main WebSocket events and some specific scenarios. However, consider the following suggestions for improvement:

  1. Consider adding an onPong() method to complement onWebsocketPing().
  2. The onOldJavaVersionDetected method seems very specific. Consider if this belongs in a more general error handling method or a separate interface for version-specific concerns.
  3. For consistency, consider renaming onWebsocketPing() to onPing() to match the style of other method names.
network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (1)

12-15: LGTM: Class annotations create an immutable DTO with builder pattern.

The combination of Lombok annotations (@DaTa, @Setter(AccessLevel.NONE), @builder, @AllArgsConstructor) effectively creates an immutable class with a builder pattern, which is excellent for DTOs. This approach reduces boilerplate code and ensures thread-safety.

Consider adding @EqualsAndHashCode(callSuper = false) to explicitly define equality based on the fields of this class only, in case this class is extended in the future.

network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (3)

11-15: LGTM: Well-chosen Lombok annotations for an immutable configuration class.

The annotations create an immutable, easy-to-use configuration class:

  • @Data provides getters, toString, equals, and hashCode methods.
  • @Setter(AccessLevel.NONE) prevents setter generation, ensuring immutability.
  • @Builder allows for a fluent API for object creation.
  • @AllArgsConstructor generates a constructor with all fields as parameters.

Consider adding @Getter explicitly for clarity, even though it's included in @Data:

 @Data
 @Setter(AccessLevel.NONE)
+@Getter
 @Builder
 @AllArgsConstructor
 public class WebSocketEngineConfig {

16-19: LGTM: Well-defined immutable fields for WebSocket configuration.

The fields cover essential aspects of WebSocket configuration and are correctly declared as private and final, ensuring immutability.

Consider adding Javadoc comments for each field to improve documentation:

 public class WebSocketEngineConfig {
+    /** The proxy configuration for the WebSocket connection. */
     private final ProxyConfig proxy;
+    /** Indicates whether TLS should be used for the connection. */
     private final boolean tls;
+    /** The host address for the WebSocket connection. */
     private final String host;
+    /** The SSL socket factory for secure connections. */
     private final SSLSocketFactory sslSocketFactory;
 }

1-20: Excellent implementation of WebSocketEngineConfig class.

This new class aligns well with the PR objective of decoupling HTTP and WebSocket engines. Key points:

  1. The use of Lombok annotations reduces boilerplate while maintaining clarity.
  2. The class is immutable, which is ideal for configuration objects.
  3. The builder pattern (via @Builder) will facilitate easy creation and modification of configurations.
  4. The fields cover essential aspects of WebSocket configuration.

This implementation provides a solid foundation for managing WebSocket configurations in a decoupled manner, enhancing the flexibility and maintainability of the codebase.

To further improve the abstraction:

  1. Consider creating an interface WebSocketConfig that this class implements. This would allow for easier swapping of different WebSocket configuration implementations in the future if needed.
  2. You might want to add a validate() method to ensure all required fields are set correctly before the configuration is used.
network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (2)

11-14: LGTM: Effective use of Lombok annotations for an immutable configuration object.

The combination of @Data, @Setter(AccessLevel.NONE), @Builder, and @AllArgsConstructor creates an immutable configuration object with a builder pattern. This is a good practice for configuration classes.

Consider adding @Getter explicitly for clarity, even though it's included in @Data. This makes the intent more obvious:

 @Data
 @Setter(AccessLevel.NONE)
+@Getter
 @Builder
 @AllArgsConstructor
 public class ProxyConfig {

15-22: LGTM: Well-structured proxy configuration class with comprehensive fields.

The ProxyConfig class is well-designed with fields covering all essential proxy configuration parameters. The use of List<String> for nonProxyHosts and a separate ProxyAuthType for authType demonstrates good design choices.

Consider adding validation for the port field to ensure it's within the valid range (0-65535). You can achieve this by using Lombok's @Builder.Default with a custom setter method:

 @Data
 @Setter(AccessLevel.NONE)
 @Builder
 @AllArgsConstructor
 public class ProxyConfig {
     private String host;
-    private int port;
+    @Builder.Default
+    private int port = -1;
     private String username;
     private String password;
     private List<String> nonProxyHosts;
     private ProxyAuthType authType;
+
+    private void setPort(int port) {
+        if (port < 0 || port > 65535) {
+            throw new IllegalArgumentException("Port must be between 0 and 65535");
+        }
+        this.port = port;
+    }
 }

This change ensures that the port is always valid when set, while still allowing it to be unspecified (indicated by -1) if not provided during construction.

network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (1)

12-19: LGTM: Well-implemented create method with a minor improvement suggestion.

The create method is well-implemented, correctly using the configuration to set up the DefaultWebSocketClient. The conditional TLS setup is a good security practice. Returning the interface type WebSocketClient rather than the concrete implementation is excellent for maintaining abstraction.

Consider adding null checks and validation for the input parameters url and listener to improve robustness. For example:

@Override
public WebSocketClient create(String url, WebSocketListener listener) {
    if (url == null || url.isEmpty()) {
        throw new IllegalArgumentException("URL cannot be null or empty");
    }
    if (listener == null) {
        throw new IllegalArgumentException("WebSocketListener cannot be null");
    }
    
    DefaultWebSocketClient client = new DefaultWebSocketClient(URI.create(url), listener, config);
    if (config.isTls()) {
        client.setSocketFactory(config.getSslSocketFactory());
    }
    return client;
}
network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (3)

10-12: LGTM: Constructor is simple and correct.

The constructor correctly initializes the config field with the provided HttpEngineConfig object.

Consider adding null-check validation for the config parameter to prevent potential NullPointerExceptions:

 public DefaultHttpEngine(HttpEngineConfig config) {
+    if (config == null) {
+        throw new IllegalArgumentException("HttpEngineConfig cannot be null");
+    }
     this.config = config;
 }

14-20: LGTM: call method implements proxy logic correctly.

The method effectively creates a Proxy object based on the configuration and returns a new DefaultHttpCall with the appropriate parameters.

Consider adding error handling for potential IllegalArgumentException when creating InetSocketAddress:

 @Override
 public HttpCall call(HttpRequest request) {
-    Proxy proxy = isUsingProxy()
-            ? new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxy().getHost(), config.getProxy().getPort()))
-            : Proxy.NO_PROXY;
-    return new DefaultHttpCall(request, proxy);
+    Proxy proxy = Proxy.NO_PROXY;
+    if (isUsingProxy()) {
+        try {
+            proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxy().getHost(), config.getProxy().getPort()));
+        } catch (IllegalArgumentException e) {
+            // Log the error and fall back to NO_PROXY
+            System.err.println("Invalid proxy configuration: " + e.getMessage());
+        }
+    }
+    return new DefaultHttpCall(request, proxy);
 }

This change improves error handling and provides a fallback mechanism in case of invalid proxy configuration.


22-25: LGTM: isUsingProxy method is simple and correct.

The method correctly determines if a proxy is being used based on the config.getProxy() value.

For added robustness, consider adding a null check for config:

 @Override
 public boolean isUsingProxy() {
-    return config.getProxy() != null;
+    return config != null && config.getProxy() != null;
 }

This change would prevent a NullPointerException if config is null, which could happen if the constructor is modified in the future to allow null values.

dependencies.gradle (1)

Issues Found: Remaining imports of org.java_websocket detected in the codebase. Please remove or refactor these usages to complete the dependency removal.

Analysis chain

Line range hint 1-17: Verify removal of Java-WebSocket dependency.

The AI summary mentions that the 'org.java-websocket:Java-WebSocket:1.5.3' dependency has been removed, but this removal is not visible in the provided code snippet. Please confirm that this dependency has indeed been removed from the project.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the removal of Java-WebSocket dependency and check for any remaining usages.

# Test 1: Check if the Java-WebSocket dependency is still present in any Gradle files
echo "Checking for Java-WebSocket dependency in Gradle files:"
rg --type gradle "org\.java-websocket:Java-WebSocket"

# Test 2: Check for any remaining imports or usages of Java-WebSocket classes
echo "Checking for Java-WebSocket imports or usages:"
rg --type java "import org\.java_websocket" || rg --type java "WebSocket"

Length of output: 869

network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (6)

5-5: Consider adding documentation for the connect() method.

While the method name is self-explanatory, it would be beneficial to add a Javadoc comment describing its purpose, any potential exceptions it might throw, and any important details about the connection process.

Here's a suggested Javadoc comment:

/**
 * Initiates a WebSocket connection.
 * 
 * @throws IOException if an I/O error occurs while creating the connection
 * @throws WebSocketException if the connection cannot be established
 */
void connect();

12-18: LGTM! Well-documented method with a minor suggestion.

The close(int code, String reason) method is well-documented with clear explanations for its parameters.

Consider adding @throws tags if this method can throw any exceptions, and possibly an @see tag referencing related methods or specifications (e.g., WebSocket protocol RFC). Here's a suggested addition:

 * @throws IllegalArgumentException if the code is not valid per WebSocket protocol
 * @see <a href="https://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455, Section 7.4: Status Codes</a>

20-27: LGTM! Well-documented method with a minor formatting suggestion.

The cancel(int code, String reason) method is well-documented, clearly explaining its purpose and how it differs from the close methods.

Consider formatting the comment as proper Javadoc by adding @param tags for each parameter and possibly @throws if any exceptions can be thrown. Here's a suggested revision:

/**
 * This will close the connection immediately without a proper close handshake. The code and the
 * message therefore won't be transferred over the wire also they will be forwarded to `onClose`.
 *
 * @param code the closing code
 * @param reason the closing message
 * @throws IllegalArgumentException if the code is not valid per WebSocket protocol
 */
void cancel(int code, String reason);

29-29: Consider adding documentation for the send(byte[] message) method.

While the method name is clear, it would be beneficial to add a Javadoc comment describing its purpose, any potential exceptions it might throw, and any important details about the message sending process.

Here's a suggested Javadoc comment:

/**
 * Sends a binary message over the WebSocket connection.
 *
 * @param message the byte array containing the message to be sent
 * @throws IOException if an I/O error occurs while sending the message
 * @throws IllegalStateException if the connection is not open
 */
void send(byte[] message);

31-31: Consider adding documentation for the send(String message) method.

While the method name is clear, it would be beneficial to add a Javadoc comment describing its purpose, any potential exceptions it might throw, and its relationship to the send(byte[] message) method.

Here's a suggested Javadoc comment:

/**
 * Sends a text message over the WebSocket connection.
 *
 * @param message the String message to be sent
 * @throws IOException if an I/O error occurs while sending the message
 * @throws IllegalStateException if the connection is not open
 * @see #send(byte[])
 */
void send(String message);

1-33: Consider expanding the interface to handle incoming messages and connection state.

The WebSocketClient interface provides a good foundation for WebSocket operations. However, to make it more complete and easier to use, consider adding the following methods:

  1. A method to handle incoming messages:

    void onMessage(MessageHandler handler);
  2. Methods to handle connection state changes:

    void onOpen(ConnectionHandler handler);
    void onClose(CloseHandler handler);
    void onError(ErrorHandler handler);
  3. A method to check the current connection state:

    ConnectionState getState();

These additions would make the interface more robust and allow for better control and monitoring of the WebSocket connection.

network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (2)

14-27: LGTM: Well-designed immutable HttpRequest class.

The use of Lombok annotations (@DaTa, @Setter(AccessLevel.NONE), @AllArgsConstructor) effectively reduces boilerplate code while promoting immutability. The fields cover all necessary components of an HTTP request, and the class is designed to be immutable, which is good for thread-safety.

Consider adding @Builder annotation to the class to automatically generate a builder pattern. This would eliminate the need for a custom HttpRequestBuilder class. Example:

@Data
@Setter(AccessLevel.NONE)
@AllArgsConstructor
@Builder
public class HttpRequest {
    // ... existing fields ...
}

This change would simplify the code and maintain the same functionality.


29-78: LGTM: Well-implemented Builder pattern.

The HttpRequestBuilder class effectively implements the Builder pattern, providing a fluent interface for constructing HttpRequest instances. The conversion of headers from Map<String, String> to Map<String, List<String>> in the headers method ensures compatibility with HTTP standards.

Consider adding validation checks in the build method to ensure all required fields are set before creating the HttpRequest instance. For example:

public HttpRequest build() {
    Objects.requireNonNull(url, "URL must not be null");
    Objects.requireNonNull(method, "HTTP method must not be null");
    if (httpOpenTimeout <= 0) {
        throw new IllegalStateException("HTTP open timeout must be positive");
    }
    if (httpReadTimeout <= 0) {
        throw new IllegalStateException("HTTP read timeout must be positive");
    }
    return new HttpRequest(this.url, this.method, this.httpOpenTimeout, this.httpReadTimeout, this.body, this.headers);
}

This would prevent the creation of invalid HttpRequest instances.

lib/src/main/java/io/ably/lib/http/HttpScheduler.java (1)

Line range hint 1-479: Summary: Good progress on refactoring, but consider further improvements

The changes in this file represent a positive step towards decoupling HTTP and WebSocket engines by introducing the HttpCall abstraction. However, to fully achieve the PR objectives, consider the following suggestions:

  1. Extend the use of HttpCall throughout the class for consistency.
  2. Review and update the HttpCore class to work seamlessly with HttpCall.
  3. Ensure that all HTTP-related operations in this file are using the new abstraction.

These improvements will help to fully realize the benefits of the decoupling effort and make the code more maintainable and flexible for future changes.

lib/src/test/java/io/ably/lib/test/common/Helpers.java (1)

Line range hint 990-1004: Consider adding error handling for null HttpRequest

While the changes improve the abstraction, it's important to ensure robust error handling. Consider adding a null check for the HttpRequest parameter at the beginning of the onRawHttpRequest method.

Here's a suggested improvement:

 public HttpCore.Response onRawHttpRequest(String id, HttpRequest request, String authHeader, Map<String, List<String>> requestHeaders,
                                           HttpCore.RequestBody requestBody) {
+    if (request == null) {
+        throw new IllegalArgumentException("HttpRequest cannot be null");
+    }
     
     /* duplicating if necessary, ensure lower-case versions of header names are present */
     Map<String, List<String>> normalisedHeaders = new HashMap<String, List<String>>();
     // ... rest of the method

This addition will help prevent potential null pointer exceptions and make the method more robust.

lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java (3)

1381-1382: Approved: Good refactoring to use HttpRequest

The change from HttpURLConnection to HttpRequest is a good refactoring step. It increases the abstraction level, which can improve flexibility and testability.

Consider updating the method name from onRawHttpRequest to onHttpRequest to better reflect the new parameter type and maintain consistency with the abstraction level.


1446-1447: Approved: Consistent refactoring

The change is consistent with the previous one, which is good for maintaining code uniformity.

To reduce code duplication, consider extracting the common RawHttpListener implementation into a separate method or class. This would make the test code more DRY (Don't Repeat Yourself) and easier to maintain. For example:

private RawHttpListener createMessageCapturingListener(final Message[] messages) {
    return new RawHttpListener() {
        @Override
        public HttpCore.Response onRawHttpRequest(String id, HttpRequest request, String authHeader,
                                                  Map<String, List<String>> requestHeaders, HttpCore.RequestBody requestBody) {
            try {
                if(testParams.useBinaryProtocol) {
                    messages[0] = MessageSerializer.readMsgpack(requestBody.getEncoded())[0];
                } else {
                    messages[0] = MessageSerializer.readMessagesFromJson(requestBody.getEncoded())[0];
                }
            } catch (AblyException e) {
                e.printStackTrace();
                fail("Unexpected exception");
            }
            return null;
        }

        @Override
        public void onRawHttpResponse(String id, String method, HttpCore.Response response) {}

        @Override
        public void onRawHttpException(String id, String method, Throwable t) {}
    };
}

Then you can use this method in both test cases:

options.httpListener = createMessageCapturingListener(messages);

This approach would make the tests more maintainable and reduce the risk of inconsistencies between similar test setups.


Line range hint 1-1844: Overall assessment: Good refactoring with room for improvement

The changes in this file are part of a broader refactoring effort to use HttpRequest instead of HttpURLConnection. This is a positive change that increases the abstraction level and potentially improves flexibility and testability.

Key points:

  1. The changes are consistent across the two modified sections.
  2. The refactoring doesn't appear to alter the functionality of the tests.
  3. There's an opportunity to reduce code duplication by extracting the common RawHttpListener implementation.

Consider reviewing the entire test suite for similar patterns that could benefit from this refactoring. This could lead to a more maintainable and consistent test codebase overall.

network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1)

9-15: Consider logging when no WebSocket engines are available.

When neither the OkWebSocket engine nor the default engine is available, an IllegalStateException is thrown without any logging. Adding a log statement before throwing the exception can aid in debugging and provide clearer context in logs.

You might add logging like this:

 if (defaultFactory != null) return defaultFactory;
+// Log a warning or error before throwing the exception
+System.err.println("No WebSocket engines are available.");
 throw new IllegalStateException("No engines are available");
network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java (1)

70-81: Document deprecation plans for Android versions below API 24

The override of onSetSSLParameters includes a workaround for Android versions below API 24. To maintain clarity, consider documenting when this workaround can be removed and use the @Deprecated annotation to indicate future deprecation.

For example:

/**
 * ...
 * @deprecated Since API level 24 supports this method. This workaround can be removed when minSdkVersion >= 24.
 */
@Deprecated
@Override
protected void onSetSSLParameters(SSLParameters sslParameters) {
    // Existing code
}
network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java (2)

125-130: Log exceptions when closing the InputStream

Silently ignoring exceptions can make debugging difficult. If an IOException occurs while closing the InputStream, it should be logged or appropriately handled to aid in diagnosing potential resource leaks or underlying issues.

Consider logging the exception:

} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
-           // Ignored
+           // Log the exception
+           e.printStackTrace(); // Replace with a proper logging mechanism
        }
    }
}

52-56: Reevaluate calling cancel() in the finally block

Calling cancel() in the finally block of the execute method disconnects the HttpURLConnection regardless of whether the operation completed successfully. This might interrupt the response processing prematurely. Consider removing the cancel() call here and managing the connection lifecycle more precisely.

lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (1)

248-249: Remove hardcoded 'remote' value in log message

In the onClose method, the remote parameter has been removed, but the log statement still includes remote = false hardcoded. This could lead to confusion when interpreting logs. Consider removing the remote value from the log message.

Apply this diff to update the log statement:

- Log.d(TAG, "onClose(): wsCode = " + wsCode + "; wsReason = " + wsReason + "; remote = " + false);
+ Log.d(TAG, "onClose(): wsCode = " + wsCode + "; wsReason = " + wsReason);
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 161fc45 and 3391599.

Files selected for processing (38)
  • build.gradle (1 hunks)
  • dependencies.gradle (1 hunks)
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java (2 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpCore.java (12 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java (2 hunks)
  • lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (10 hunks)
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java (4 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java (3 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java (5 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
  • network-client-default/build.gradle.kts (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (1 hunks)
  • network-client-okhttp/build.gradle.kts (1 hunks)
  • network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java (1 hunks)
  • settings.gradle (1 hunks)
Additional context used
ast-grep
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html

Additional comments not posted (69)
network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1)

1-6: Verify usage of EngineType in the codebase

To ensure this new enum is being used correctly throughout the codebase, let's verify its usage.

Verification successful

EngineType usage verified successfully across the codebase.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of EngineType in the codebase

# Search for import statements
echo "Checking import statements:"
rg --type java "import.*EngineType"

# Search for usage of EngineType
echo "\nChecking usage of EngineType:"
rg --type java "EngineType\.(DEFAULT|OKHTTP)"

# Search for method parameters or return types using EngineType
echo "\nChecking method signatures:"
rg --type java "EngineType\s+\w+|(\w+\(.*EngineType.*\))"

Length of output: 1403

network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1)

1-6: LGTM! Consider adding documentation and clarifying exception handling.

The HttpCall interface is well-structured and aligns with the PR objective of creating an abstraction layer for HTTP operations. It provides a clear contract for implementing classes, which will facilitate easier swapping of implementations.

However, there are a few suggestions to improve the code:

  1. Add an import statement for the HttpResponse class to ensure proper compilation:
import io.ably.lib.types.HttpResponse;
  1. Add JavaDoc comments to the interface and its methods to improve documentation:
/**
 * Represents an HTTP call operation.
 */
public interface HttpCall {
    /**
     * Executes the HTTP call.
     *
     * @return The response from the HTTP call.
     */
    HttpResponse execute();

    /**
     * Cancels the ongoing HTTP call.
     */
    void cancel();
}
  1. Consider specifying exception handling in the method signatures. For example:
HttpResponse execute() throws IOException, HttpException;

To verify the usage of HttpResponse in the codebase, please run the following script:

This script will help us understand if HttpResponse is properly defined and used across the project, which is crucial for the correct implementation of this interface.

network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (2)

1-1: LGTM: Package declaration is correct and follows conventions.

The package declaration io.ably.lib.network is consistent with the file path and follows Java naming conventions.


3-3: LGTM: Interface declaration is well-designed and aligns with PR objectives.

The HttpEngine interface is appropriately named and declared as public. This design choice supports the PR's goal of decoupling HTTP functionality, allowing for easier swapping of implementations in the future.

network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1)

3-5: Verify related types and update existing implementations.

This new interface introduces dependencies on WebSocketClient and WebSocketListener types. To ensure smooth integration:

  1. Confirm that WebSocketClient and WebSocketListener are defined elsewhere in the codebase.
  2. Update any existing WebSocket-related implementations to use this new WebSocketEngine interface.

Run the following script to check for related types and existing implementations:

Verification successful

All related types are present, and existing implementations utilize the new WebSocketEngine interface.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify related types and existing implementations

# Test 1: Check for WebSocketClient and WebSocketListener definitions
echo "Searching for WebSocketClient and WebSocketListener definitions:"
rg --type java -e 'class WebSocketClient' -e 'interface WebSocketClient' -e 'class WebSocketListener' -e 'interface WebSocketListener'

# Test 2: Look for existing WebSocket implementations that might need updating
echo "Searching for existing WebSocket implementations:"
rg --type java -e 'WebSocket' -e 'ws://' -e 'wss://'

Length of output: 11317

settings.gradle (1)

4-7: LGTM! The new modules align well with the PR objectives.

The addition of the new modules 'network-client-core', 'network-client-default', and 'network-client-okhttp' is in line with the PR's goal of decoupling HTTP and WebSocket engines. This modular structure should indeed enhance the organization and maintainability of the codebase. The 'network-client-core' module likely houses the abstraction layer, while 'network-client-default' and 'network-client-okhttp' probably represent different implementations that can be easily swapped, as mentioned in the PR objectives.

It's also worth noting that existing modules remain unchanged, which suggests that backward compatibility has been maintained.

network-client-core/build.gradle.kts (3)

1-4: LGTM: Appropriate plugins for a Java library project.

The use of java-library and io.freefair.lombok plugins is well-suited for this module. The java-library plugin provides necessary configurations for a Java library project, while the Lombok plugin will help reduce boilerplate code, improving maintainability.


11-13: LGTM: Appropriate repository configuration.

Using mavenCentral() as the repository for dependency resolution is a good choice. It's a widely used and reliable source for Java dependencies, which helps ensure consistency and security in your project's dependency management.


1-13: Overall, excellent build configuration for the new module.

This build.gradle.kts file effectively sets up the build configuration for the new network-client-core module. It applies appropriate plugins, sets up Java compatibility, and configures the dependency repository. This configuration supports the PR's objective of decoupling HTTP and WebSocket engines by creating a separate, well-structured module. The use of Lombok will help in reducing boilerplate code, further improving maintainability.

network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java (1)

1-3: LGTM: Class declaration aligns with PR objectives.

The OkHttpEngine class implementing the HttpEngine interface is a good approach. It aligns with the PR objective of creating an abstraction layer for HTTP functionality, which will allow for easier swapping of implementations in the future.

network-client-okhttp/build.gradle.kts (4)

1-4: LGTM: Appropriate plugins applied.

The java-library plugin is suitable for a Java library project, and the io.freefair.lombok plugin will help reduce boilerplate code. Both are relevant choices for this module.


11-13: LGTM: Appropriate repository configuration.

Using mavenCentral() as the sole repository is a good practice. It's a standard, reliable source for dependencies and helps maintain consistency in dependency management.


6-9: Verify Java version compatibility.

The module is configured to use Java 1.8 for both source and target compatibility. While this ensures broad compatibility, it may limit access to newer Java features. Please confirm that this aligns with the project's overall requirements and other modules.

Verification successful

Java version compatibility is consistent across the project.

All modules are configured to use Java 1.8 for both source and target compatibility, aligning with the project's overall requirements.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Java version configuration across the project

# Test: Search for Java version configurations in other Gradle files
echo "Searching for Java version configurations in other Gradle files:"
rg --type gradle "sourceCompatibility|targetCompatibility" -g '!network-client-okhttp/build.gradle.kts'

# Test: Check if there's a global Java version setting
echo "Checking for global Java version setting:"
rg --type gradle "sourceCompatibility|targetCompatibility" rootProject.buildscript

Length of output: 680


15-17: Verify completeness of dependencies.

The API dependency on :network-client-core is appropriate and suggests a good modular architecture. However, it's unusual for a network client module to have no external dependencies.

Please confirm if any external dependencies (e.g., OkHttp) are missing from this configuration. You may want to run the following script to check for usage of external libraries:

network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (3)

1-7: LGTM: Appropriate package and imports

The package declaration io.ably.lib.network is suitable for this network-related class. The use of Lombok annotations (AccessLevel, AllArgsConstructor, Data, Setter) is a good practice to reduce boilerplate code, enhancing code readability and maintainability.


8-11: LGTM: Well-designed immutable class for HTTP body representation

The HttpBody class is well-designed with appropriate Lombok annotations:

  • @Data generates essential methods (toString, equals, hashCode, and getters).
  • @Setter(AccessLevel.NONE) ensures immutability by preventing setter generation.
  • @AllArgsConstructor provides a convenient way to initialize all fields.

This design creates a clean, immutable abstraction for HTTP bodies, which aligns well with the PR objective of introducing an abstraction layer and improving code organization.


1-14: Great addition: HttpBody class enhances abstraction and maintainability

The introduction of the HttpBody class is a valuable addition to the project:

  1. It provides a clear abstraction for HTTP body data, supporting the PR's objective of decoupling HTTP and WebSocket engines.
  2. The immutable design ensures thread safety and prevents unintended modifications.
  3. The use of Lombok annotations significantly reduces boilerplate code, improving readability and maintainability.

This class will serve as a solid foundation for handling HTTP body data in the refactored network client, making it easier to manage and extend functionality in the future.

network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (3)

1-1: LGTM: Package declaration is correct.

The package declaration io.ably.lib.network is appropriate and aligns with the file path.


3-7: LGTM: Appropriate use of Lombok imports.

The import statements are correct and include only the necessary Lombok annotations. Using Lombok is a good choice as it can significantly reduce boilerplate code, improving code readability and maintainability.


9-12: LGTM: Well-chosen Lombok annotations for immutable configuration.

The combination of Lombok annotations (@DaTa, @Setter(AccessLevel.NONE), @builder, @AllArgsConstructor) is well-thought-out:

  • It creates an immutable configuration object (no setters).
  • It provides a builder pattern for flexible object creation.
  • It generates common methods (toString, equals, hashCode) automatically.

This design is suitable for a configuration class, ensuring thread-safety and preventing accidental modifications after creation.

network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (3)

1-3: LGTM: Class declaration follows best practices.

The DefaultHttpEngineFactory class correctly implements the HttpEngineFactory interface, adhering to the factory pattern. This aligns well with the PR objective of introducing an abstraction layer for HTTP engines.


5-8: LGTM: Factory method implementation is correct.

The create method follows the factory pattern correctly:

  1. It takes a HttpEngineConfig parameter, allowing for customized configurations.
  2. It returns a new instance of DefaultHttpEngine, adhering to the factory method's responsibility.
  3. The method is concise and follows the Single Responsibility Principle.

1-14: Verify imports and consider adding documentation.

The DefaultHttpEngineFactory class is well-structured and aligns with the PR objectives. However, there are a couple of points to consider:

  1. There are no import statements in this file. Please verify that all referenced types (HttpEngineFactory, HttpEngine, HttpEngineConfig, EngineType) are either in the same package or in java.lang. If not, add the necessary imports.

  2. Consider adding Javadoc comments to the class and methods. This would improve code documentation and make it easier for other developers to understand and use this factory.

To check for potential missing imports, run the following command:

The factory pattern implemented here provides a good abstraction for creating HTTP engines. To further improve the design:

  1. Consider using dependency injection for the HttpEngineConfig if it's used across multiple components.
  2. If there are plans for multiple engine types, you might want to create an abstract factory or use the Strategy pattern to allow for runtime selection of different engine types.
network-client-default/build.gradle.kts (4)

1-4: LGTM: Appropriate plugins applied.

The java-library plugin is correctly applied for a library project, and the Lombok plugin is a good choice for reducing boilerplate code.


11-13: LGTM: Appropriate repository configuration.

Using Maven Central as the sole repository is a good practice, ensuring reliability and security in dependency management.


15-18: LGTM: Dependencies are appropriate for the module's purpose.

The API dependency on network-client-core and the implementation dependency on Java-WebSocket align well with the module's purpose and the PR's objective of decoupling HTTP and WebSocket engines.


6-9: Verify Java version compatibility.

The Java compatibility is set to version 1.8. While this ensures broad compatibility, it may limit access to newer Java features. Please confirm that this version aligns with the project's overall requirements and other modules.

Verification successful

Java version compatibility verified.

All Gradle files consistently set sourceCompatibility and targetCompatibility to version 1.8. Additionally, no Java 9+ features are detected in the codebase. This configuration aligns with the project's requirements.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Java version compatibility across the project

# Test: Search for Java version specifications in other Gradle files
echo "Checking Java version specifications in other Gradle files:"
rg --type gradle "sourceCompatibility|targetCompatibility" --glob '!network-client-default/build.gradle.kts'

# Test: Check if any Java 9+ features are used in the codebase
echo "Checking for Java 9+ features usage:"
rg --type java "var\s+\w+\s*=" # Example: searching for local variable type inference (var keyword)

Length of output: 549


Script:

#!/bin/bash
# Description: Verify consistent Java version settings across the entire codebase

# Search for any Gradle files with Java version set higher than 1.8
echo "Searching for Gradle files with Java version higher than 1.8:"
rg --type gradle '(sourceCompatibility\s*=\s*"1\.[89]")|(targetCompatibility\s*=\s*"1\.[89]")' --ignore-case

# Search for any usage of Java 9+ features beyond variable type inference
echo "Checking for usage of Java 10+ features (e.g., local-variable syntax for lambda parameters):"
rg --type java "(var\s+\w+\s*=)|(->\s+\w+\s*)"

Length of output: 5582

network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (3)

1-3: LGTM: Class declaration is well-structured.

The DefaultWebSocketEngineFactory class correctly implements the WebSocketEngineFactory interface, adhering to Java naming conventions. This implementation aligns with the PR objective of introducing an abstraction layer for WebSocket engines.


5-8: LGTM: Factory method implementation is correct.

The create method properly implements the factory pattern by instantiating a DefaultWebSocketEngine with the provided configuration. This approach allows for easy swapping of WebSocket engine implementations in the future.


10-13: LGTM: Engine type getter is appropriately implemented.

The getEngineType method correctly returns the engine type as EngineType.DEFAULT. This implementation allows for easy identification of the engine type and supports potential future extensions with different engine types.

network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (4)

1-1: LGTM: Package declaration is correct and follows conventions.

The package declaration io.ably.lib.network is appropriate and aligns with the file path.


3-3: LGTM: Import statement is appropriate.

The import of java.nio.ByteBuffer is necessary and follows the principle of importing only what's needed.


5-5: LGTM: Interface declaration is well-defined.

The WebSocketListener interface is appropriately named and follows Java conventions. The public access modifier is suitable for its intended use.


1-13: Overall assessment: Well-structured WebSocket listener interface.

This new WebSocketListener interface provides a comprehensive set of methods for handling WebSocket events. It follows Java naming conventions and is appropriately placed in the io.ably.lib.network package. The interface design allows for easy implementation and extension, which aligns well with the PR objective of decoupling HTTP and WebSocket engines.

Consider the suggestions in the previous comment to further refine the interface. These changes would enhance consistency and potentially improve the overall design of the WebSocket handling system.

network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (2)

1-10: LGTM: Package declaration and imports are well-organized.

The package declaration follows Java naming conventions, and the imports are appropriate for the class. The use of Lombok annotations is a good practice to reduce boilerplate code.


16-16: LGTM: Class declaration is clear and follows conventions.

The HttpResponse class is appropriately named and declared as public, following Java naming conventions and allowing it to be used across the project.

network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (1)

1-10: LGTM: Appropriate imports for the class functionality.

The imports are well-chosen:

  • Lombok annotations will help reduce boilerplate code, improving maintainability.
  • The SSLSocketFactory import indicates proper SSL/TLS support for WebSocket connections.
network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (2)

3-9: LGTM: Import statements are appropriate and concise.

The import statements are well-organized, importing only the necessary Lombok annotations and the List interface from java.util. This demonstrates good practice in keeping the imports clean and relevant to the class implementation.


1-22: Excellent implementation of ProxyConfig class.

This new ProxyConfig class is a well-designed, immutable configuration object that effectively encapsulates proxy settings. The use of Lombok annotations significantly reduces boilerplate code, enhancing readability and maintainability. This implementation aligns well with the PR objectives of refactoring and improving code organization.

The class structure supports the goal of decoupling HTTP and WebSocket engines by providing a clear and comprehensive configuration structure. This will facilitate easier management and potential swapping of implementations in the future.

Overall, this is a high-quality addition to the codebase that contributes positively to the project's architecture.

network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (3)

1-6: LGTM: Class structure and package declaration are well-defined.

The DefaultWebSocketEngine class is appropriately placed in the io.ably.lib.network package. It correctly implements the WebSocketEngine interface and uses a configuration object, which aligns with good design practices for flexibility and maintainability.


8-10: LGTM: Constructor follows dependency injection principle.

The constructor is well-designed, taking a WebSocketEngineConfig parameter and assigning it to the config field. This approach allows for external configuration, enhancing flexibility and testability of the class.


1-20: Great implementation aligning with PR objectives.

The DefaultWebSocketEngine class successfully implements the WebSocketEngine interface, contributing to the decoupling of HTTP and WebSocket engines as outlined in the PR objectives. The use of a configuration object and the abstraction provided by the interface facilitate easier swapping of implementations, which aligns perfectly with the goal of improving flexibility in handling HTTP and WebSocket functionalities.

The class structure, with its configurable constructor and create method, provides a clean and maintainable way to manage WebSocket client creation. This implementation enhances the organization of the codebase and supports the overall objective of improving code maintainability.

network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (3)

3-5: LGTM: Import statements are appropriate.

The import statements for InetSocketAddress and Proxy are relevant to the class functionality and are used in the code.


6-9: LGTM: Class declaration and field are well-defined.

The DefaultHttpEngine class correctly implements the HttpEngine interface. The config field is appropriately declared as private and final, ensuring immutability and encapsulation.


1-26: Overall, the DefaultHttpEngine implementation is well-structured and functional.

The class successfully implements the HttpEngine interface, providing a default HTTP engine with proxy support. The code is clean, concise, and follows good practices. The suggested improvements for error handling and null checks would further enhance the robustness of the implementation.

dependencies.gradle (1)

7-8: LGTM: New project dependencies align with refactoring goals.

The addition of ':network-client-core' and ':network-client-default' as project dependencies aligns well with the PR objective of decoupling HTTP and WebSocket engines. This modularization should improve code organization and maintainability.

network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1)

7-10: LGTM! Clear method with appropriate documentation.

The close() method is well-documented, explaining its purpose and when it can be used. The implementation looks good.

lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java (2)

1-8: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are correct and necessary for the functionality of the class.


9-10: LGTM: Class declaration is appropriate.

The class ClientOptionsUtils is correctly declared as public and follows Java naming conventions.

network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (2)

1-13: LGTM: Package declaration and imports are appropriate.

The package name io.ably.lib.network is suitable for a network-related class. The use of Lombok annotations to reduce boilerplate code is a good practice. All imports are relevant to the class implementation.


1-84: Overall, well-designed HttpRequest class with minor suggestions for improvement.

The HttpRequest class and its builder are well-implemented, promoting immutability and providing a flexible way to construct HTTP requests. This aligns well with the PR objective of decoupling HTTP and WebSocket engines. The use of Lombok effectively reduces boilerplate code.

Consider the following suggestions for further improvement:

  1. Use the @Builder annotation to simplify the builder implementation.
  2. Add validation checks in the build method to ensure all required fields are set.
  3. Override the toString method to mask sensitive information in headers.

These changes would enhance the robustness and security of the implementation while maintaining its current functionality.

lib/src/main/java/io/ably/lib/debug/DebugOptions.java (2)

7-7: LGTM: New import statement is appropriate.

The addition of import io.ably.lib.network.HttpRequest; is consistent with the changes made in the RawHttpListener interface. This import is necessary for the updated method signature.


22-22: Approve change, but verify impact on existing implementations.

The updated method signature in the RawHttpListener interface is a good step towards decoupling HTTP and WebSocket engines. The change from HttpURLConnection to HttpRequest provides a more abstract representation of HTTP requests, which aligns with the PR objectives.

However, this change might impact existing implementations of the RawHttpListener interface.

Please run the following script to check for existing implementations of RawHttpListener that might need updating:

Also, could you please confirm that the HttpRequest class includes a method to retrieve the HTTP method, which was previously passed as a separate parameter?

Verification successful

Change verified, no impact on existing implementations.

All implementations of RawHttpListener are contained within test classes, ensuring that the update to the method signature does not affect production code.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find implementations of RawHttpListener that might need updating

# Search for classes implementing RawHttpListener
echo "Classes implementing RawHttpListener:"
ast-grep --lang java --pattern 'class $_ implements $$$RawHttpListener$$$'

# Search for onRawHttpRequest method implementations
echo "\nExisting onRawHttpRequest method implementations:"
ast-grep --lang java --pattern 'onRawHttpRequest($$$)'

Length of output: 676


Script:

#!/bin/bash
# Description: Refined search for implementations of RawHttpListener and their onRawHttpRequest methods

echo "Refined search for classes implementing RawHttpListener:"
ast-grep --lang java --pattern 'class $_ implements RawHttpListener { $$$ }'

echo "\nRefined search for onRawHttpRequest method implementations:"
ast-grep --lang java --pattern 'onRawHttpRequest($_, $_, $_, $_, $_);'

echo "\nFallback: Using ripgrep to find potential implementations of RawHttpListener:"
rg --type java "implements\s+RawHttpListener"

echo "\nFallback: Using ripgrep to find onRawHttpRequest method definitions:"
rg --type java "onRawHttpRequest\s*\("

Length of output: 2969

lib/src/main/java/io/ably/lib/http/HttpScheduler.java (4)

11-11: LGTM: Import statement for HttpCall added.

The addition of the HttpCall import is consistent with the changes made in this file and aligns with the PR objective of decoupling HTTP and WebSocket engines.


342-342: LGTM: Field declaration updated to use HttpCall

The change from HttpURLConnection conn to HttpCall httpCall is consistent with the overall refactoring and maintains the same protection level.


Line range hint 1-479: Consider extending the use of HttpCall throughout the class

While the change to use HttpCall instead of HttpURLConnection is a step in the right direction, it appears that the refactoring might not be complete. The HttpCall is only used in the disposeConnection method, while other methods still rely on HttpCore for execution.

Consider updating other methods in this class to use HttpCall directly for consistency and to fully leverage the new abstraction. This might involve changes to methods like httpExecuteWithRetry and potentially updating the HttpCore class to work with HttpCall.

To assess the extent of the refactoring needed, run the following script to check for other occurrences of HTTP-related operations in this file:

#!/bin/bash
# Description: Check for other HTTP-related operations in HttpScheduler.java

# Search for methods that might need updating
rg --type java -n 'httpExecuteWithRetry|httpExecute' lib/src/main/java/io/ably/lib/http/HttpScheduler.java

# Check HttpCore usage
rg --type java -n 'HttpCore' lib/src/main/java/io/ably/lib/http/HttpScheduler.java

334-337: Verify the behavior of httpCall.cancel()

The changes in the disposeConnection method are consistent with the shift from HttpURLConnection to HttpCall. However, it's important to ensure that httpCall.cancel() provides the same or better functionality as conn.disconnect().

Please confirm that httpCall.cancel() properly releases resources and terminates the connection. Run the following script to check the implementation of HttpCall.cancel():

lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java (6)

5-5: LGTM: New import added for HttpRequest

The addition of the HttpRequest import is consistent with the refactoring mentioned in the PR objectives. This change supports the updated method signature of onRawHttpRequest.


138-138: LGTM: Updated method signature for onRawHttpRequest

The change from HttpURLConnection conn to HttpRequest request and the removal of the method parameter align with the PR objectives. This modification supports the decoupling of HTTP and WebSocket engines and provides a more abstract interface.


141-141: LGTM: Updated method check in onRawHttpRequest

The change from method.equalsIgnoreCase("POST") to request.getMethod().equalsIgnoreCase("POST") is consistent with the updated method signature. This modification maintains the same functionality while utilizing the new HttpRequest object.


199-199: LGTM: Consistent update of onRawHttpRequest method signature

The change in this method signature is consistent with the previous modification, replacing HttpURLConnection conn with HttpRequest request and removing the method parameter. This ensures uniform updates across all instances of onRawHttpRequest.


202-202: LGTM: Consistent update of method check in onRawHttpRequest

The change from method.equalsIgnoreCase("POST") to request.getMethod().equalsIgnoreCase("POST") is consistent with the updated method signature and the previous instance. This modification maintains the same functionality while utilizing the new HttpRequest object.


Line range hint 1-446: Overall assessment: Consistent and well-executed refactoring

The changes in this file consistently replace HttpURLConnection with HttpRequest across multiple instances of the onRawHttpRequest method. This refactoring aligns well with the PR objectives of decoupling HTTP and WebSocket engines. The modifications improve the abstraction of HTTP requests, which should enhance the flexibility and maintainability of the code. The consistency of these changes across multiple instances demonstrates a thorough refactoring effort.

lib/src/test/java/io/ably/lib/test/common/Helpers.java (3)

Line range hint 990-1004: Improved abstraction in RawHttpRequest class

The changes in the RawHttpRequest class represent a positive refactoring:

  1. Removal of the conn field of type HttpURLConnection.
  2. Addition of url and method fields.

These changes decouple the class from the specific HttpURLConnection implementation, making it more abstract and potentially easier to test. This abstraction allows for greater flexibility in handling different types of HTTP requests and improves the overall design of the class.


Line range hint 990-1004: Consistent refactoring in RawHttpTracker class

The changes in the RawHttpTracker class are consistent with the modifications made to RawHttpRequest:

  1. The onRawHttpRequest method now accepts an HttpRequest parameter instead of HttpURLConnection.
  2. The method body has been updated to use the new HttpRequest parameter.

These changes align well with the move towards a more abstract representation of HTTP requests, improving the overall design and flexibility of the code.


Line range hint 1077-1081: Consistent update in getRequestParam method

The getRequestParam method has been correctly updated to use req.url.getQuery() instead of req.conn.getURL().getQuery(). This change is consistent with the earlier modifications to the RawHttpRequest class, where the conn field was removed and replaced with a url field.

This update maintains the method's functionality while adhering to the new, more abstract representation of HTTP requests. It's a good example of ensuring consistency across the codebase during refactoring.

lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (3)

81-83: Introduction of WebSocketEngineFactory enhances flexibility

The use of WebSocketEngineFactory to obtain the first available engine promotes modularity and allows for easier swapping of WebSocket implementations. Logging the engine type improves debuggability.


288-290: Broadened exception handling in onError method

Changing the onError method parameter from Exception to Throwable expands the scope to include both exceptions and errors. Ensure that this change aligns with your error-handling strategy and that all types of Throwable are appropriately managed.


369-369: Verify the cancel method signature in webSocketClient

Ensure that the webSocketClient.cancel(ABNORMAL_CLOSE, "timed out"); statement correctly invokes the cancel method with the expected parameters. Verify that the cancel method accepts an integer code and a string reason.

Run the following script to verify the cancel method's signature:

Verification successful

Verified the cancel method signature in webSocketClient

The cancel method is correctly invoked with an integer code and a string reason, matching its definition in WebSocketClient.java.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the 'cancel' method in WebSocketClient accepts the correct parameters.

# Test: Search for 'void cancel(int code, String reason)' method definition.
ast-grep --lang java --pattern $'void cancel(int $_, String $_)'

Length of output: 185

@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from 3391599 to c7e5ecd Compare September 24, 2024 14:14
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 24, 2024 14:15 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (2)
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (1)

248-249: Consider retaining or documenting the removal of the remote parameter

The onClose method no longer includes the remote parameter, which previously indicated whether the close was initiated remotely or locally. This information might be valuable for debugging or logging purposes.

Consider either:

  1. Retaining the remote parameter if it's still available from the WebSocket implementation.
  2. Documenting the reason for its removal if it's no longer relevant or available.
lib/src/test/java/io/ably/lib/test/rest/HttpTest.java (1)

Line range hint 1-1: Summary of changes and potential impact

The main changes in this file revolve around the removal of the Proxy parameter from the httpExecute method. This simplification of the method signature is consistently applied throughout the file. The addition of the HttpRequest import suggests that some of the functionality may have been moved to this class.

These changes appear to be part of a larger refactoring effort to decouple HTTP and WebSocket engines, as mentioned in the PR objectives. While the changes look good overall, it's important to ensure that proxy functionality hasn't been lost in the process.

Consider the following points:

  1. Verify that proxy handling has been moved to an appropriate place in the HTTP request chain.
  2. Ensure that all tests related to proxy functionality are still valid and have been updated or moved as necessary.
  3. Update the documentation to reflect these changes in the HTTP handling process.
  4. If the HttpRequest class now handles some of the functionality previously in httpExecute, consider adding or updating tests for this class.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 3391599 and c7e5ecd.

Files selected for processing (39)
  • build.gradle (1 hunks)
  • dependencies.gradle (1 hunks)
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java (2 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpCore.java (12 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java (2 hunks)
  • lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (10 hunks)
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java (4 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/HttpTest.java (2 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java (3 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java (5 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
  • network-client-default/build.gradle.kts (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (1 hunks)
  • network-client-okhttp/build.gradle.kts (1 hunks)
  • network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java (1 hunks)
  • settings.gradle (1 hunks)
Files skipped from review as they are similar to previous changes (37)
  • build.gradle
  • dependencies.gradle
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java
  • lib/src/main/java/io/ably/lib/http/HttpCore.java
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java
  • network-client-core/build.gradle.kts
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java
  • network-client-default/build.gradle.kts
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java
  • network-client-okhttp/build.gradle.kts
  • network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java
  • settings.gradle
Additional context used
ast-grep
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html

Additional comments not posted (9)
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (7)

4-8: LGTM: New imports align with refactoring objectives

The addition of new WebSocket-related imports and ClientOptionsUtils aligns well with the PR's objective of decoupling HTTP and WebSocket engines. This change sets the foundation for a more modular and flexible WebSocket implementation.

Also applies to: 15-15


81-89: LGTM: Improved WebSocket connection setup

The introduction of WebSocketEngineFactory and WebSocketEngineConfig enhances the flexibility and configurability of the WebSocket connection setup. This aligns well with the PR's objective of decoupling HTTP and WebSocket engines and allows for easier implementation swapping in the future.

Also applies to: 97-98


138-138: LGTM: Simplified send logic with improved error handling

The send method has been refactored to use the webSocketClient.send() method, simplifying the implementation. The addition of NotConnectedException handling enhances the robustness of the error management in the transport layer.

Also applies to: 143-143, 145-145


191-191: LGTM: Improved WebSocket event handling

The new WebSocketHandler class implements WebSocketListener, providing a more standardized and organized approach to handling WebSocket events. The updated methods (onOpen, onClose, onError) and the addition of onOldJavaVersionDetected enhance the robustness of the WebSocket connection management.

Also applies to: 201-203, 206-209, 248-290, 294-296


288-290: LGTM: Enhanced error handling in onError

The onError method now accepts a Throwable instead of an Exception, making it more versatile in handling various types of errors. The simplified error message creation improves readability while still providing necessary information for debugging.


369-369: LGTM: Updated activity timer expiry handling

The onActivityTimerExpiry method has been updated to use webSocketClient.cancel(), which aligns with the overall refactoring of the WebSocket handling. This change maintains the existing functionality while integrating with the new WebSocket implementation.


91-93: ⚠️ Potential issue

Consider specifying TLS version for enhanced security

The SSL context initialization still uses SSLContext.getInstance("TLS"), which may default to older, less secure protocols. As mentioned in a previous review comment and flagged by static analysis, it's recommended to specify TLSv1.2 or higher for better security.

Consider applying this change:

- SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
lib/src/test/java/io/ably/lib/test/rest/HttpTest.java (2)

11-11: Import addition looks good.

The addition of the io.ably.lib.network.HttpRequest import is consistent with the refactoring of the HTTP functionality. This change suggests that the HttpRequest class is now being utilized in the test file.


141-146: Method signature update looks good, but verify proxy handling.

The removal of the Proxy proxy parameter from the httpExecute method signature simplifies the method and is consistently applied. This change suggests that proxy handling has been moved elsewhere in the HTTP request chain.

To ensure that proxy functionality hasn't been lost, please run the following script to check for proxy handling in other parts of the codebase:

Verification successful

Proxy handling is maintained elsewhere in the codebase; the removal of the Proxy parameter in the httpExecute method is verified.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for proxy handling in the codebase

# Search for proxy-related code in the entire project
echo "Searching for proxy-related code:"
rg --type java -i 'proxy' -g '!test'

# Search for new proxy handling methods or classes
echo "Searching for potential new proxy handling methods or classes:"
rg --type java -i 'setproxy|configureproxy|proxyconfig'

Length of output: 11042

@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from c7e5ecd to d2b310b Compare September 24, 2024 14:52
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 24, 2024 14:53 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range and nitpick comments (3)
android/build.gradle (2)

88-90: LGTM! Consider updating to the latest stable versions.

The addition of msgpack-core, gson, and vcdiff-core libraries aligns well with the PR's objective of refactoring and improving the codebase structure. These libraries provide robust solutions for serialization, JSON processing, and binary diff/patch operations.

Consider updating to the latest stable versions:

  • org.msgpack:msgpack-core:0.9.5
  • com.google.code.gson:gson:2.10.1
  • com.davidehrmann.vcdiff:vcdiff-core:0.1.2

94-101: LGTM! Consider updating test dependencies to more recent versions.

The addition of these test dependencies enhances the project's testing capabilities, which is crucial for maintaining code quality during refactoring. The inclusion of NanoHTTPD suggests improved testing of HTTP interactions, aligning with the PR's objectives.

Consider updating to more recent versions of these libraries:

  • org.hamcrest:hamcrest:2.2 (replaces hamcrest-all)
  • junit:junit:4.13.2 (or consider migrating to JUnit 5)
  • org.nanohttpd:nanohttpd:2.3.1 (and related modules)
  • org.mockito:mockito-core:5.4.0
  • net.jodah:concurrentunit:0.4.6
  • org.slf4j:slf4j-simple:2.0.7

Updating these dependencies can provide bug fixes, performance improvements, and new features that could benefit your testing process.

lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (1)

Line range hint 248-286: Consider simplifying the onClose method

The onClose method uses a switch statement with several fall-through cases. Consider simplifying this logic by grouping similar cases or using a more concise approach, such as a map of error codes to reasons. This could improve readability and maintainability.

Here's a potential simplification using a map:

private static final Map<Integer, ErrorInfo> closeReasonMap = Map.of(
    CLOSE_NORMAL, ConnectionManager.REASON_DISCONNECTED,
    GOING_AWAY, ConnectionManager.REASON_DISCONNECTED,
    REFUSE, ConnectionManager.REASON_REFUSED,
    POLICY_VALIDATION, ConnectionManager.REASON_REFUSED,
    TOOBIG, ConnectionManager.REASON_TOO_BIG
);

@Override
public void onClose(final int wsCode, final String wsReason) {
    Log.d(TAG, "onClose(): wsCode = " + wsCode + "; wsReason = " + wsReason);
    
    ErrorInfo reason = closeReasonMap.getOrDefault(wsCode, ConnectionManager.REASON_FAILED);
    connectListener.onTransportUnavailable(WebSocketTransport.this, reason);
    dispose();
}

This approach reduces the complexity of the method while maintaining the same logic.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c7e5ecd and d2b310b.

Files selected for processing (40)
  • android/build.gradle (1 hunks)
  • build.gradle (1 hunks)
  • dependencies.gradle (1 hunks)
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java (2 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpCore.java (12 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java (2 hunks)
  • lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (10 hunks)
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java (4 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/HttpTest.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java (3 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java (5 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
  • network-client-default/build.gradle.kts (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (1 hunks)
  • network-client-okhttp/build.gradle.kts (1 hunks)
  • network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java (1 hunks)
  • settings.gradle (1 hunks)
Files skipped from review as they are similar to previous changes (38)
  • build.gradle
  • dependencies.gradle
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java
  • lib/src/main/java/io/ably/lib/http/HttpCore.java
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java
  • lib/src/test/java/io/ably/lib/test/rest/HttpTest.java
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java
  • network-client-core/build.gradle.kts
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpConnectionException.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java
  • network-client-default/build.gradle.kts
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java
  • network-client-okhttp/build.gradle.kts
  • network-client-okhttp/src/main/java/io/ably/lib/network/OkHttpEngine.java
  • settings.gradle
Additional context used
ast-grep
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html

Additional comments not posted (9)
android/build.gradle (2)

88-101: Summary: Changes align well with PR objectives

The modifications to android/build.gradle effectively support the PR's goal of decoupling HTTP and WebSocket engines. The new dependencies introduce necessary functionality for serialization, JSON processing, and network operations. The addition of project dependencies (':network-client-core' and ':network-client-default') suggests a well-structured modular approach to the refactoring.

The enhanced test dependencies will help maintain code quality during this significant refactoring effort. Overall, these changes contribute to improving the codebase's structure and maintainability.


92-93: LGTM! Please provide more information about the new modules.

The addition of ':network-client-core' and ':network-client-default' project dependencies aligns well with the PR's objective of decoupling HTTP and WebSocket engines. This modular approach should improve the codebase's structure and maintainability.

Could you please provide more information about these new modules? Specifically:

  1. What functionality does each module encapsulate?
  2. How do they interact with the existing codebase?
  3. Are there any migration steps required for existing code?

To help verify the module structure, please run the following script:

lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (7)

4-8: LGTM: New imports enhance modularity

The addition of these WebSocket-related imports suggests a move towards a more modular and flexible WebSocket implementation. This change is likely to improve code organization, testability, and maintainability.


50-50: LGTM: Updated WebSocket client member

The change from WsClient wsConnection to WebSocketClient webSocketClient aligns well with the new WebSocket implementation. This update likely provides a more standardized and potentially more robust WebSocket client interface.


81-100: LGTM: Improved WebSocket connection process

The refactored connection process using WebSocketEngineFactory and WebSocketEngine provides greater flexibility and configurability. This approach allows for easier swapping of WebSocket implementations and improves the overall design.

Tools
ast-grep

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html


114-116: LGTM: Updated close method

The changes to the close() method correctly use the new webSocketClient instance, maintaining the same logical flow as before. This update is consistent with the overall refactoring of the WebSocket implementation.


138-138: LGTM: Improved send method with better error handling

The updates to the send() method correctly use the new webSocketClient for sending messages. The addition of NotConnectedException handling enhances the robustness of the method by providing more specific error management.

Also applies to: 143-143, 145-145


Line range hint 191-295: LGTM: Improved WebSocketHandler implementation

The new WebSocketHandler class, implementing WebSocketListener, provides a more focused and maintainable approach to handling WebSocket events. This change enhances the separation of concerns and aligns well with the overall refactoring of the WebSocket implementation.


369-369: LGTM: Updated activity timer logic

The change from wsConnection.close() to webSocketClient.cancel() is consistent with the new WebSocket implementation. The logic for handling inactivity remains sound, maintaining the same behavior as before.

@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from d2b310b to ec95bbe Compare September 24, 2024 15:19
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 24, 2024 15:20 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range and nitpick comments (1)
android/build.gradle (1)

Line range hint 18-30: Consider updating minSdkVersion

The current minSdkVersion is set to 19, which corresponds to Android 4.4 (KitKat), released in 2013. While this ensures wide compatibility, it may limit the use of newer Android features and optimizations.

Consider increasing the minSdkVersion to a more recent version, such as 21 (Android 5.0 Lollipop) or higher, depending on your user base and required features. This could allow for more modern API usage and potentially simplify development.

Before making this change, analyze your user base to ensure you're not excluding a significant portion of your users.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d2b310b and ec95bbe.

Files selected for processing (4)
  • android/build.gradle (2 hunks)
  • build.gradle (1 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • settings.gradle (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • network-client-core/build.gradle.kts
Additional comments not posted (6)
settings.gradle (1)

1-7: LGTM: Plugin management configuration looks good.

The added pluginManagement block is correctly structured and includes commonly used repositories (Google, Gradle Plugin Portal, and Maven Central). This configuration ensures that Gradle can properly resolve plugins required for the project.

build.gradle (1)

5-6: LGTM! Consider updating plugin versions and clarify Android Library plugin usage.

The addition of Lombok and Android Library plugins aligns well with the PR's objective of improving code structure and maintainability. Setting apply false allows for selective application in subprojects, which is a good practice.

However, I have a few suggestions:

  1. The Lombok plugin version (5.0.1) is quite old. Consider updating to the latest version (currently 8.4) for potential bug fixes and new features.

  2. The Android Library plugin version (4.2.2) is also outdated. The latest version is 8.2.0. Updating could provide access to newer Android features and optimizations.

  3. The introduction of the Android Library plugin is interesting. Could you provide more context on how Android support fits into the project's roadmap? This wasn't mentioned in the PR objectives.

To check for the latest versions of these plugins, you can run:

android/build.gradle (4)

1-3: LGTM: Updated to use the plugins DSL

The change from buildscript to plugins block is a good modernization of the build script. It simplifies the configuration and aligns with current Gradle best practices.


Line range hint 102-107: LGTM: Appropriate configuration for test dependencies

The configuration to exclude hamcrest-core and extend testImplementation to androidTestImplementation is appropriate. This helps avoid potential conflicts and efficiently shares test dependencies between unit tests and instrumented tests.

The overall structure of the build file remains clean and well-organized, which is commendable.


86-93: LGTM: Enhanced test dependencies, but consider version updates

The addition of new test dependencies significantly improves the project's testing capabilities. This is a positive change that will enhance the robustness of the codebase.

However, some of the dependencies are using older versions:

  • JUnit 4.12 (latest is 4.13.2)
  • Mockito 1.10.19 (latest in 1.x series is 1.10.19, but 5.x is available)
  • NanoHTTPD 2.3.0 (latest is 2.3.1)

Consider updating these to their latest versions for potential bug fixes and improvements.

Please run the following script to check for the latest versions of these test dependencies:

#!/bin/bash
# Description: Check for the latest versions of the new test dependencies

# Function to fetch the latest version
fetch_latest_version() {
    local group=$1
    local artifact=$2
    curl -s "https://search.maven.org/solrsearch/select?q=g:${group}+AND+a:${artifact}&rows=1&wt=json" | jq -r '.response.docs[0].latestVersion'
}

# Check JUnit
latest_junit=$(fetch_latest_version "junit" "junit")
echo "junit - Current: 4.12, Latest: $latest_junit"

# Check Hamcrest
latest_hamcrest=$(fetch_latest_version "org.hamcrest" "hamcrest-all")
echo "hamcrest-all - Current: 1.3, Latest: $latest_hamcrest"

# Check NanoHTTPD
latest_nanohttpd=$(fetch_latest_version "org.nanohttpd" "nanohttpd")
echo "nanohttpd - Current: 2.3.0, Latest: $latest_nanohttpd"

# Check Mockito
latest_mockito=$(fetch_latest_version "org.mockito" "mockito-core")
echo "mockito-core - Current: 1.10.19, Latest: $latest_mockito"

# Check ConcurrentUnit
latest_concurrentunit=$(fetch_latest_version "net.jodah" "concurrentunit")
echo "concurrentunit - Current: 0.4.2, Latest: $latest_concurrentunit"

# Check SLF4J
latest_slf4j=$(fetch_latest_version "org.slf4j" "slf4j-simple")
echo "slf4j-simple - Current: 1.7.30, Latest: $latest_slf4j"

80-85: LGTM: New dependencies align with PR objectives

The addition of new dependencies (msgpack-core, gson, vcdiff-core) and project dependencies (network-client-core, network-client-default) aligns well with the PR's objective of decoupling HTTP and WebSocket engines. This modular approach should improve maintainability.

However, it's important to ensure that the specific versions of these dependencies are up-to-date and don't have any known security vulnerabilities.

Please run the following script to check for the latest versions of these dependencies:

settings.gradle Outdated Show resolved Hide resolved
@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from ec95bbe to 374ec59 Compare September 24, 2024 16:42
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 24, 2024 16:43 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (1)
gradle.properties (1)

1-2: LGTM! Consider using a placeholder for VERSION_NAME.

The GROUP and VERSION_NAME properties are correctly defined. The group ID follows the reverse domain name convention, which is a good practice.

Consider using a placeholder for VERSION_NAME (e.g., VERSION_NAME=1.2.42-SNAPSHOT) if this is a development version. This can help distinguish between release and development builds.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ec95bbe and 374ec59.

Files selected for processing (10)
  • android/build.gradle (2 hunks)
  • build.gradle (1 hunks)
  • gradle.properties (1 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • network-client-core/gradle.properties (1 hunks)
  • network-client-default/build.gradle.kts (1 hunks)
  • network-client-default/gradle.properties (1 hunks)
  • network-client-okhttp/build.gradle.kts (1 hunks)
  • network-client-okhttp/gradle.properties (1 hunks)
  • settings.gradle (1 hunks)
Files skipped from review as they are similar to previous changes (5)
  • android/build.gradle
  • network-client-core/build.gradle.kts
  • network-client-default/build.gradle.kts
  • network-client-okhttp/build.gradle.kts
  • settings.gradle
Additional comments not posted (9)
network-client-core/gradle.properties (1)

1-3: LGTM! Well-defined Gradle properties for the new module.

The gradle.properties file for the network-client-core module is correctly set up with the following properties:

  1. POM_ARTIFACT_ID: Correctly identifies the artifact as "network-client-core".
  2. POM_NAME: Provides a clear, human-readable name "Network Core".
  3. POM_PACKAGING: Specifies the standard JAR packaging for Java libraries.

These properties are essential for proper identification and packaging of the module in the build process and when published to repositories.

network-client-okhttp/gradle.properties (1)

1-3: LGTM! Properties are well-defined for the new module.

The gradle.properties file for the new 'network-client-okhttp' module is correctly set up with appropriate values:

  1. POM_ARTIFACT_ID is correctly set to 'network-client-okhttp'.
  2. POM_NAME provides a clear description: 'OkHttp Client'.
  3. POM_PACKAGING is appropriately set to 'jar' for a Java library.

These properties align well with the PR objectives of decoupling HTTP and WebSocket engines by creating a separate module for the OkHttp client. This separation will enhance the project's structure and facilitate easier management of different network client implementations.

build.gradle (2)

5-7: Overall assessment of plugin additions

The addition of these three plugins (Lombok, Android Library, and Maven Publish) aligns well with the PR objectives of refactoring and improving the project structure. These changes suggest a move towards:

  1. Reducing boilerplate code (Lombok)
  2. Better support for Android library development
  3. Improved artifact publishing capabilities

These additions will likely facilitate the decoupling of HTTP and WebSocket engines as mentioned in the PR objectives, by providing tools for cleaner code structure and easier module management.

While the plugin additions are approved in principle, please consider the version update suggestions in the previous comments to ensure you're using the most up-to-date and compatible versions of these plugins.


6-6: 🛠️ Refactor suggestion

Update Android Library plugin version and verify compatibility.

The Android Library plugin is added, which is necessary for building Android libraries. However, there are important considerations:

  1. The current version (4.2.2) is significantly outdated. The latest version as of September 2024 is 8.1.2. Updating to the latest version can provide access to new features, performance improvements, and bug fixes.
  2. The apply false directive is correctly used here, allowing subprojects to apply this plugin as needed.

Consider updating the plugin declaration:

-id 'com.android.library' version '4.2.2' apply false
+id 'com.android.library' version '8.1.2' apply false

Before updating, please verify compatibility with your project's Gradle version and other dependencies. Run the following script to check the current Gradle version:

gradle.properties (5)

4-9: LGTM! Project description and SCM details are well-defined.

The project description is concise and informative. The SCM URLs are consistent and follow the expected format for GitHub repositories. These properties are crucial for generating accurate POM files for Maven Central publishing.


11-13: LGTM! License information is accurate and complete.

The license information is well-defined, using the Apache Software License, Version 2.0. The license URL correctly points to the official Apache website. These properties are essential for compliance and transparency in open-source projects.


15-18: LGTM! Developer information and Sonatype staging profile are correctly defined.

The developer information is consistent with the project's group ID. Using the organization name (Ably) instead of an individual developer is appropriate for a company-maintained project. The Sonatype staging profile matches the group ID, which is correct for Maven Central publishing.


19-20: Existing Gradle and Android properties remain unchanged.

The org.gradle.jvmargs and android.useAndroidX properties were not modified in this PR. They continue to provide important configuration for the Gradle build process and Android project setup.


1-20: Summary: Gradle properties updated with comprehensive project metadata.

The changes to gradle.properties significantly enhance the project's metadata, particularly for Maven Central publishing. New properties have been added to define the project's group ID, version, description, SCM details, license information, and developer details. These additions follow best practices for open-source Java projects and will improve the project's visibility and usability when published to Maven repositories.

The existing Gradle and Android-specific properties remain unchanged, maintaining the current build configuration.

Overall, these changes represent a positive improvement to the project's build configuration and metadata.

network-client-default/gradle.properties Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
@ttypic ttypic force-pushed the chore-rearange-code branch from bd2945f to 161fc45 Compare September 25, 2024 07:40
@ttypic ttypic changed the base branch from chore-rearange-code to chore-update-gradle September 25, 2024 09:12
@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from 374ec59 to d0daa06 Compare September 25, 2024 09:28
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 25, 2024 09:28 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1032/javadoc September 25, 2024 09:29 Inactive
@ttypic ttypic force-pushed the chore-update-gradle branch from a7e2a22 to 7d70cd9 Compare September 25, 2024 09:29
@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from d0daa06 to 2e8d692 Compare September 25, 2024 09:31
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 25, 2024 09:32 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1032/javadoc September 25, 2024 09:32 Inactive
@ttypic ttypic requested a review from AndyTWF September 25, 2024 09:45
- Extracted HTTP calls and WebSocket listeners into a separate module.
- Introduced an abstraction layer for easier implementation swapping.
@ttypic ttypic force-pushed the ECO-4208/proxy-support branch from 2e8d692 to 6f38c17 Compare September 25, 2024 11:40
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features September 25, 2024 11:41 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1032/javadoc September 25, 2024 11:42 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (4)
.gitignore (1)

12-12: LGTM! Good addition to .gitignore

Adding lombok.config to .gitignore is a good practice. This file often contains project-specific Lombok configurations that shouldn't be shared across different development environments.

Consider grouping similar entries together for better organization. For instance, you could move lombok.config next to other configuration files or IDE-related entries.

network-client-core/src/main/java/io/ably/lib/network/FailedConnectionException.java (1)

1-7: LGTM! Consider adding more flexibility and documentation.

The implementation of FailedConnectionException is correct and follows good practices. Here are some suggestions for improvement:

  1. Consider adding a constructor that accepts both a custom message and a cause:

    public FailedConnectionException(String message, Throwable cause) {
        super(message, cause);
    }

    This would allow for more informative exception messages.

  2. The choice of extending RuntimeException makes this an unchecked exception. Ensure this aligns with your error handling strategy, as it doesn't force callers to explicitly handle the exception.

  3. Add Javadoc comments to describe the class purpose and constructor usage. For example:

    /**
     * Exception thrown when a network connection fails.
     */
    public class FailedConnectionException extends RuntimeException {
        /**
         * Constructs a new FailedConnectionException with the specified cause.
         *
         * @param cause the cause of the connection failure
         */
        public FailedConnectionException(Throwable cause) {
            super(cause);
        }
    }
  4. Consider making the class final if you don't intend for it to be subclassed:

    public final class FailedConnectionException extends RuntimeException {
        // ...
    }
lib/src/main/java/io/ably/lib/types/AblyException.java (1)

54-55: Approve with suggestion: Add null check for t.getCause()

The new condition for handling FailedConnectionException is a good addition to the exception handling logic. It correctly preserves the underlying cause and uses HostFailedException, which is consistent with how other connection-related exceptions are handled.

However, to improve robustness, consider adding a null check for t.getCause(). This will prevent potential NullPointerExceptions if the cause is null.

Here's a suggested improvement:

 if (t instanceof FailedConnectionException)
-    return new HostFailedException(t.getCause(), ErrorInfo.fromThrowable(t.getCause()));
+    return new HostFailedException(t.getCause() != null ? t.getCause() : t,
+                                   ErrorInfo.fromThrowable(t.getCause() != null ? t.getCause() : t));

This change ensures that if t.getCause() is null, the original exception t is used instead.

gradle/libs.versions.toml (1)

51-51: Approved: Addition of Lombok plugin

The addition of the Lombok plugin is consistent with the introduction of Lombok to the project. This will enable the use of Lombok's annotations to reduce boilerplate code.

Consider updating the project documentation to reflect the introduction of Lombok and provide guidelines on its usage within the project. This will help maintain consistency and inform other developers about this new tool in the project's ecosystem.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 374ec59 and 6f38c17.

📒 Files selected for processing (42)
  • .gitignore (1 hunks)
  • android/build.gradle.kts (1 hunks)
  • build.gradle.kts (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
  • java/build.gradle.kts (1 hunks)
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java (2 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpCore.java (13 hunks)
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java (2 hunks)
  • lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (10 hunks)
  • lib/src/main/java/io/ably/lib/types/AblyException.java (3 hunks)
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java (4 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/HttpTest.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java (3 hunks)
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java (5 hunks)
  • network-client-core/build.gradle.kts (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/FailedConnectionException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
  • network-client-default/build.gradle.kts (1 hunks)
  • network-client-default/gradle.properties (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java (1 hunks)
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java (1 hunks)
  • settings.gradle.kts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (32)
  • lib/src/main/java/io/ably/lib/debug/DebugOptions.java
  • lib/src/main/java/io/ably/lib/http/HttpCore.java
  • lib/src/main/java/io/ably/lib/http/HttpScheduler.java
  • lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java
  • lib/src/test/java/io/ably/lib/test/common/Helpers.java
  • lib/src/test/java/io/ably/lib/test/rest/HttpTest.java
  • lib/src/test/java/io/ably/lib/test/rest/RestAuthTest.java
  • lib/src/test/java/io/ably/lib/test/rest/RestChannelPublishTest.java
  • network-client-core/build.gradle.kts
  • network-client-core/src/main/java/io/ably/lib/network/EngineType.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpBody.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpRequest.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpResponse.java
  • network-client-core/src/main/java/io/ably/lib/network/NotConnectedException.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyAuthType.java
  • network-client-core/src/main/java/io/ably/lib/network/ProxyConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineConfig.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java
  • network-client-default/build.gradle.kts
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpCall.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultHttpEngineFactory.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketClient.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngine.java
  • network-client-default/src/main/java/io/ably/lib/network/DefaultWebSocketEngineFactory.java
🧰 Additional context used
ast-grep
lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html

🔇 Additional comments not posted (15)
settings.gradle.kts (1)

14-15: LGTM! The new modules align well with the PR objectives.

The addition of network-client-core and network-client-default modules supports the goal of decoupling HTTP and WebSocket engines. This change:

  1. Improves code organization by separating these components into distinct modules.
  2. Enhances maintainability by isolating network-related functionality.
  3. Facilitates easier implementation swapping through the likely abstraction layer in network-client-core.
  4. Allows for potential future extensions or alternative implementations via the network-client-default module.

These changes are consistent with the PR's aim to refactor and improve the structure of the codebase.

android/build.gradle.kts (1)

55-56: New network client dependencies added.

The addition of :network-client-core as an implementation dependency and :network-client-default as a runtime-only dependency aligns with the PR objective of decoupling HTTP and WebSocket engines. This change supports the introduction of an abstraction layer for easier implementation swapping.

A few points to consider:

  1. Ensure that the :network-client-core and :network-client-default modules are properly set up in the project structure.
  2. Verify that these new dependencies don't conflict with any existing network-related functionalities in the project.
  3. Consider adding comments to explain the purpose of these new dependencies for future maintainers.

To verify the existence and setup of the new modules, run the following script:

✅ Verification successful

Dependencies correctly added.

The modules :network-client-core and :network-client-default exist and contain their respective build.gradle.kts files. This confirms that the new dependencies are properly set up and aligned with the project structure.

  • Ensure that these modules are correctly integrated with existing code and that their functionalities do not conflict with current implementations.
  • Consider documenting the purpose of these dependencies for future reference.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of new network client modules

# Test 1: Check if the network-client-core module exists
echo "Checking for network-client-core module:"
fd -t d "network-client-core$"

# Test 2: Check if the network-client-default module exists
echo "Checking for network-client-default module:"
fd -t d "network-client-default$"

# Test 3: Check for build.gradle.kts files in these modules
echo "Checking for build.gradle.kts files in the new modules:"
fd -t f "build.gradle.kts$" -p "network-client-core" -p "network-client-default"

Length of output: 578

lib/src/main/java/io/ably/lib/types/AblyException.java (2)

3-3: LGTM: New import statement is appropriate.

The addition of the import statement for FailedConnectionException is necessary for the new exception handling logic and follows the existing import style in the file.


3-3: Overall: Good enhancement to exception handling

The changes in this file improve the exception handling capabilities of the AblyException class. By adding specific handling for FailedConnectionException, the code now provides more granular error information for this type of failure. This enhancement is consistent with the existing pattern of creating HostFailedException instances for connection-related issues.

The changes maintain the method's contract and integrate well with the existing code structure. This improvement will likely lead to more accurate error reporting and easier debugging of connection failures in the Ably Java library.

Also applies to: 54-55

java/build.gradle.kts (1)

22-23: LGTM! The new dependencies align well with the PR objectives.

The addition of these two project dependencies:

  1. implementation(project(":network-client-core"))
  2. runtimeOnly(project(":network-client-default"))

is consistent with the goal of decoupling HTTP and WebSocket engines. The use of implementation for the core module and runtimeOnly for the default module supports the creation of an abstraction layer, allowing for easier implementation swapping as mentioned in the PR objectives. This structure enhances code organization and maintainability.

gradle/libs.versions.toml (2)

43-43: Approved: Removal of 'java-websocket' from common bundle

The removal of 'java-websocket' from the common bundle aligns well with the PR objective of decoupling HTTP and WebSocket engines. This change contributes to the overall goal of improving the structure and maintainability of the codebase.


19-19: Verify Lombok version

The addition of Lombok (version 8.10) is noted. However, this version number seems unusually high for Lombok. The latest stable version of Lombok is typically in the 1.x range.

Please double-check if this version number is correct. If it's a typo, consider updating it to the latest stable version of Lombok.

To verify the latest version, you can run:

lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java (8)

4-8: LGTM: New imports enhance modularity

The addition of these new imports for WebSocket-related classes aligns well with the PR objective of decoupling HTTP and WebSocket engines. This change suggests a more modular and flexible WebSocket implementation, which should improve maintainability and extensibility.


50-50: LGTM: Updated WebSocket client reference

The replacement of wsConnection with webSocketClient is consistent with the new WebSocket implementation. This change is crucial for integrating the new WebSocket engine and aligns with the overall refactoring objective.


81-100: LGTM with suggestion: Enhanced connection logic

The new connection logic using WebSocketEngineFactory and WebSocketEngineConfig introduces greater flexibility and configurability, which is excellent. This aligns well with the PR's objective of decoupling the WebSocket engine.

However, I noticed that the SSL context initialization still uses SSLContext.getInstance("TLS"), which may default to older, less secure protocols. As mentioned in a previous review, it's recommended to specify TLSv1.2 or higher for better security.

Consider applying this diff to specify a more secure TLS version:

- SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
🧰 Tools
ast-grep

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html


114-116: LGTM: Updated close method

The changes to the close method are consistent with the new WebSocket implementation. The logic remains similar, but now correctly uses the webSocketClient reference. This update ensures proper closure of the WebSocket connection with the new implementation.


138-138: LGTM: Updated send method

The changes to the send method appropriately use the new webSocketClient reference for sending messages. This update ensures compatibility with the new WebSocket implementation while maintaining the existing logic for both binary and text message formats.

Also applies to: 143-143


Line range hint 191-295: LGTM: Improved WebSocket handling with WebSocketHandler

The replacement of WsClient with WebSocketHandler is a significant improvement:

  1. Implementing WebSocketListener instead of extending WebSocketClient provides better separation of concerns and flexibility.
  2. Updated method signatures (onOpen, onClose, onError) align with the new WebSocket implementation.
  3. The addition of onWebsocketPing allows for more efficient connection management without relying on Ably heartbeats.
  4. The new onOldJavaVersionDetected method provides better error handling for SSL-related issues on older Java versions.

These changes align well with the PR objective of decoupling the WebSocket engine and should improve the overall robustness of the WebSocket implementation.


369-369: LGTM: Updated connection closure on timeout

The change from wsConnection.close() to webSocketClient.cancel() is consistent with the new WebSocket implementation. This update ensures that the connection is properly closed using the appropriate method when an activity timeout occurs.


Line range hint 1-382: Overall assessment: Successful refactoring with improved modularity

The changes in this file successfully achieve the PR objective of decoupling the WebSocket engine. Key improvements include:

  1. Introduction of a more flexible WebSocket engine configuration.
  2. Replacement of WsClient with WebSocketHandler, providing better separation of concerns.
  3. Enhanced WebSocket event handling, including support for WebSocket pings.
  4. Consistent updates throughout the file to use the new WebSocket client implementation.

These changes should result in a more maintainable and extensible WebSocket implementation. The only remaining point of attention is the SSL context initialization, which was addressed in a previous comment.

Great work on this refactoring!

🧰 Tools
ast-grep

[warning] 90-90: 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all
SSL versions are considered weak encryption and are deprecated. Use
SSLContext.getInstance("TLSv1.2") for the best security.'
Context: SSLContext.getInstance("TLS")
Note: [CWE-326] Inadequate Encryption Strength [REFERENCES]
- https://tools.ietf.org/html/rfc7568
- https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html

network-client-default/gradle.properties Show resolved Hide resolved
build.gradle.kts Show resolved Hide resolved
Copy link
Collaborator

@sacOO7 sacOO7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Engine terminology used across interfaces and classes is confusing. Can we replace naming with either Lib or Client instead.
Also, some of the intermediate interfaces/calsses can be entirely removed leading to the creation of either defaultHTTPClient or OkHttpClient.
I will post more information regarding this 👍

@ttypic ttypic requested a review from sacOO7 October 7, 2024 09:22
@github-actions github-actions bot temporarily deployed to staging/pull/1032/features October 7, 2024 09:23 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1032/javadoc October 7, 2024 09:23 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (16)
network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (2)

3-5: Enhance the Javadoc comment for better documentation.

While the current comment provides a basic description, it could be more informative. Consider expanding it to include:

  1. A more detailed explanation of the interface's purpose.
  2. Information about the WebSocketListener parameter.
  3. Description of the returned WebSocketClient.

Here's a suggested improvement:

/**
 * Defines a factory for creating WebSocket clients bound to specific URLs.
 * This interface allows for flexible implementation of WebSocket creation strategies.
 *
 * @see WebSocketClient
 * @see WebSocketListener
 */

6-8: LGTM: Interface declaration and method signature are well-designed.

The WebSocketEngine interface and its create method are appropriately defined for a factory pattern. The method signature clearly indicates its purpose and parameters.

Consider adding Javadoc for the create method:

/**
 * Creates a WebSocket client bound to the specified URL.
 *
 * @param url The URL to which the WebSocket should connect.
 * @param listener The listener to handle WebSocket events.
 * @return A new WebSocketClient instance.
 */
WebSocketClient create(String url, WebSocketListener listener);

This addition would provide clearer documentation for implementers and users of this interface.

network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (2)

9-12: LGTM: Well-defined execute() method with minor documentation typo.

The execute() method is appropriately defined for synchronous HTTP request execution. However, there's a small typo in the documentation.

Please correct the typo in the documentation:

-     * Synchronously execute Http request and return response from te server
+     * Synchronously execute Http request and return response from the server

1-18: Excellent interface design: Concise, focused, and aligned with PR objectives.

The HttpCall interface is well-designed, adhering to the Single Responsibility Principle and providing a clear contract for implementers. It aligns perfectly with the PR objectives of decoupling HTTP functionality, allowing for easier implementation swapping and improved maintainability.

Key strengths:

  1. Focused on a single responsibility (HTTP request execution and cancellation).
  2. Clear and concise method signatures.
  3. Explicit thread-safety requirement.
  4. Easily mockable for unit testing.

This interface forms a solid foundation for the refactoring effort to decouple HTTP and WebSocket engines.

Consider adding a method to check the status of the HTTP call (e.g., isExecuted(), isCancelled()), which could be useful for more granular control and error handling in client code.

network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (2)

9-12: Approve method with suggestion for improved documentation.

The call method signature is well-defined and aligns with the interface's purpose. However, the Javadoc comment could be more descriptive.

Consider expanding the Javadoc comment to provide more details:

/**
 * Makes a cancelable HTTP request.
 *
 * @param request The HTTP request to be executed
 * @return A cancelable HTTP request call
 */
HttpCall call(HttpRequest request);

14-18: Approve method with suggestion for concise documentation.

The isUsingProxy method is well-defined and its purpose is clear. The Javadoc comment is good but could be more concise.

Consider simplifying the Javadoc comment:

/**
 * @return true if the engine is configured to use a proxy, false otherwise
 */
boolean isUsingProxy();
network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (4)

3-7: Enhance interface documentation for clarity.

The interface documentation provides a basic explanation, but it could be more comprehensive. Consider adding information about:

  1. The lifecycle of the WebSocket connection.
  2. Any specific threading or concurrency considerations.
  3. How error handling is expected to be implemented.
  4. Any dependencies or prerequisites for using this interface.

This additional context will help implementers better understand the expected behavior and responsibilities of the WebSocketClient.


9-12: Enhance connect() method documentation.

While the current documentation is concise, it could be more informative. Consider adding:

  1. Information about possible exceptions that might be thrown.
  2. The expected state of the connection after this method is called.
  3. Whether this method is blocking or non-blocking.
  4. Any prerequisites before calling this method.

Example:

/**
 * Establishes a connection to the WebSocket server.
 * 
 * @throws IOException if there's an error during connection establishment
 * @throws IllegalStateException if the client is already connected
 * @return void This method doesn't return anything, but the connection state should be checked separately.
 */
void connect();

14-17: Enhance close() method documentation.

The current documentation is brief. Consider expanding it to include:

  1. The behavior if the connection is already closed or was never opened.
  2. Whether this method is blocking or non-blocking.
  3. Any exceptions that might be thrown.
  4. The state of the WebSocketClient after this method is called.

Example:

/**
 * Sends the closing handshake to the WebSocket server.
 * This method initiates a graceful shutdown of the connection.
 * 
 * @throws IOException if there's an error during the closing handshake
 * @throws IllegalStateException if the connection is already closed or was never opened
 */
void close();

1-50: Overall assessment of the WebSocketClient interface

The WebSocketClient interface provides a solid foundation for implementing WebSocket functionality in the Ably Java library. It covers the essential operations needed for managing a WebSocket connection, including connecting, sending messages, and closing the connection.

Strengths:

  1. Clear and concise method names that follow Java conventions.
  2. Separation of concerns between different connection operations.
  3. Support for both binary and text message sending.

Areas for improvement:

  1. Enhance method documentation to provide more detailed information about behavior, exceptions, and constraints.
  2. Consider adding parameter validation for methods that accept parameters.
  3. Potentially add methods for checking connection state and handling connection events.

Consider adding the following methods to make the interface more comprehensive:

/**
 * Checks if the WebSocket connection is currently open and ready for communication.
 *
 * @return true if the connection is open, false otherwise.
 */
boolean isConnected();

/**
 * Sets a listener for WebSocket events such as message received, connection closed, etc.
 *
 * @param listener The WebSocketListener to handle events.
 */
void setListener(WebSocketListener listener);

These additions would provide users of the interface with more control and information about the WebSocket connection state and events.

network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (4)

5-8: Enhance the interface Javadoc comment.

While the interface name is clear, the Javadoc comment could be more descriptive. Consider expanding it to provide more context about the interface's purpose and usage.

Suggested improvement:

/**
 * WebSocket Listener interface
 * 
 * This interface defines callback methods for handling various WebSocket events.
 * Implementations of this interface can be used to respond to connection events,
 * incoming messages, and error conditions in a WebSocket communication.
 */
public interface WebSocketListener {

31-34: Improve method name and enhance Javadoc for onWebsocketPing.

  1. The method name should follow Java naming conventions. Consider changing it to onWebSocketPing.
  2. The Javadoc could be more informative about the expected behavior when a ping frame is received.

Suggested improvements:

/**
 * Callback for receiving a ping frame from the WebSocket server.
 * This method is called when a ping frame is received, if supported by the WebSocket engine.
 * Implementations may use this to update connection status or perform keep-alive actions.
 */
void onWebSocketPing();

36-41: Enhance Javadoc for onClose method.

While the method signature is clear, the Javadoc could be more informative about the parameters and their significance.

Suggested improvement:

/**
 * Called after the WebSocket connection has been closed.
 *
 * @param code The status code indicating the reason for closure (as per WebSocket protocol).
 * @param reason A human-readable string explaining the reason for closure.
 */
void onClose(int code, String reason);

53-57: Consider generalizing method name and enhance Javadoc for onOldJavaVersionDetected.

  1. The method name is very specific. Consider a more general name like onSecurityConstraintViolation to cover other potential security issues.
  2. The Javadoc could be more informative about the implications and expected actions when this method is called.

Suggested improvements:

/**
 * Called when a security constraint violation is detected, such as inability to use secure HTTPS algorithms.
 * This method is typically invoked when the runtime environment cannot support TLS 1.2 or higher,
 * which may occur on older Java versions.
 *
 * @param throwable The exception providing details about the security constraint violation.
 */
void onSecurityConstraintViolation(Throwable throwable);

If you prefer to keep the current method name, at least enhance the Javadoc as suggested above.

CONTRIBUTING.md (2)

44-52: Improve Markdown formatting for the code block

The descriptions of the supported engines are clear and informative. The code snippet for replacing the default engine with the OkHttp engine is helpful. However, the code block is not properly formatted according to Markdown standards.

Please update the code block formatting to use triple backticks (```) instead of single backticks. This will ensure proper syntax highlighting and improve readability. For example:

```kotlin
implementation("io.ably:ably-java:$ABLY_VERSION") {
    exclude(group = "io.ably", module = "network-client-default")
}
runtimeOnly("io.ably:network-client-okhttp:$ABLY_VERSION")

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Markdownlint</summary><blockquote>

47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)

</blockquote></details>

</details>

---

`54-64`: **Improve list formatting for consistency**

The instructions for adding a new network engine are clear and concise. They provide a good overview of the process, which is helpful for contributors.


To maintain consistency with the rest of the document, please adjust the list formatting. Remove the extra indentation for list items. For example:

```markdown
To add a new network engine, follow these steps:

1. **Implement the interfaces**:
   - Implement the `HttpEngineFactory` and `WebSocketEngineFactory` interfaces for your custom engine.

2. **Register the engine**:
   - Modify the `getFirstAvailable()` methods in these interfaces to include your new implementation.

This change will ensure that the list formatting is consistent throughout the document.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~64-~64: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...engine will be available for use within ably-java. ### Code Standard #### Checkstyle ...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6f38c17 and 576374b.

📒 Files selected for processing (8)
  • CONTRIBUTING.md (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
🧰 Additional context used
🪛 LanguageTool
CONTRIBUTING.md

[uncategorized] ~40-~40: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...twork Engine Implementation Currently, ably-java supports two different engines for net...

(HYPHENATED_LY_ADVERB_ADJECTIVE)


[uncategorized] ~64-~64: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...engine will be available for use within ably-java. ### Code Standard #### Checkstyle ...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint
CONTRIBUTING.md

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)

🔇 Additional comments (17)
network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (2)

1-1: LGTM: Package declaration is correct and follows conventions.

The package declaration io.ably.lib.network is consistent with the file path and follows Java naming conventions.


1-8: Summary: Well-designed interface that aligns with PR objectives.

The WebSocketEngine interface is a well-structured addition that supports the PR's goal of decoupling HTTP and WebSocket engines. It provides a clean abstraction for WebSocket client creation, which should enhance the flexibility and maintainability of the codebase.

The interface design allows for easy implementation swapping, as different WebSocketEngine implementations can be created without affecting the rest of the system. This aligns perfectly with the PR's objective of introducing an abstraction layer for easier implementation swapping.

Overall, this change is a positive step towards improving the organization and extensibility of the Ably Java library's networking components.

network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (2)

1-8: LGTM: Well-documented interface with clear purpose and requirements.

The package declaration is appropriate, and the interface documentation clearly describes its purpose as a cancelable HTTP request call. The explicit mention of thread-safety requirement is crucial for implementers.


14-18: LGTM: Well-defined cancel() method.

The cancel() method is appropriately defined and documented for canceling pending HTTP requests.

network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (2)

1-7: LGTM: Package declaration and interface documentation are well-defined.

The package declaration is appropriate, and the Javadoc comment provides a clear description of the interface's purpose, including important details about configurations such as proxy settings.


1-18: Well-designed interface aligning with PR objectives.

The HttpEngine interface is well-structured and clearly defines the contract for an HTTP engine capable of making cancelable HTTP requests. It successfully contributes to the PR's goal of decoupling HTTP functionality and creating an abstraction layer. This abstraction will facilitate easier implementation swapping in the future, as outlined in the PR objectives.

The interface is concise, focusing on the essential operations (making HTTP calls and checking proxy usage). This design promotes flexibility and maintainability, allowing for different implementations to be easily swapped or modified without affecting the overall system.

network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (6)

1-4: LGTM: Package declaration and imports are appropriate.

The package declaration matches the file's location, and the ByteBuffer import is necessary for the onMessage method parameter.


9-13: LGTM: onOpen method is well-defined and documented.

The method name is clear, and the Javadoc provides appropriate information about when the method is called.


15-21: LGTM: onMessage(ByteBuffer blob) method is well-defined and documented.

The method signature is clear, and the Javadoc provides appropriate information about the purpose and parameter. The cross-reference to the string version of onMessage is helpful.


23-29: LGTM: onMessage(String string) method is well-defined and documented.

The method signature is clear, and the Javadoc provides appropriate information about the purpose and parameter. The cross-reference to the ByteBuffer version of onMessage is helpful.


43-51: LGTM: onError method is well-defined with comprehensive documentation.

The method signature is clear, and the Javadoc provides detailed information about different error scenarios and their implications. This is particularly helpful for implementers of the interface.


1-57: Overall assessment: Well-structured interface with minor improvements suggested.

The WebSocketListener interface provides a comprehensive set of callbacks for WebSocket events. The methods are generally well-named and documented. Minor improvements have been suggested for some method names and Javadoc comments to enhance clarity and consistency. These changes will make the interface more user-friendly for implementers.

CONTRIBUTING.md (2)

38-43: LGTM: Clear introduction to network engines

The new section provides a concise and informative introduction to the concept of network engine implementations in the ably-java library. It clearly states the two currently supported engines, which is helpful for contributors.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~40-~40: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...twork Engine Implementation Currently, ably-java supports two different engines for net...

(HYPHENATED_LY_ADVERB_ADJECTIVE)


38-64: Excellent addition to the contributing guidelines

The new section "Adding a New Network Engine Implementation" is a valuable addition to the CONTRIBUTING.md file. It provides clear instructions for contributors who wish to add new network engines to the ably-java library. This information will help maintain consistency and quality in the project as it grows.

The content is well-structured and informative, covering the current supported engines and the process for adding new ones. With the minor formatting adjustments suggested in previous comments, this section will be even more effective in guiding contributors.

Overall, these changes enhance the documentation and support the project's extensibility. Great work!

🧰 Tools
🪛 LanguageTool

[uncategorized] ~40-~40: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...twork Engine Implementation Currently, ably-java supports two different engines for net...

(HYPHENATED_LY_ADVERB_ADJECTIVE)


[uncategorized] ~64-~64: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...engine will be available for use within ably-java. ### Code Standard #### Checkstyle ...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)

network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (2)

23-41: Previous suggestions on code duplication and exception handling are still applicable

The methods tryGetOkHttpFactory() and tryGetDefaultFactory() contain similar code. Past review comments have suggested extracting the common logic into a helper method to adhere to the DRY (Don't Repeat Yourself) principle. Additionally, consider logging exceptions in the catch blocks to aid in debugging class loading issues.


15-21: Implementation of getFirstAvailable() is clear and effective

The method correctly attempts to load available HTTP engine factories in order of preference and handles the absence of engines appropriately by throwing an exception.

network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1)

14-20: getFirstAvailable() method implementation is clear and effective

The method correctly prioritizes the OkWebSocketEngineFactory and gracefully falls back to the default factory if necessary, throwing an exception only when no factories are available.

Also add algorithm how to add new engine in the `CONTRIBUTING.md` guide
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
CONTRIBUTING.md (3)

54-64: LGTM: Clear instructions for adding new network engines

The steps provided for adding a new network engine are concise and align well with the PR's goal of creating an abstraction layer for easier implementation swapping. This guidance will be valuable for developers looking to extend the library's functionality.

Consider adding a link to more detailed documentation or providing an example implementation to further assist developers in this process. This could help ensure that new implementations are consistent with the library's design principles.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~64-~64: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...engine will be available for use within ably-java. ### Code Standard #### Checkstyle ...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


47-52: LGTM: Clear example of engine swapping

The provided code snippet effectively demonstrates how to replace the default engine with the OkHttp engine, showcasing the library's flexibility as described in the PR objectives.

Consider adding a brief comment before the code snippet to explicitly state that this is Kotlin DSL syntax for Gradle. This could help developers who are more familiar with the Groovy DSL to understand and adapt the example to their needs.

🧰 Tools
🪛 Markdownlint

47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)


59-62: Consider adjusting list indentation and code block style for consistency

To improve the document's formatting consistency:

  1. Adjust the indentation of unordered lists to match the rest of the document. Currently, lines 59 and 62 have 2 spaces of indentation, while the standard is typically 0 or 4 spaces.
  2. Consider using consistent code block styles throughout the document. The code block starting at line 47 uses fenced style (```), while other parts of the document might use indented style.

These changes will enhance the overall consistency and readability of the document.

🧰 Tools
🪛 Markdownlint

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 576374b and 061eca7.

📒 Files selected for processing (8)
  • CONTRIBUTING.md (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java (1 hunks)
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • network-client-core/src/main/java/io/ably/lib/network/HttpCall.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/HttpEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketClient.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngine.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketEngineFactory.java
  • network-client-core/src/main/java/io/ably/lib/network/WebSocketListener.java
🧰 Additional context used
🪛 LanguageTool
CONTRIBUTING.md

[uncategorized] ~40-~40: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...twork Engine Implementation Currently, ably-java supports two different engines for net...

(HYPHENATED_LY_ADVERB_ADJECTIVE)


[uncategorized] ~64-~64: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...engine will be available for use within ably-java. ### Code Standard #### Checkstyle ...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint
CONTRIBUTING.md

59-59: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


62-62: Expected: 0; Actual: 2
Unordered list indentation

(MD007, ul-indent)


47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)

🔇 Additional comments (1)
CONTRIBUTING.md (1)

38-52: LGTM: Clear explanation of network engine implementations

This new section effectively introduces the concept of network engines in the ably-java library, aligning well with the PR's objective of decoupling HTTP and WebSocket engines. The explanation of the two existing engines (Default and OkHttp) provides valuable context for developers and demonstrates the improved code organization and maintainability.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~40-~40: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...twork Engine Implementation Currently, ably-java supports two different engines for net...

(HYPHENATED_LY_ADVERB_ADJECTIVE)

🪛 Markdownlint

47-47: Expected: indented; Actual: fenced
Code block style

(MD046, code-block-style)

CONTRIBUTING.md Show resolved Hide resolved
Copy link
Collaborator

@sacOO7 sacOO7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, you can take a look at comment though

@ttypic ttypic changed the base branch from chore-update-gradle to main October 7, 2024 14:38
@ttypic ttypic merged commit 8dfc73a into main Oct 7, 2024
9 of 10 checks passed
@ttypic ttypic deleted the ECO-4208/proxy-support branch October 7, 2024 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants