Skip to content

Commit

Permalink
fixup! refactor: decouple HTTP and WebSocket engines
Browse files Browse the repository at this point in the history
  • Loading branch information
ttypic committed Sep 24, 2024
1 parent fe912c2 commit 8966f37
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 25 deletions.
4 changes: 3 additions & 1 deletion android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
minSdk = 19
compileSdk = 30
buildConfigField("String", "LIBRARY_NAME", "\"android\"")
buildConfigField("String", "VERSION", "\"${property("VERSION")}\"")
buildConfigField("String", "VERSION", "\"${property("VERSION_NAME")}\"")
testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["class"] = "io.ably.lib.test.android.AndroidPushTest"
testInstrumentationRunnerArguments["timeout_msec"] = "300000"
Expand Down Expand Up @@ -49,6 +49,8 @@ dependencies {
api(libs.gson)
implementation(libs.bundles.common)
testImplementation(libs.bundles.tests)
implementation(project(":network-client-core"))
runtimeOnly(project(":network-client-default"))
implementation("com.google.firebase:firebase-messaging:22.0.0")
androidTestImplementation("com.android.support.test:runner:0.5")
androidTestImplementation("com.android.support.test:rules:0.5")
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

plugins {
alias(libs.plugins.android.library) apply false
id("io.freefair.lombok") version "8.10" apply false
}

subprojects {
Expand Down
19 changes: 19 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
GROUP=io.ably
VERSION_NAME=1.2.42

POM_DESCRIPTION=Realtime and REST client library SDK for the Ably platform
POM_INCEPTION_YEAR=2015
POM_URL=https://github.com/ably/ably-java
POM_SCM_URL=https://github.com/ably/ably-java
POM_SCM_CONNECTION=scm:git:https://github.com/ably/ably-java.git
POM_SCM_DEV_CONNECTION=scm:git:[email protected]:ably/ably-java.git

POM_LICENSE_NAME=The Apache Software License, Version 2.0
POM_LICENSE_URL=https://raw.github.com/ably/ably-java/main/LICENSE
POM_LICENSE_DIST=repo

POM_DEVELOPER_ID=ably
POM_DEVELOPER_NAME=Ably
POM_DEVELOPER_URL=https://github.com/ably/
SONATYPE_STAGING_PROFILE=io.ably

org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
4 changes: 3 additions & 1 deletion java/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ java {
dependencies {
api(libs.gson)
implementation(libs.bundles.common)
implementation(project(":network-client-core"))
runtimeOnly(project(":network-client-default"))
testImplementation(libs.bundles.tests)
}

buildConfig {
useJavaOutput()
packageName = "io.ably.lib"
buildConfigField("String", "LIBRARY_NAME", "\"java\"")
buildConfigField("String", "VERSION", "\"$version\"")
buildConfigField("String", "VERSION", "\"${property("VERSION_NAME")}\"")
}

sourceSets {
Expand Down
33 changes: 27 additions & 6 deletions lib/src/main/java/io/ably/lib/http/HttpCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import com.google.gson.JsonParseException;
import io.ably.lib.debug.DebugOptions;
import io.ably.lib.network.HttpBody;
import io.ably.lib.network.FailedConnectionException;
import io.ably.lib.network.HttpEngine;
import io.ably.lib.network.HttpEngineConfig;
import io.ably.lib.network.HttpEngineFactory;
import io.ably.lib.network.HttpRequest;
import io.ably.lib.network.HttpBody;
import io.ably.lib.network.HttpResponse;
import io.ably.lib.rest.Auth;
import io.ably.lib.transport.Defaults;
Expand Down Expand Up @@ -64,8 +65,8 @@ public class HttpCore {
final Hosts hosts;
private final Auth auth;
private final PlatformAgentProvider platformAgentProvider;
private HttpAuth proxyAuth;
private final HttpEngine engine;
private HttpAuth proxyAuth;

/*************************
* Public API
Expand Down Expand Up @@ -202,7 +203,7 @@ public <T> T httpExecute(URL url, String method, Param[] headers, RequestBody re
* @return
* @throws AblyException
*/
<T> T httpExecute(URL url, String method, Param[] headers, RequestBody requestBody, boolean withCredentials, boolean withProxyCredentials, ResponseHandler<T> responseHandler) throws AblyException {
<T> T httpExecute(URL url, String method, Param[] headers, RequestBody requestBody, boolean withCredentials, boolean withProxyCredentials, ResponseHandler<T> responseHandler) throws AblyException {
HttpRequest.HttpRequestBuilder requestBuilder = HttpRequest.builder();
/* prepare connection */
requestBuilder
Expand Down Expand Up @@ -255,7 +256,14 @@ <T> T httpExecute(URL url, String method, Param[] headers, RequestBody requestBo
}
}

Response response = executeRequest(request);

Response response;

try {
response = executeRequest(request);
} catch (FailedConnectionException exception) {
throw AblyException.fromThrowable(exception);
}

if (rawHttpListener != null) {
rawHttpListener.onRawHttpResponse(id, method, response);
Expand Down Expand Up @@ -356,8 +364,8 @@ private <T> T handleResponse(boolean credentialsIncluded, Response response, Res

/* handle error details in header */
if (error == null) {
String errorCodeHeader = response.getHeaderFields("X-Ably-ErrorCode").get(0);
String errorMessageHeader = response.getHeaderFields("X-Ably-ErrorMessage").get(0);
String errorCodeHeader = response.getHeaderField("X-Ably-ErrorCode");
String errorMessageHeader = response.getHeaderField("X-Ably-ErrorMessage");
if (errorCodeHeader != null) {
try {
error = new ErrorInfo(errorMessageHeader, response.statusCode, Integer.parseInt(errorCodeHeader));
Expand Down Expand Up @@ -502,6 +510,19 @@ public List<String> getHeaderFields(String name) {

return headers.get(name.toLowerCase(Locale.ROOT));
}

public String getHeaderField(String name) {
if (headers == null) {
return null;
}

List<String> values = headers.get(name.toLowerCase(Locale.ROOT));
if (values == null || values.isEmpty()) {
return null;
}

return values.get(0);
}
}

/**
Expand Down
5 changes: 4 additions & 1 deletion lib/src/main/java/io/ably/lib/types/AblyException.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.ably.lib.types;

import io.ably.lib.network.FailedConnectionException;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.SocketTimeoutException;
Expand Down Expand Up @@ -50,6 +51,8 @@ public static AblyException fromThrowable(Throwable t) {
return (AblyException)t;
if(t instanceof ConnectException || t instanceof SocketTimeoutException || t instanceof UnknownHostException || t instanceof NoRouteToHostException)
return new HostFailedException(t, ErrorInfo.fromThrowable(t));
if (t instanceof FailedConnectionException)
return new HostFailedException(t.getCause(), ErrorInfo.fromThrowable(t.getCause()));

return new AblyException(t, ErrorInfo.fromThrowable(t));
}
Expand All @@ -61,4 +64,4 @@ public static class HostFailedException extends AblyException {
super(throwable, reason);
}
}
}
}
8 changes: 6 additions & 2 deletions lib/src/main/java/io/ably/lib/util/ClientOptionsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.ably.lib.network.ProxyConfig;
import io.ably.lib.types.ClientOptions;

import java.util.Arrays;
import java.util.List;

public class ClientOptionsUtils {
Expand All @@ -17,8 +18,11 @@ public static ProxyConfig covertToProxyConfig(ClientOptions clientOptions) {
.host(clientOptions.proxy.host)
.port(clientOptions.proxy.port)
.username(clientOptions.proxy.username)
.password(clientOptions.proxy.password)
.nonProxyHosts(List.of(clientOptions.proxy.nonProxyHosts));
.password(clientOptions.proxy.password);

if (clientOptions.proxy.nonProxyHosts != null) {
builder.nonProxyHosts(Arrays.asList(clientOptions.proxy.nonProxyHosts));
}

switch (clientOptions.proxy.prefAuthType) {
case BASIC:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.ably.lib.network;

public class FailedConnectionException extends RuntimeException {
public FailedConnectionException(Throwable cause) {
super(cause);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.net.URL;
Expand All @@ -15,13 +16,28 @@
@Setter(AccessLevel.NONE)
@AllArgsConstructor
public class HttpRequest {

public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TYPE = "Content-Type";

private final URL url;
private final String method;
private final int httpOpenTimeout;
private final int httpReadTimeout;
private final HttpBody body;
@Getter(AccessLevel.NONE)
private final Map<String, List<String>> headers;

public Map<String, List<String>> getHeaders() {
Map<String, List<String>> headersCopy = new HashMap<>(headers);
if (body != null) {
int length = body.getContent() == null ? 0 : body.getContent().length;
headersCopy.put(CONTENT_TYPE, Collections.singletonList(body.getContentType()));
headersCopy.put(CONTENT_LENGTH, Collections.singletonList(Integer.toString(length)));
}
return headersCopy;
}

public static HttpRequestBuilder builder() {
return new HttpRequestBuilder();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.NoRouteToHostException;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

class DefaultHttpCall implements HttpCall {
public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TYPE = "Content-Type";

private final Proxy proxy;
private final HttpRequest request;
private HttpURLConnection connection;
Expand All @@ -39,7 +40,9 @@ public HttpResponse execute() {
for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
String headerName = entry.getKey();
List<String> values = entry.getValue();
values.forEach(headerValue -> connection.setRequestProperty(headerName, headerValue));
for (String headerValue : values) {
connection.setRequestProperty(headerName, headerValue);
}
}

/* prepare request body */
Expand All @@ -49,8 +52,10 @@ public HttpResponse execute() {
}

return readResponse();
} catch (ConnectException | SocketTimeoutException | UnknownHostException | NoRouteToHostException fce) {
throw new FailedConnectionException(fce);
} catch (IOException ioe) {
throw new HttpConnectionException(ioe);
throw new RuntimeException(ioe);
} finally {
cancel();
}
Expand All @@ -71,8 +76,6 @@ private byte[] prepareRequestBody(HttpBody requestBody) throws IOException {
byte[] body = requestBody.getContent();
int length = body.length;
connection.setFixedLengthStreamingMode(length);
connection.setRequestProperty(CONTENT_TYPE, requestBody.getContentType());
connection.setRequestProperty(CONTENT_LENGTH, Integer.toString(length));
return body;
}

Expand Down
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ rootProject.name = "ably-java"
include("java")
include("android")
include("gradle-lint")
include("network-client-core")
include("network-client-default")
include("network-client-okhttp")

0 comments on commit 8966f37

Please sign in to comment.