com.twitter.hbc.httpclient.BasicClient.java Source code

Java tutorial

Introduction

Here is the source code for com.twitter.hbc.httpclient.BasicClient.java

Source

/**
 * Copyright 2013 Twitter, Inc.
 * 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 com.twitter.hbc.httpclient;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.Nullable;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.HttpParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.twitter.hbc.RateTracker;
import com.twitter.hbc.ReconnectionManager;
import com.twitter.hbc.core.Client;
import com.twitter.hbc.core.Hosts;
import com.twitter.hbc.core.StatsReporter;
import com.twitter.hbc.core.endpoint.StreamingEndpoint;
import com.twitter.hbc.core.event.Event;
import com.twitter.hbc.core.processor.HosebirdMessageProcessor;
import com.twitter.hbc.httpclient.auth.Authentication;

/**
 * This class and classes in this package will depend on HttpClient
 */

public class BasicClient implements Client {

    private final static int DEFAULT_STOP_TIMEOUT_MILLIS = 5000;

    private final ExecutorService executorService;

    private final ClientBase clientBase;
    private final AtomicBoolean canRun;

    private final static Logger logger = LoggerFactory.getLogger(BasicClient.class);

    public BasicClient(String name, Hosts hosts, StreamingEndpoint endpoint, Authentication auth,
            boolean enableGZip, HosebirdMessageProcessor processor, ReconnectionManager reconnectionManager,
            RateTracker rateTracker, ExecutorService executorService, @Nullable BlockingQueue<Event> eventsQueue,
            HttpParams params, SchemeRegistry schemeRegistry) {
        Preconditions.checkNotNull(auth);
        HttpClient client;
        if (enableGZip) {
            client = new RestartableHttpClient(auth, enableGZip, params, schemeRegistry);
        } else {
            DefaultHttpClient defaultClient = new DefaultHttpClient(
                    new PoolingClientConnectionManager(schemeRegistry), params);

            /** Set auth **/
            auth.setupConnection(defaultClient);
            client = defaultClient;
        }

        this.canRun = new AtomicBoolean(true);
        this.executorService = executorService;
        this.clientBase = new ClientBase(name, client, hosts, endpoint, auth, processor, reconnectionManager,
                rateTracker, eventsQueue);
    }

    /**
     * For testing only
     */
    @VisibleForTesting
    BasicClient(final ClientBase clientBase, ExecutorService executorService) {
        this.canRun = new AtomicBoolean(true);
        this.clientBase = clientBase;
        this.executorService = executorService;
    }

    /**
     * {@inheritDoc}
     * Forks a new thread to do the IO in.
     */
    @Override
    public void connect() {
        if (!canRun.compareAndSet(true, false) || clientBase.isDone()) {
            throw new IllegalStateException("There is already a connection thread running for " + this.clientBase);
        }
        executorService.execute(clientBase);
        logger.info("New connection executed: {}", this.clientBase);
    }

    @Override
    public StatsReporter.StatsTracker getStatsTracker() {
        return clientBase.getStatsTracker();
    }

    public boolean isDone() {
        return clientBase.isDone();
    }

    /**
     * This method should only be called after the client is done
     */
    public Event getExitEvent() {
        return clientBase.getExitEvent();
    }

    @Override
    public void stop() {
        stop(DEFAULT_STOP_TIMEOUT_MILLIS);
    }

    @Override
    public void stop(int waitMillis) {
        logger.info("Stopping the client: " + this.clientBase);
        try {
            clientBase.stop(waitMillis);
            logger.info("Successfully stopped the client: {}", this.clientBase);
        } catch (InterruptedException e) {
            logger.info("Thread interrupted when attempting to stop the client: {}", this.clientBase);
        }
        executorService.shutdown();
    }

    @Override
    public String getName() {
        return clientBase.getName();
    }

    @Override
    public StreamingEndpoint getEndpoint() {
        return clientBase.getEndpoint();
    }

    @Override
    public void reconnect() {
        clientBase.reconnect();
    }

    @VisibleForTesting
    boolean waitForFinish(int millis) throws InterruptedException {
        return clientBase.waitForFinish(millis);
    }
}