Skip to content

Commit

Permalink
created InterceptingHttpClient
Browse files Browse the repository at this point in the history
  • Loading branch information
yvasyliev committed Dec 26, 2023
1 parent bec7524 commit 629f449
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 38 deletions.
4 changes: 2 additions & 2 deletions src/main/java/io/github/yvasyliev/deezer/DeezerContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import io.github.yvasyliev.deezer.http.DefaultHttpClient;
import io.github.yvasyliev.deezer.http.HttpClient;
import io.github.yvasyliev.deezer.http.InterceptingHttpClient;
import io.github.yvasyliev.deezer.methods.validators.AbstractResponseValidator;
import io.github.yvasyliev.deezer.methods.validators.ErrorValidator;
import io.github.yvasyliev.deezer.methods.validators.ResponseValidator;
Expand All @@ -26,7 +26,7 @@ public class DeezerContext {
public DeezerContext() {
this(
DEEZER_API_HOST,
new DefaultHttpClient(),
new InterceptingHttpClient(),
new ObjectMapper(),
AbstractResponseValidator.createChain(new WrongCodeValidator(), new ErrorValidator())
);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/io/github/yvasyliev/deezer/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import io.github.yvasyliev.deezer.objects.Track;

import java.io.IOException;
import java.net.URL;
import java.util.Map;

public class Main {
public static void main(String[] args) throws IOException {
DeezerClient deezerClient = new DeezerClient();
ObjectMapper objectMapper = deezerClient.getContext().getObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(objectMapper.convertValue("https://google.com", URL.class));
PagingMethod<Track> artistTop = deezerClient.getArtistTop(27);
Map<String, String> map = deezerClient.getContext().getObjectMapper().convertValue(artistTop, new TypeReference<Map<String, String>>() {
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package io.github.yvasyliev.deezer.http;

import io.github.yvasyliev.deezer.helpers.IOHelper;
import io.github.yvasyliev.deezer.helpers.QueryParams;
import io.github.yvasyliev.deezer.helpers.URLHelper;
import lombok.Cleanup;

import java.io.IOException;
Expand All @@ -12,14 +10,15 @@

public class DefaultHttpClient implements HttpClient {
@Override
public HttpResponse get(String url, QueryParams queryParams) throws IOException {
@Cleanup("disconnect") HttpURLConnection connection = (HttpURLConnection) URLHelper.newUrl(url, queryParams).openConnection();
public HttpResponse send(HttpRequest request) throws IOException {
@Cleanup("disconnect") HttpURLConnection connection = (HttpURLConnection) request.getUrl().openConnection();
connection.setRequestMethod(request.getMethod().name());
InputStream content = connection.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST
? connection.getInputStream()
: connection.getErrorStream();
return new HttpResponse(
new String(IOHelper.readAllBytes(content), StandardCharsets.UTF_8),
connection.getResponseCode()
connection.getResponseCode(),
new String(IOHelper.readAllBytes(content), StandardCharsets.UTF_8)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.github.yvasyliev.deezer.http;

import io.github.yvasyliev.deezer.helpers.QueryParams;

import java.io.IOException;

public interface HttpClient {
HttpResponse get(String url, QueryParams queryParams) throws IOException;
HttpResponse send(HttpRequest request) throws IOException;
}
5 changes: 5 additions & 0 deletions src/main/java/io/github/yvasyliev/deezer/http/HttpMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.yvasyliev.deezer.http;

public enum HttpMethod {
GET
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.yvasyliev.deezer.http;

import java.net.URL;

public interface HttpRequest {
HttpMethod getMethod();
URL getUrl();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
@Data
@AllArgsConstructor
public class HttpResponse {
private String content;
private int statusCode;
private String content;

public boolean isOk() {
return statusCode == HttpURLConnection.HTTP_OK;
}

@Override
public String toString() {
return statusCode + ": " + content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.github.yvasyliev.deezer.http;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;

@Getter
@Setter
@AllArgsConstructor
public class InterceptingHttpClient implements HttpClient {
private HttpClient origHttpClient;
private Interceptor<HttpRequest> requestInterceptor;
private Interceptor<HttpResponse> responseInterceptor;

public InterceptingHttpClient() {
this(
new DefaultHttpClient(),
request -> {
System.out.println(request);
return request;
},
response -> {
System.out.println(response);
return response;
}
);
}

@Override
public HttpResponse send(HttpRequest request) throws IOException {
return responseInterceptor.intercept(origHttpClient.send(requestInterceptor.intercept(request)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.yvasyliev.deezer.http;

import java.io.IOException;

@FunctionalInterface
public interface Interceptor<T> {
T intercept(T t) throws IOException;
}
15 changes: 3 additions & 12 deletions src/main/java/io/github/yvasyliev/deezer/methods/GetMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import io.github.yvasyliev.deezer.DeezerContext;
import io.github.yvasyliev.deezer.helpers.QueryParams;
import io.github.yvasyliev.deezer.http.HttpClient;
import io.github.yvasyliev.deezer.http.HttpResponse;

import java.io.IOException;
import io.github.yvasyliev.deezer.http.HttpMethod;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class GetMethod<T> extends Method<T> {
Expand All @@ -16,12 +12,7 @@ public GetMethod(DeezerContext context, String path, TypeReference<T> responseTy
}

@Override
protected HttpResponse fetch(HttpClient httpClient, String url, QueryParams queryParams) throws IOException {
return httpClient.get(url, queryParams);
}

@Override
public String toString() {
return "GET " + super.toString();
public HttpMethod getMethod() {
return HttpMethod.GET;
}
}
30 changes: 20 additions & 10 deletions src/main/java/io/github/yvasyliev/deezer/methods/Method.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
import io.github.yvasyliev.deezer.exceptions.DeezerResponseException;
import io.github.yvasyliev.deezer.exceptions.UnsupportedHttpResponseException;
import io.github.yvasyliev.deezer.helpers.QueryParams;
import io.github.yvasyliev.deezer.http.HttpClient;
import io.github.yvasyliev.deezer.http.HttpMethod;
import io.github.yvasyliev.deezer.http.HttpRequest;
import io.github.yvasyliev.deezer.http.HttpResponse;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.IOException;
import java.net.URL;

@Data
@AllArgsConstructor
public abstract class Method<T> {
public abstract class Method<T> implements HttpRequest {
@JacksonInject
@JsonIgnore
private DeezerContext context;
Expand All @@ -32,28 +34,36 @@ public abstract class Method<T> {
private TypeReference<T> responseType;

public T execute() throws IOException {
ObjectMapper mapper = context.getObjectMapper();
QueryParams queryParams = mapper.convertValue(this, QueryParams.class);
HttpResponse response = fetch(context.getHttpClient(), context.getDeezerApiHost() + path, queryParams);
HttpResponse response = context.getHttpClient().send(this);
if (!response.isOk()) {
throw new UnsupportedHttpResponseException(response);
}
ObjectMapper mapper = context.getObjectMapper();
JsonNode jsonResponse = mapper.readTree(response.getContent());
if (!context.getResponseValidator().validate(jsonResponse)) {
throw new DeezerResponseException(jsonResponse);
}
return mapper.treeToValue(jsonResponse, getResponseType());
}

protected abstract HttpResponse fetch(HttpClient httpClient, String url, QueryParams queryParams) throws IOException;

@JsonIgnore
@Override
public String toString() {
public URL getUrl() {
ObjectMapper mapper = context.getObjectMapper();
String endpoint = context.getDeezerApiHost() + path;
QueryParams queryParams = context.getObjectMapper().convertValue(this, QueryParams.class);
QueryParams queryParams = mapper.convertValue(this, QueryParams.class);
if (!queryParams.isEmpty()) {
endpoint += "?" + queryParams.toQuery();
}
return endpoint;
return mapper.convertValue(endpoint, URL.class);
}

@JsonIgnore
@Override
public abstract HttpMethod getMethod();

@Override
public String toString() {
return getMethod() + " " + getUrl();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package io.github.yvasyliev.deezer.methods.validators;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.NonNull;

public abstract class AbstractResponseValidator implements ResponseValidator {
private AbstractResponseValidator nextValidator;

public static AbstractResponseValidator createChain(@NonNull AbstractResponseValidator firstValidator, AbstractResponseValidator... chain) {
public static AbstractResponseValidator createChain(AbstractResponseValidator firstValidator, AbstractResponseValidator... chain) {
AbstractResponseValidator head = firstValidator;
for (AbstractResponseValidator nextInChain : chain) {
head.nextValidator = nextInChain;
Expand All @@ -15,8 +14,6 @@ public static AbstractResponseValidator createChain(@NonNull AbstractResponseVal
return firstValidator;
}

public abstract boolean validate(JsonNode rawResponse);

protected boolean validateNext(JsonNode rawResponse) {
return nextValidator == null || nextValidator.validate(rawResponse);
}
Expand Down

0 comments on commit 629f449

Please sign in to comment.