diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackHandler.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackHandler.java deleted file mode 100644 index 40b3bddbf92..00000000000 --- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.cloudstack.framework.async; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface AsyncCallbackHandler { - String operationName(); -} diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java index c787e6a4da0..828a772b758 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java @@ -20,24 +20,47 @@ package org.apache.cloudstack.framework.rpc; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; -public class RpcCallbackDispatcher { - - private static Map, Map> s_handlerCache = new HashMap, Map>(); +public class RpcCallbackDispatcher { + private Method _callbackMethod; + private T _targetObject; - public static boolean dispatch(Object target, RpcClientCall clientCall) { + private RpcCallbackDispatcher(T target) { + _targetObject = target; + } + + @SuppressWarnings("unchecked") + public T getTarget() { + return (T)Enhancer.create(_targetObject.getClass(), new MethodInterceptor() { + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, + MethodProxy arg3) throws Throwable { + _callbackMethod = arg1; + return null; + } + }); + } + + public RpcCallbackDispatcher setCallback(Object useless) { + return this; + } + + public static

RpcCallbackDispatcher

create(P target) { + return new RpcCallbackDispatcher

(target); + } + + public boolean dispatch(RpcClientCall clientCall) { assert(clientCall != null); - assert(target != null); - - Method handler = resolveHandler(target.getClass(), clientCall.getCommand()); - if(handler == null) + + if(_callbackMethod == null) return false; try { - handler.invoke(target, clientCall); + _callbackMethod.invoke(_targetObject, clientCall, clientCall.getContext()); } catch (IllegalArgumentException e) { throw new RpcException("IllegalArgumentException when invoking RPC callback for command: " + clientCall.getCommand()); } catch (IllegalAccessException e) { @@ -48,41 +71,4 @@ public class RpcCallbackDispatcher { return true; } - - public static Method resolveHandler(Class handlerClz, String command) { - synchronized(s_handlerCache) { - Map handlerMap = getAndSetHandlerMap(handlerClz); - - Method handler = handlerMap.get(command); - if(handler != null) - return handler; - - for(Method method : handlerClz.getDeclaredMethods()) { - RpcCallbackHandler annotation = method.getAnnotation(RpcCallbackHandler.class); - if(annotation != null) { - if(annotation.command().equals(command)) { - method.setAccessible(true); - handlerMap.put(command, method); - return method; - } - } - } - } - - return null; - } - - private static Map getAndSetHandlerMap(Class handlerClz) { - Map handlerMap; - synchronized(s_handlerCache) { - handlerMap = s_handlerCache.get(handlerClz); - - if(handlerMap == null) { - handlerMap = new HashMap(); - s_handlerCache.put(handlerClz, handlerMap); - } - } - - return handlerMap; - } } diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackHandler.java b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackHandler.java deleted file mode 100644 index 86dfceb5c78..00000000000 --- a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.cloudstack.framework.rpc; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface RpcCallbackHandler { - String command(); -} diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java index 7a7e45ca78a..0e7516f2f48 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java @@ -29,11 +29,11 @@ public interface RpcClientCall { RpcClientCall setCommandArg(Object arg); Object getCommandArg(); - RpcClientCall setContextParam(String key, Object param); - T getContextParam(String key); + RpcClientCall setContext(Object param); + T getContext(); RpcClientCall addCallbackListener(RpcCallbackListener listener); - RpcClientCall setCallbackDispatcherTarget(Object target); + RpcClientCall setCallbackDispatcher(RpcCallbackDispatcher dispatcher); RpcClientCall setOneway(); diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java index 1db878d8f1f..cd427a40b4e 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java @@ -23,19 +23,20 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - public class RpcClientCallImpl implements RpcClientCall { private String _command; private Object _commandArg; private int _timeoutMilliseconds = DEFAULT_RPC_TIMEOUT; - private Map _contextParams = new HashMap(); + private Object _contextObject; private boolean _oneway = false; @SuppressWarnings("rawtypes") private List _callbackListeners = new ArrayList(); - private Object _callbackDispatcherTarget; + + @SuppressWarnings("rawtypes") + private RpcCallbackDispatcher _callbackDispatcher; private RpcProvider _rpcProvider; private long _startTickInMs; @@ -81,16 +82,15 @@ public class RpcClientCallImpl implements RpcClientCall { } @Override - public RpcClientCall setContextParam(String key, Object param) { - assert(key != null); - _contextParams.put(key, param); + public RpcClientCall setContext(Object param) { + _contextObject = param; return this; } @SuppressWarnings("unchecked") @Override - public T getContextParam(String key) { - return (T)_contextParams.get(key); + public T getContext() { + return (T)_contextObject; } @Override @@ -101,11 +101,10 @@ public class RpcClientCallImpl implements RpcClientCall { } @Override - public RpcClientCall setCallbackDispatcherTarget(Object target) { - _callbackDispatcherTarget = target; + public RpcClientCall setCallbackDispatcher(RpcCallbackDispatcher dispatcher) { + _callbackDispatcher = dispatcher; return this; } - @Override public RpcClientCall setOneway() { @@ -210,8 +209,8 @@ public class RpcClientCallImpl implements RpcClientCall { for(@SuppressWarnings("rawtypes") RpcCallbackListener listener: _callbackListeners) listener.onSuccess(resultObject); } else { - if(_callbackDispatcherTarget != null) - RpcCallbackDispatcher.dispatch(_callbackDispatcherTarget, this); + if(_callbackDispatcher != null) + _callbackDispatcher.dispatch(this); } } @@ -228,8 +227,8 @@ public class RpcClientCallImpl implements RpcClientCall { for(@SuppressWarnings("rawtypes") RpcCallbackListener listener: _callbackListeners) listener.onFailure(e); } else { - if(_callbackDispatcherTarget != null) - RpcCallbackDispatcher.dispatch(_callbackDispatcherTarget, this); + if(_callbackDispatcher != null) + _callbackDispatcher.dispatch(this); } } } diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/ClientOnlyEventDrivenStyle.java b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/ClientOnlyEventDrivenStyle.java index a6c8105c8b0..b9ab85a58b5 100644 --- a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/ClientOnlyEventDrivenStyle.java +++ b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/ClientOnlyEventDrivenStyle.java @@ -18,7 +18,7 @@ */ package org.apache.cloudstack.framework.codestyle; -import org.apache.cloudstack.framework.rpc.RpcCallbackHandler; +import org.apache.cloudstack.framework.rpc.RpcCallbackDispatcher; import org.apache.cloudstack.framework.rpc.RpcClientCall; import org.apache.cloudstack.framework.rpc.RpcException; import org.apache.cloudstack.framework.rpc.RpcIOException; @@ -30,17 +30,16 @@ public class ClientOnlyEventDrivenStyle { public void AsyncCallRpcService() { String cmd = new String(); + RpcCallbackDispatcher callbackDispatcher = RpcCallbackDispatcher.create(this); + callbackDispatcher.setCallback(callbackDispatcher.getTarget().OnAsyncCallRpcServiceCallback(null, null)); _rpcProvider.newCall("host-2").setCommand("TestCommand").setCommandArg(cmd).setTimeout(10000) - .setCallbackDispatcherTarget(this) - .setContextParam("origCmd", cmd) // save context object for callback handler + .setCallbackDispatcher(callbackDispatcher) + .setContext("Context Object") // save context object for callback handler .apply(); } - @RpcCallbackHandler(command="TestCommand") - public void OnAsyncCallRpcServiceCallback(RpcClientCall call) { + public Void OnAsyncCallRpcServiceCallback(RpcClientCall call, String context) { try { - String origCmd = call.getContextParam("origCmd"); // restore calling context at callback handler - String answer = call.get(); } catch(RpcTimeoutException e) { @@ -49,5 +48,7 @@ public class ClientOnlyEventDrivenStyle { } catch(RpcException e) { } + + return null; } }