spring.travel.site.services.HttpClient.java Source code

Java tutorial

Introduction

Here is the source code for spring.travel.site.services.HttpClient.java

Source

/**
 * Copyright 2014 Andy Godwin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package spring.travel.site.services;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Request;
import com.ning.http.client.Response;

import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class HttpClient {

    private final TypeFactory typeFactory = TypeFactory.defaultInstance();

    private final ObjectMapper objectMapper;

    private final AsyncHttpClient asyncHttpClient;

    public HttpClient(ObjectMapper objectMapper, AsyncHttpClient asyncHttpClient) {
        this.objectMapper = objectMapper;
        this.asyncHttpClient = asyncHttpClient;
    }

    public <T> CompletableFuture<T> get(String url, Class<T> type) {
        return get(url, typeFactory.constructType(type));
    }

    public <T> CompletableFuture<T> get(String url, TypeReference<T> type) {
        return get(url, typeFactory.constructType(type));
    }

    private <T> CompletableFuture<T> get(String url, JavaType type) {
        return execute(() -> asyncHttpClient.prepareGet(url).build(), request -> {
            request.getHeaders().add("Accept", "application/json");
        }, response -> {
            switch (response.getStatusCode()) {
            case 200:
                return objectMapper.readValue(response.getResponseBody(), type);
            case 204:
                return null;
            default:
                throw new HttpException(response.getStatusCode());
            }
        });
    }

    public <T> CompletableFuture<T> get(String url, Consumer<Request> requestConsumer,
            ResponseMapper<T> responseMapper) {
        return execute(() -> asyncHttpClient.prepareGet(url).build(), requestConsumer, responseMapper);
    }

    public <T> CompletableFuture<T> post(String url, String body, Class<T> type) {
        return post(url, body, typeFactory.constructType(type));
    }

    public <T> CompletableFuture<T> post(String url, String body, TypeReference<T> type) {
        return post(url, body, typeFactory.constructType(type));
    }

    private <T> CompletableFuture<T> post(String url, String body, JavaType type) {
        return post(url, body, request -> request.getHeaders().add("Accept", "application/json").add("Content-Type",
                "application/json"), response -> {
                    switch (response.getStatusCode()) {
                    case 200:
                        return objectMapper.readValue(response.getResponseBody(), type);
                    case 201:
                    case 202:
                    case 204:
                        return null;
                    default:
                        throw new HttpException(response.getStatusCode());
                    }
                });
    }

    public <T> CompletableFuture<T> post(String url, String body, Consumer<Request> requestConsumer,
            ResponseMapper<T> responseMapper) {
        return execute(() -> asyncHttpClient.preparePost(url).setBody(body).build(), requestConsumer,
                responseMapper);
    }

    private <T> CompletableFuture<T> execute(Supplier<Request> requestSupplier, Consumer<Request> requestConsumer,
            ResponseMapper<T> responseMapper) {
        CompletableFuture<T> future = new CompletableFuture<>();
        try {
            Request request = requestSupplier.get();
            requestConsumer.accept(request);
            asyncHttpClient.executeRequest(request, new AsyncCompletionHandler<T>() {
                @Override
                public T onCompleted(Response response) throws Exception {
                    T t = responseMapper.map(response);
                    future.complete(t);
                    return t;
                }

                @Override
                public void onThrowable(Throwable t) {
                    future.completeExceptionally(t);
                }
            });
        } catch (Exception e) {
            future.completeExceptionally(e);
        }
        return future;
    }
}