com.twitter.hbc.httpclient.BasicClient Maven / Gradle / Ivy
The newest version!
/**
* 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 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;
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 javax.annotation.Nullable;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 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 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);
}
}