uk.co.sdev.async.http.ning.ObservableClient.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.sdev.async.http.ning.ObservableClient.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 uk.co.sdev.async.http.ning;

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.AsyncHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.HttpResponseBodyPart;
import com.ning.http.client.HttpResponseHeaders;
import com.ning.http.client.HttpResponseStatus;
import com.ning.http.client.Request;
import com.ning.http.client.Response;
import rx.Observable;
import uk.co.sdev.async.http.HttpException;

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

public class ObservableClient {

    private final TypeFactory typeFactory = TypeFactory.defaultInstance();

    private final ObjectMapper objectMapper;

    private final AsyncHttpClient asyncHttpClient;

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

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

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

    private <T> Observable<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> Observable<T> get(String url, Consumer<Request> requestConsumer, ResponseMapper<T> responseMapper) {
        return execute(() -> asyncHttpClient.prepareGet(url).build(), requestConsumer, responseMapper);
    }

    public Observable<byte[]> stream(String url, Consumer<Request> requestConsumer) {
        return Observable.create(subscriber -> {
            try {
                Request request = asyncHttpClient.prepareGet(url).build();
                requestConsumer.accept(request);
                asyncHttpClient.executeRequest(request, new ObservableAsyncHandler(subscriber));
            } catch (Exception e) {
                subscriber.onError(e);
            }
        });
    }

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

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

    private <T> Observable<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> Observable<T> post(String url, String body, Consumer<Request> requestConsumer,
            ResponseMapper<T> responseMapper) {
        return execute(() -> asyncHttpClient.preparePost(url).setBody(body).build(), requestConsumer,
                responseMapper);
    }

    private <T> Observable<T> execute(Supplier<Request> requestSupplier, Consumer<Request> requestConsumer,
            ResponseMapper<T> responseMapper) {
        return Observable.create(subscriber -> {
            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);
                        subscriber.onNext(t);
                        subscriber.onCompleted();
                        return t;
                    }

                    @Override
                    public void onThrowable(Throwable t) {
                        subscriber.onError(t);
                    }
                });
            } catch (Exception e) {
                subscriber.onError(e);
            }
        });
    }
}