Skip to content

Commit 90b561e

Browse files
author
sasurendran
committed
Adding AsyncHttpClientFactory and AsyncHttpClientRegistry
1 parent 9588664 commit 90b561e

16 files changed

+1078
-6
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Then in your code you can simply do ([Javadoc](http://sonatype.github.com/async-
2424
import com.ning.http.client.*;
2525
import java.util.concurrent.Future;
2626

27-
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
27+
AsyncHttpClient asyncHttpClient = AsyncHttpClientFactory.getAsyncHttpClient();
2828
Future<Response> f = asyncHttpClient.prepareGet("http://www.ning.com/").execute();
2929
Response r = f.get();
3030
```
@@ -37,7 +37,7 @@ You can also accomplish asynchronous (non-blocking) operation without using a Fu
3737
import com.ning.http.client.*;
3838
import java.util.concurrent.Future;
3939

40-
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
40+
AsyncHttpClient asyncHttpClient = AsyncHttpClientFactory.getAsyncHttpClient();
4141
asyncHttpClient.prepareGet("http://www.ning.com/").execute(new AsyncCompletionHandler<Response>(){
4242

4343
@Override
@@ -62,7 +62,7 @@ You can also mix Future with AsyncHandler to only retrieve part of the asynchron
6262
import com.ning.http.client.*;
6363
import java.util.concurrent.Future;
6464

65-
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
65+
AsyncHttpClient asyncHttpClient = AsyncHttpClientFactory.getAsyncHttpClient();
6666
Future<Integer> f = asyncHttpClient.prepareGet("http://www.ning.com/").execute(
6767
new AsyncCompletionHandler<Integer>(){
6868

@@ -89,7 +89,7 @@ which is something you want to do for large responses: this way you can process
8989
import com.ning.http.client.*;
9090
import java.util.concurrent.Future;
9191

92-
AsyncHttpClient c = new AsyncHttpClient();
92+
AsyncHttpClient c = AsyncHttpClientFactory.getAsyncHttpClient();
9393
Future<String> f = c.prepareGet("http://www.ning.com/").execute(new AsyncHandler<String>() {
9494
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
9595

@@ -140,7 +140,7 @@ Finally, you can also configure the AsyncHttpClient via its AsyncHttpClientConfi
140140
```java
141141
AsyncHttpClientConfig cf = new AsyncHttpClientConfig.Builder()
142142
S.setProxyServer(new ProxyServer("127.0.0.1", 38080)).build();
143-
AsyncHttpClient c = new AsyncHttpClient(cf);
143+
AsyncHttpClient c = AsyncHttpClientFactory.getAsyncHttpClient(cf);
144144
```
145145

146146
## WebSocket
@@ -176,7 +176,7 @@ The library uses Java non blocking I/O for supporting asynchronous operations. T
176176

177177
```java
178178
AsyncHttpClientConfig config = new AsyncHttpClientConfig.Builder().build();
179-
AsyncHttpClient client = new AsyncHttpClient(new GrizzlyAsyncHttpProvider(config), config);
179+
AsyncHttpClient client = AsyncHttpClientFactory.getAsyncHttpClient(new GrizzlyAsyncHttpProvider(config), config);
180180
```
181181

182182
## User Group
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package org.asynchttpclient;
2+
3+
import org.asynchttpclient.util.AsyncImplHelper;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import java.lang.reflect.Constructor;
8+
import java.util.concurrent.locks.Lock;
9+
import java.util.concurrent.locks.ReentrantLock;
10+
11+
/**
12+
* The AsyncHttpClientFactory returns back an instance of AsyncHttpClient. The
13+
* actual instance is determined by the system property
14+
* 'org.async.http.client.impl'. If the system property doesn't exist then it
15+
* checks for a property file 'asynchttpclient.properties' and looks for a
16+
* property 'org.async.http.client.impl' in there. If it finds it then returns
17+
* an instance of that class. If there is an exception while reading the
18+
* properties file or system property it throws a RuntimeException
19+
* AsyncHttpClientImplException. If any of the constructors of the instance
20+
* throws an exception it thows a AsyncHttpClientImplException. By default if
21+
* neither the system property or the property file exists then it will return
22+
* the default instance of {@link DefaultAsyncHttpClient}
23+
*
24+
* @author sasurendran
25+
*
26+
*/
27+
public class AsyncHttpClientFactory {
28+
29+
private static Class<AsyncHttpClient> asyncHttpClientImplClass = null;
30+
private static volatile boolean instantiated = false;
31+
public static final Logger logger = LoggerFactory.getLogger(AsyncHttpClientFactory.class);
32+
private static Lock lock = new ReentrantLock();
33+
34+
public static AsyncHttpClient getAsyncHttpClient() {
35+
36+
try {
37+
if (attemptInstantiation())
38+
return (AsyncHttpClient) asyncHttpClientImplClass.newInstance();
39+
} catch (InstantiationException e) {
40+
throw new AsyncHttpClientImplException("Unable to create the class specified by system property : "
41+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY,e);
42+
} catch (IllegalAccessException e) {
43+
throw new AsyncHttpClientImplException("Unable to find the class specified by system property : "
44+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY,e);
45+
}
46+
return new DefaultAsyncHttpClient();
47+
}
48+
49+
public static AsyncHttpClient getAsyncHttpClient(AsyncHttpProvider provider) {
50+
if (attemptInstantiation()) {
51+
try {
52+
Constructor<AsyncHttpClient> constructor = asyncHttpClientImplClass
53+
.getConstructor(AsyncHttpProvider.class);
54+
return constructor.newInstance(provider);
55+
}catch (Exception e) {
56+
throw new AsyncHttpClientImplException(
57+
"Unable to find the instantiate the class specified by system property : "
58+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY
59+
+ "(AsyncHttpProvider) due to : " + e.getMessage(), e);
60+
}
61+
}
62+
return new DefaultAsyncHttpClient(provider);
63+
}
64+
65+
public static AsyncHttpClient getAsyncHttpClient(AsyncHttpClientConfig config) {
66+
if (attemptInstantiation()) {
67+
try {
68+
Constructor<AsyncHttpClient> constructor = asyncHttpClientImplClass
69+
.getConstructor(AsyncHttpClientConfig.class);
70+
return constructor.newInstance(config);
71+
} catch (Exception e) {
72+
throw new AsyncHttpClientImplException(
73+
"Unable to find the instantiate the class specified by system property : "
74+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY
75+
+ "(AsyncHttpProvider) due to : " + e.getMessage(), e);
76+
}
77+
}
78+
return new DefaultAsyncHttpClient(config);
79+
}
80+
81+
public static AsyncHttpClient getAsyncHttpClient(AsyncHttpProvider provider, AsyncHttpClientConfig config) {
82+
if (attemptInstantiation()) {
83+
try {
84+
Constructor<AsyncHttpClient> constructor = asyncHttpClientImplClass.getConstructor(
85+
AsyncHttpProvider.class, AsyncHttpClientConfig.class);
86+
return constructor.newInstance(provider, config);
87+
} catch (Exception e) {
88+
throw new AsyncHttpClientImplException(
89+
"Unable to find the instantiate the class specified by system property : "
90+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY
91+
+ "(AsyncHttpProvider) due to : " + e.getMessage(), e);
92+
}
93+
}
94+
return new DefaultAsyncHttpClient(provider, config);
95+
}
96+
97+
public static AsyncHttpClient getAsyncHttpClient(String providerClass, AsyncHttpClientConfig config) {
98+
if (attemptInstantiation()) {
99+
try {
100+
Constructor<AsyncHttpClient> constructor = asyncHttpClientImplClass.getConstructor(String.class,
101+
AsyncHttpClientConfig.class);
102+
return constructor.newInstance(providerClass, config);
103+
} catch (Exception e) {
104+
throw new AsyncHttpClientImplException(
105+
"Unable to find the instantiate the class specified by system property : "
106+
+ AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY
107+
+ "(AsyncHttpProvider) due to : " + e.getMessage(), e);
108+
}
109+
}
110+
return new DefaultAsyncHttpClient(providerClass, config);
111+
}
112+
113+
private static boolean attemptInstantiation() {
114+
if (!instantiated) {
115+
lock.lock();
116+
try {
117+
if (!instantiated) {
118+
asyncHttpClientImplClass = AsyncImplHelper
119+
.getAsyncImplClass(AsyncImplHelper.ASYNC_HTTP_CLIENT_IMPL_SYSTEM_PROPERTY);
120+
instantiated = true;
121+
}
122+
} finally {
123+
lock.unlock();
124+
}
125+
}
126+
return asyncHttpClientImplClass != null;
127+
}
128+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.asynchttpclient;
2+
3+
public class AsyncHttpClientImplException extends RuntimeException {
4+
5+
public AsyncHttpClientImplException(String msg) {
6+
super(msg);
7+
}
8+
9+
public AsyncHttpClientImplException(String msg, Exception e) {
10+
super(msg, e);
11+
}
12+
13+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.asynchttpclient;
2+
3+
import java.util.Set;
4+
5+
public interface AsyncHttpClientRegistry {
6+
7+
/**
8+
* Returns back the AsyncHttpClient associated with this name
9+
*
10+
* @param clientName
11+
* @return
12+
*/
13+
AsyncHttpClient get(String clientName);
14+
15+
/**
16+
* Registers this instance of AsyncHttpClient with this name and returns
17+
* back a null if an instance with the same name never existed but will return back the
18+
* previous instance if there was another instance registered with the same
19+
* name and has been replaced by this one.
20+
*
21+
* @param name
22+
* @param ahc
23+
* @return
24+
*/
25+
AsyncHttpClient addOrReplace(String name, AsyncHttpClient ahc);
26+
27+
/**
28+
* Will register only if an instance with this name doesn't exist and if it
29+
* does exist will not replace this instance and will return false. Use it in the
30+
* following way:
31+
* <blockquote><pre>
32+
* AsyncHttpClient ahc = AsyncHttpClientFactory.getAsyncHttpClient();
33+
* if(!AsyncHttpClientRegistryImpl.getInstance().registerIfNew(“MyAHC”,ahc)){
34+
* //An instance with this name is already registered so close ahc
35+
* ahc.close();
36+
* //and do necessary cleanup
37+
* }
38+
* </pre></blockquote>
39+
*
40+
* @param name
41+
* @param ahc
42+
* @return
43+
*/
44+
45+
boolean registerIfNew(String name, AsyncHttpClient ahc);
46+
47+
/**
48+
* Remove the instance associate with this name
49+
*
50+
* @param name
51+
* @return
52+
*/
53+
54+
boolean unRegister(String name);
55+
56+
/**
57+
* Returns back all registered names
58+
*
59+
* @return
60+
*/
61+
62+
Set<String> getAllRegisteredNames();
63+
64+
/**
65+
* Removes all instances from this registry.
66+
*/
67+
68+
void clearAllInstances();
69+
70+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package org.asynchttpclient;
2+
3+
import org.asynchttpclient.util.AsyncImplHelper;
4+
5+
import java.util.Set;
6+
import java.util.concurrent.ConcurrentHashMap;
7+
import java.util.concurrent.ConcurrentMap;
8+
import java.util.concurrent.locks.Lock;
9+
import java.util.concurrent.locks.ReentrantLock;
10+
11+
public class AsyncHttpClientRegistryImpl implements AsyncHttpClientRegistry {
12+
13+
private static ConcurrentMap<String, AsyncHttpClient> asyncHttpClientMap = new ConcurrentHashMap<String, AsyncHttpClient>();
14+
private static volatile AsyncHttpClientRegistry _instance;
15+
private static Lock lock = new ReentrantLock();
16+
17+
/**
18+
* Returns a singleton instance of AsyncHttpClientRegistry
19+
* @return
20+
*/
21+
public static AsyncHttpClientRegistry getInstance() {
22+
if (_instance == null) {
23+
lock.lock();
24+
try {
25+
if (_instance == null) {
26+
Class asyncHttpClientRegistryImplClass = AsyncImplHelper
27+
.getAsyncImplClass(AsyncImplHelper.ASYNC_HTTP_CLIENT_REGISTRY_SYSTEM_PROPERTY);
28+
if (asyncHttpClientRegistryImplClass != null)
29+
_instance = (AsyncHttpClientRegistry) asyncHttpClientRegistryImplClass.newInstance();
30+
else
31+
_instance = new AsyncHttpClientRegistryImpl();
32+
}
33+
} catch (InstantiationException e) {
34+
throw new AsyncHttpClientImplException("Couldn't instantiate AsyncHttpClientRegistry : "
35+
+ e.getMessage(), e);
36+
} catch (IllegalAccessException e) {
37+
throw new AsyncHttpClientImplException("Couldn't instantiate AsyncHttpClientRegistry : "
38+
+ e.getMessage(), e);
39+
} finally {
40+
lock.unlock();
41+
}
42+
}
43+
return _instance;
44+
}
45+
46+
/*
47+
* (non-Javadoc)
48+
*
49+
* @see org.asynchttpclient.IAsyncHttpClientRegistry#get(java.lang.String)
50+
*/
51+
@Override
52+
public AsyncHttpClient get(String clientName) {
53+
return asyncHttpClientMap.get(clientName);
54+
}
55+
56+
/*
57+
* (non-Javadoc)
58+
*
59+
* @see
60+
* org.asynchttpclient.IAsyncHttpClientRegistry#register(java.lang.String,
61+
* org.asynchttpclient.AsyncHttpClient)
62+
*/
63+
@Override
64+
public AsyncHttpClient addOrReplace(String name, AsyncHttpClient ahc) {
65+
return asyncHttpClientMap.put(name, ahc);
66+
}
67+
68+
/*
69+
* (non-Javadoc)
70+
*
71+
* @see
72+
* org.asynchttpclient.IAsyncHttpClientRegistry#registerIfNew(java.lang.
73+
* String, org.asynchttpclient.AsyncHttpClient)
74+
*/
75+
@Override
76+
public boolean registerIfNew(String name, AsyncHttpClient ahc) {
77+
return asyncHttpClientMap.putIfAbsent(name, ahc)==null;
78+
}
79+
80+
/*
81+
* (non-Javadoc)
82+
*
83+
* @see
84+
* org.asynchttpclient.IAsyncHttpClientRegistry#unRegister(java.lang.String)
85+
*/
86+
@Override
87+
public boolean unRegister(String name) {
88+
return asyncHttpClientMap.remove(name) != null;
89+
}
90+
91+
/*
92+
* (non-Javadoc)
93+
*
94+
* @see org.asynchttpclient.IAsyncHttpClientRegistry#getAllRegisteredNames()
95+
*/
96+
@Override
97+
public Set<String> getAllRegisteredNames() {
98+
return asyncHttpClientMap.keySet();
99+
}
100+
101+
/*
102+
* (non-Javadoc)
103+
*
104+
* @see org.asynchttpclient.IAsyncHttpClientRegistry#clearAllInstances()
105+
*/
106+
@Override
107+
public void clearAllInstances() {
108+
asyncHttpClientMap.clear();
109+
}
110+
111+
}

0 commit comments

Comments
 (0)