com.ning.metrics.goodwill.access.GoodwillAccessor.java Source code

Java tutorial

Introduction

Here is the source code for com.ning.metrics.goodwill.access.GoodwillAccessor.java

Source

/*
 * Copyright 2010-2011 Ning, Inc.
 *
 * Ning licenses this file to you 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 com.ning.metrics.goodwill.access;

import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.Response;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Future;

public class GoodwillAccessor extends Accessor {
    protected static final ObjectMapper mapper = new ObjectMapper();
    protected AsyncHttpClient client;

    public GoodwillAccessor(final String host, final int port) {
        super(host, port);
        client = createHttpClient();
    }

    /**
     * Get the Goodwill schema associated to a schema name.
     * </p>
     * Typical invocation:
     * <pre>
     * try {
     *   GoodwillSchema type = accessor.getSchema("test").get();
     * ...
     * }
     * catch (Exception e) {
     *   // Connection exception? Goodwill server down?
     * }
     * </pre>
     *
     * @param schemaName schema name to lookup
     * @return a future on the Schema
     */
    public Future<GoodwillSchema> getSchema(final String schemaName) {
        try {
            return client.prepareGet(String.format("%s/%s", url, schemaName))
                    .addHeader("Accept", "application/json").execute(new AsyncCompletionHandler<GoodwillSchema>() {
                        @Override
                        public GoodwillSchema onCompleted(final Response response) throws Exception {
                            if (response.getStatusCode() != 200) {
                                return null;
                            }

                            final InputStream in = response.getResponseBodyAsStream();
                            try {
                                return mapper.readValue(in, GoodwillSchema.class);
                            } finally {
                                closeStream(in);
                            }
                        }

                        @Override
                        public void onThrowable(final Throwable t) {
                            log.warn("Got exception looking up the schema", t);
                        }
                    });
        } catch (IOException e) {
            log.warn("Got exception looking up the schema", e);
            return null;
        }
    }

    /**
     * Get all schemata.
     * <p/>
     * Use schemata, instead of schemas, which is closer to the original .
     *
     * @return a future on a list of Schema
     * @see #getSchema(String) for an invocation example
     */
    public Future<List<GoodwillSchema>> getSchemata() {
        try {
            return client.prepareGet(url).addHeader("Accept", "application/json")
                    .execute(new AsyncCompletionHandler<List<GoodwillSchema>>() {
                        @Override
                        public List<GoodwillSchema> onCompleted(final Response response) throws Exception {
                            if (response.getStatusCode() != 200) {
                                return null;
                            }

                            InputStream in = response.getResponseBodyAsStream();
                            try {
                                final HashMap<String, List<GoodwillSchema>> map = mapper.readValue(in,
                                        new TypeReference<HashMap<String, List<GoodwillSchema>>>() {
                                        });
                                return map.get("types");
                            } finally {
                                closeStream(in);
                            }
                        }

                        @Override
                        public void onThrowable(final Throwable t) {
                            log.warn("Got exception looking up the schema list", t);
                        }
                    });
        } catch (IOException e) {
            log.warn("Got exception looking up the schema list", e);
            return null;
        }
    }

    // note: if called from base-class constructor, couldn't sub-class; hence just make static
    private static AsyncHttpClient createHttpClient() {
        // Don't limit the number of connections per host
        // See https://github.com/ning/async-http-client/issues/issue/28
        final AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
        builder.setMaximumConnectionsPerHost(-1);
        return new AsyncHttpClient(builder.build());
    }

    /**
     * Close the underlying http client
     */
    public synchronized void close() {
        client.close();
    }

    protected final void closeStream(final InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                log.warn("Failed to close http-client - provided InputStream: {}", e.getLocalizedMessage());
            }
        }
    }
}