com.lonepulse.zombielink.executor.HttpClientDirectory Maven / Gradle / Ivy
package com.lonepulse.zombielink.executor;
/*
* #%L
* ZombieLink
* %%
* Copyright (C) 2013 - 2014 Lonepulse
* %%
* 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.
* #L%
*/
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.client.HttpClient;
import com.lonepulse.zombielink.Directory;
import com.lonepulse.zombielink.annotation.Config;
import com.lonepulse.zombielink.proxy.Zombie;
/**
* A registry of {@link HttpClient}s which are configured to be used for a specific endpoint.
*
* @version 1.1.0
*
* @since 1.3.0
*
* @author Lahiru Sahan Jayasinghe
*/
enum HttpClientDirectory implements Directory, HttpClient> {
/**
* The {@link HttpClientDirectory} which caches {@link HttpClient}s that are uniquely configured
* for each endpoint. An {@link HttpClient} is stored or accessed using an endpoint's {@link Class}.
*
* @since 1.3.0
*/
INSTANCE;
/**
* The default configuration for an {@link HttpClient} which will be used to execute endpoint
* requests if no specialized configuration is provided.
*
* @since 1.3.0
*/
public static final HttpClient DEFAULT;
private static final Map DIRECTORY = new HashMap();
private static final Map ENDPOINT_CONFIGS = new HashMap();
static {
DEFAULT = new Zombie.Configuration(){}.httpClient();
DIRECTORY.put(Zombie.Configuration.class.getName(), DEFAULT);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
synchronized (DIRECTORY) {
for (HttpClient httpClient : DIRECTORY.values()) {
try {
httpClient.getConnectionManager().shutdown();
}
catch(Exception e) {
Logger.getLogger(HttpClientDirectory.class.getName()).log(
Level.WARNING, "Failed to shutdown the connection manager for an HTTP client.", e);
}
}
}
}
}));
}
/**
* Registers an instance of {@link HttpClient} under the given {@link Class} of the endpoint
* definition. If an {@link HttpClient} already exists under the given endpoint, no attempt
* will be made to replace the existing instance.
*
* @param endpoint
* the {@link Class} of the endpoint whose {@link HttpClient} is added to the directory
*
* @param httpClient
* the {@link HttpClient} which to be registered under the given endpoint definition
*
* @return the {@link HttpClient} which was registered under the given endpoint definition
*
* @since 1.3.0
*/
@Override
public synchronized HttpClient bind(Class> endpoint, HttpClient httpClient) {
String configClassName = endpoint.isAnnotationPresent(Config.class)?
endpoint.getAnnotation(Config.class).value().getName() :Zombie.Configuration.class.getName();
String endpointClassName = endpoint.getName();
if(!DIRECTORY.containsKey(configClassName)) {
DIRECTORY.put(configClassName, httpClient);
}
if(!ENDPOINT_CONFIGS.containsKey(endpointClassName)) {
ENDPOINT_CONFIGS.put(endpointClassName, configClassName);
}
return lookup(endpoint);
}
/**
* Retrieves the {@link HttpClient} which was registered under the given endpoint. If no instance
* was registered for this endpoint's {@link Class}, the {@link #DEFAULT} instance is returned.
*
* @param endpointClass
* the {@link Class} of the endpoint definition whose {@link HttpClient} is to be retrieved
*
* @return the {@link HttpClient} which was registered under the given endpoint, else the pre-configured
* {@link #DEFAULT} instance if no existing {@link HttpClient} was found
*
* @since 1.3.0
*/
@Override
public synchronized HttpClient lookup(Class> endpointClass) {
HttpClient httpClient = DIRECTORY.get(ENDPOINT_CONFIGS.get(endpointClass.getName()));
return httpClient == null? DEFAULT :httpClient;
}
}