Skip to content

Commit c1ed9a9

Browse files
committed
Modify Async callback setup convention
1 parent aefb657 commit c1ed9a9

3 files changed

Lines changed: 353 additions & 331 deletions

File tree

framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java

Lines changed: 39 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,59 +24,58 @@
2424
import java.util.HashMap;
2525
import java.util.Map;
2626

27+
import net.sf.cglib.proxy.Enhancer;
28+
import net.sf.cglib.proxy.MethodInterceptor;
29+
import net.sf.cglib.proxy.MethodProxy;
2730

2831
@SuppressWarnings("rawtypes")
29-
public class AsyncCallbackDispatcher implements AsyncCompletionCallback {
30-
private static Map<Class<?>, Map<String, Method>> s_handlerCache = new HashMap<Class<?>, Map<String, Method>>();
31-
private final String parentCallbackKey = "parentCallback";
32-
private Map<String, Object> _contextMap = new HashMap<String, Object>();
33-
private String _operationName;
34-
private Object _targetObject;
32+
public class AsyncCallbackDispatcher<T> implements AsyncCompletionCallback {
33+
private Method _callbackMethod;
34+
private T _targetObject;
35+
private Object _contextObject;
3536
private Object _resultObject;
3637
private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver();
3738

38-
public AsyncCallbackDispatcher(Object target) {
39+
public AsyncCallbackDispatcher(T target) {
3940
assert(target != null);
4041
_targetObject = target;
4142
}
4243

43-
public AsyncCallbackDispatcher setContextParam(String key, Object param) {
44-
_contextMap.put(key, param);
45-
return this;
46-
}
47-
48-
public <T> AsyncCallbackDispatcher setParentCallback(AsyncCompletionCallback<T> parentCallback) {
49-
_contextMap.put(parentCallbackKey, parentCallback);
50-
return this;
51-
}
52-
53-
public AsyncCallbackDispatcher getParentCallback() {
54-
return (AsyncCallbackDispatcher)_contextMap.get(parentCallbackKey);
55-
}
56-
5744
public AsyncCallbackDispatcher attachDriver(AsyncCallbackDriver driver) {
5845
assert(driver != null);
5946
_driver = driver;
6047

6148
return this;
6249
}
6350

64-
public AsyncCallbackDispatcher setOperationName(String name) {
65-
_operationName = name;
66-
return this;
51+
public Method getCallbackMethod() {
52+
return _callbackMethod;
6753
}
6854

69-
public String getOperationName() {
70-
return _operationName;
55+
@SuppressWarnings("unchecked")
56+
public T getTarget() {
57+
return (T)Enhancer.create(_targetObject.getClass(), new MethodInterceptor() {
58+
@Override
59+
public Object intercept(Object arg0, Method arg1, Object[] arg2,
60+
MethodProxy arg3) throws Throwable {
61+
_callbackMethod = arg1;
62+
return null;
63+
}
64+
});
65+
}
66+
67+
public AsyncCallbackDispatcher setCallback(Object useless) {
68+
return this;
7169
}
7270

73-
public Object getTargetObject() {
74-
return _targetObject;
71+
public AsyncCallbackDispatcher setContext(Object context) {
72+
_contextObject = context;
73+
return this;
7574
}
7675

7776
@SuppressWarnings("unchecked")
78-
public <T> T getContextParam(String key) {
79-
return (T)_contextMap.get(key);
77+
public <P> P getContext() {
78+
return (P)_contextObject;
8079
}
8180

8281
public void complete(Object resultObject) {
@@ -85,65 +84,28 @@ public void complete(Object resultObject) {
8584
}
8685

8786
@SuppressWarnings("unchecked")
88-
public <T> T getResult() {
89-
return (T)_resultObject;
87+
public <R> R getResult() {
88+
return (R)_resultObject;
89+
}
90+
91+
public Object getTargetObject() {
92+
return _targetObject;
9093
}
9194

9295
public static boolean dispatch(Object target, AsyncCallbackDispatcher callback) {
9396
assert(callback != null);
9497
assert(target != null);
9598

96-
Method handler = resolveHandler(target.getClass(), callback.getOperationName());
97-
if(handler == null)
98-
return false;
99-
10099
try {
101-
handler.invoke(target, callback);
100+
callback.getCallbackMethod().invoke(target, callback, callback.getContext());
102101
} catch (IllegalArgumentException e) {
103-
throw new RuntimeException("IllegalArgumentException when invoking RPC callback for command: " + callback.getOperationName());
102+
throw new RuntimeException("IllegalArgumentException when invoking RPC callback for command: " + callback.getCallbackMethod().getName());
104103
} catch (IllegalAccessException e) {
105-
throw new RuntimeException("IllegalAccessException when invoking RPC callback for command: " + callback.getOperationName());
104+
throw new RuntimeException("IllegalAccessException when invoking RPC callback for command: " + callback.getCallbackMethod().getName());
106105
} catch (InvocationTargetException e) {
107-
throw new RuntimeException("InvocationTargetException when invoking RPC callback for command: " + callback.getOperationName(), e);
106+
throw new RuntimeException("InvocationTargetException when invoking RPC callback for command: " + callback.getCallbackMethod().getName());
108107
}
109108

110109
return true;
111110
}
112-
113-
public static Method resolveHandler(Class<?> handlerClz, String command) {
114-
synchronized(s_handlerCache) {
115-
Map<String, Method> handlerMap = getAndSetHandlerMap(handlerClz);
116-
117-
Method handler = handlerMap.get(command);
118-
if(handler != null)
119-
return handler;
120-
121-
for(Method method : handlerClz.getDeclaredMethods()) {
122-
AsyncCallbackHandler annotation = method.getAnnotation(AsyncCallbackHandler.class);
123-
if(annotation != null) {
124-
if(annotation.operationName().equals(command)) {
125-
handlerMap.put(command, method);
126-
method.setAccessible(true);
127-
return method;
128-
}
129-
}
130-
}
131-
}
132-
133-
return null;
134-
}
135-
136-
private static Map<String, Method> getAndSetHandlerMap(Class<?> handlerClz) {
137-
Map<String, Method> handlerMap;
138-
synchronized(s_handlerCache) {
139-
handlerMap = s_handlerCache.get(handlerClz);
140-
141-
if(handlerMap == null) {
142-
handlerMap = new HashMap<String, Method>();
143-
s_handlerCache.put(handlerClz, handlerMap);
144-
}
145-
}
146-
147-
return handlerMap;
148-
}
149111
}

framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,25 @@
2020

2121
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
2222
import org.apache.cloudstack.framework.async.AsyncCallbackDriver;
23-
import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
2423

2524
public class AsyncSampleEventDrivenStyleCaller {
2625
AsyncSampleCallee _ds = new AsyncSampleCallee();
2726
AsyncCallbackDriver _callbackDriver;
2827

28+
@SuppressWarnings("unchecked")
2929
public void MethodThatWillCallAsyncMethod() {
30-
Object vol = new Object();
31-
_ds.createVolume(vol,
32-
new AsyncCallbackDispatcher(this)
33-
.setOperationName("volume.create")
34-
.setContextParam("origVolume", vol)
35-
);
30+
String vol = new String("Hello");
31+
AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller> caller = new AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller>(this);
32+
_ds.createVolume(vol, caller
33+
.setCallback(caller.getTarget().HandleVolumeCreateAsyncCallback(null, null))
34+
.setContext(vol)
35+
);
3636
}
3737

38-
@AsyncCallbackHandler(operationName="volume.create")
39-
public void HandleVolumeCreateAsyncCallback(AsyncCallbackDispatcher callback) {
40-
Object origVol = callback.getContextParam("origVolume");
41-
38+
public Void HandleVolumeCreateAsyncCallback(AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller> callback, String context) {
4239
Object resultVol = callback.getResult();
40+
41+
return null;
4342
}
4443

4544
public static void main(String[] args) {

0 commit comments

Comments
 (0)