Updated Branches:
  refs/heads/master d9b85e397 -> fb94b7221

CLOUDSTACK-1568,CLOUDSTACK-1664: Fix ActionEvent interception and optimize @DB 
lookup with caching


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/fb94b722
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/fb94b722
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/fb94b722

Branch: refs/heads/master
Commit: fb94b72213bf96f2878b90260067f61629c6a956
Parents: d9b85e3
Author: Kelven Yang <kelv...@gmail.com>
Authored: Mon Mar 18 18:05:09 2013 -0700
Committer: Kelven Yang <kelv...@gmail.com>
Committed: Mon Mar 18 18:07:52 2013 -0700

----------------------------------------------------------------------
 .../com/cloud/event/ActionEventInterceptor.java    |   15 ++-
 .../ConsoleProxyHttpHandlerHelper.java             |   14 ++-
 .../utils/component/ComponentMethodProxyCache.java |   90 +++++++++++++++
 .../utils/component/SpringComponentScanUtils.java  |    1 -
 .../cloud/utils/db/TransactionContextBuilder.java  |   14 +--
 5 files changed, 119 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fb94b722/server/src/com/cloud/event/ActionEventInterceptor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/event/ActionEventInterceptor.java 
b/server/src/com/cloud/event/ActionEventInterceptor.java
index fb89498..a6c2565 100644
--- a/server/src/com/cloud/event/ActionEventInterceptor.java
+++ b/server/src/com/cloud/event/ActionEventInterceptor.java
@@ -19,22 +19,29 @@ package com.cloud.event;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
 
+import org.apache.log4j.Logger;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.reflect.MethodSignature;
 
 import com.cloud.user.UserContext;
+import com.cloud.utils.component.ComponentMethodProxyCache;
 
 public class ActionEventInterceptor {
+       private static final Logger s_logger = 
Logger.getLogger(ActionEventInterceptor.class);
 
        public ActionEventInterceptor() {
        }
 
        public Object AroundAnyMethod(ProceedingJoinPoint call) throws 
Throwable {
                MethodSignature methodSignature = 
(MethodSignature)call.getSignature();
-        Method targetMethod = methodSignature.getMethod();     
-        if(needToIntercept(targetMethod)) {
+               
+               // Note: AOP for ActionEvent is triggered annotation, no need 
to check the annotation on method again
+        Method targetMethod = ComponentMethodProxyCache.getTargetMethod(
+               methodSignature.getMethod(), call.getTarget()); 
+        
+        if(targetMethod != null) {
             EventVO event = interceptStart(targetMethod);
-               
+                               
             boolean success = true;
                        Object ret = null;
                        try {
@@ -49,6 +56,8 @@ public class ActionEventInterceptor {
                    }
                        }
                        return ret;
+        } else {
+               s_logger.error("Unable to find the proxied method behind. 
Method: " + methodSignature.getMethod().getName());
         }
         return call.proceed();
        }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fb94b722/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
----------------------------------------------------------------------
diff --git 
a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
 
b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
index 6815b0d..297e711 100644
--- 
a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
+++ 
b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
@@ -53,7 +53,7 @@ public class ConsoleProxyHttpHandlerHelper {
             ConsoleProxyClientParam param = 
encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token"));
 
             // make sure we get information from token only
-            map.clear();
+            guardUserInput(map);
             if(param != null) {
                 if(param.getClientHostAddress() != null)
                     map.put("host", param.getClientHostAddress());
@@ -72,9 +72,19 @@ public class ConsoleProxyHttpHandlerHelper {
             }
         } else {
                // we no longer accept information from parameter other than 
token 
-               map.clear();
+               guardUserInput(map);
         }
         
         return map;
     }
+    
+    private static void guardUserInput(Map<String, String> map) {
+       map.remove("host");
+       map.remove("port");
+       map.remove("tag");
+       map.remove("sid");
+       map.remove("consoleurl");
+       map.remove("sessionref");
+               map.remove("ticket");
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fb94b722/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java 
b/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java
new file mode 100644
index 0000000..ea3b685
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java
@@ -0,0 +1,90 @@
+// 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
+// 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.cloud.utils.component;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.WeakHashMap;
+
+public class ComponentMethodProxyCache {
+
+       private static WeakHashMap<TargetKey, WeakReference<Method>> s_cache = 
new WeakHashMap<TargetKey, WeakReference<Method>>();
+       
+       public ComponentMethodProxyCache() {
+       }
+       
+       public static Method getTargetMethod(Method method, Object target) {
+               synchronized(s_cache) {
+                       WeakReference<Method> targetMethod = s_cache.get(new 
TargetKey(method, target));
+                       if(targetMethod != null && targetMethod.get() != null)
+                               return targetMethod.get();
+
+               Class<?> clazz = target.getClass();
+               for(Method m : clazz.getMethods()) {
+                       if(isMethodMatched(method, m)) {
+                               s_cache.put(new TargetKey(method, target), new 
WeakReference<Method>(m));
+                               return m;
+                       }
+               }
+                       
+               return method;
+               }
+       }
+       
+       private static boolean isMethodMatched(Method m1, Method m2) {
+               if(!m1.getName().equals(m2.getName()))
+                       return false;
+               
+               Class<?>[] params1 = m1.getParameterTypes();
+               Class<?>[] params2 = m2.getParameterTypes();
+               
+               if(params1.length != params2.length)
+                       return false;
+               
+               for(int i = 0; i < params1.length; i++) {
+                       if(!params1[i].isAssignableFrom(params2[i]))
+                               return false;
+               }
+               
+               return true;
+       }
+       
+       public static class TargetKey {
+               Method _method;
+               Object _target;
+               
+               public TargetKey(Method method, Object target) {
+                       _method = method;
+                       _target = target;
+               }
+               
+               @Override
+           public boolean equals(Object obj) {
+                       if(!(obj instanceof TargetKey))
+                               return false;
+                       
+                       // for target object, we just check the reference
+                       return _method.equals(((TargetKey)obj)._method) &&
+                                       _target == ((TargetKey)obj)._target;
+               }
+               
+           public int hashCode() {
+               return _target.hashCode() ^ _target.hashCode();
+           }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fb94b722/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java 
b/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
index fda11b7..9a85c79 100644
--- a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
+++ b/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
@@ -38,5 +38,4 @@ public class SpringComponentScanUtils {
         }
         return false;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fb94b722/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java 
b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
index e03b25f..7ca33ab 100644
--- a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
+++ b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
@@ -22,9 +22,10 @@ import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 import org.apache.log4j.Logger;
 import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.Signature;
 import org.aspectj.lang.reflect.MethodSignature;
 
+import com.cloud.utils.component.ComponentMethodProxyCache;
+
 public class TransactionContextBuilder implements MethodInterceptor {
        private static final Logger s_logger = 
Logger.getLogger(TransactionContextBuilder.class);
        public TransactionContextBuilder() {
@@ -72,14 +73,9 @@ public class TransactionContextBuilder implements 
MethodInterceptor {
         Class<?> clazz = method.getDeclaringClass();
         if(clazz.isInterface()) {
                clazz = target.getClass();
-               for(Method m : clazz.getMethods()) {
-                       // it is supposed that we need to check against type 
arguments,
-                       // this can be simplified by just checking method name
-                       if(m.getName().equals(method.getName())) {
-                               if(m.getAnnotation(DB.class) != null)
-                                       return true;
-                       }
-               }
+               Method targetMethod = 
ComponentMethodProxyCache.getTargetMethod(method, target);
+                       if(targetMethod != null && 
targetMethod.getAnnotation(DB.class) != null)
+                               return true;
         }
         
         do {

Reply via email to