You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by wi...@apache.org on 2013/03/30 10:59:15 UTC
[46/52] [abbrv] git commit: updated refs/heads/qemu-img to 44197a0
CLOUDSTACK-1795: implement custom AOP to fully support legacy CloudStack AOP semantcis
Signed-off-by: Chip Childers <ch...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3ab744d1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3ab744d1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3ab744d1
Branch: refs/heads/qemu-img
Commit: 3ab744d1009ded8b937edf102d881df3e8208691
Parents: 95011d6
Author: Kelven Yang <ke...@gmail.com>
Authored: Wed Mar 27 13:06:49 2013 +0000
Committer: Kelven Yang <ke...@gmail.com>
Committed: Fri Mar 29 11:12:36 2013 -0700
----------------------------------------------------------------------
client/tomcatconf/applicationContext.xml.in | 27 +--
server/src/com/cloud/api/ApiDispatcher.java | 5 +-
server/src/com/cloud/api/ApiServer.java | 39 ++--
.../src/com/cloud/cluster/ClusterManagerImpl.java | 4 +-
.../com/cloud/event/ActionEventInterceptor.java | 52 +----
.../ExternalLoadBalancerDeviceManagerImpl.java | 2 +-
.../src/com/cloud/network/NetworkManagerImpl.java | 16 +-
server/src/com/cloud/network/NetworkModelImpl.java | 6 +-
server/src/com/cloud/server/StatsCollector.java | 3 +-
.../src/com/cloud/utils/component/AdapterBase.java | 4 +-
.../cloud/utils/component/ComponentContext.java | 32 +++-
.../ComponentInstantiationPostProcessor.java | 152 +++++++++++++++
.../component/ComponentMethodInterceptable.java | 24 +++
.../component/ComponentMethodInterceptor.java | 27 +++
.../utils/component/ComponentNamingPolicy.java | 63 ++++++
.../src/com/cloud/utils/component/ManagerBase.java | 2 +-
utils/src/com/cloud/utils/db/GenericDaoBase.java | 29 +---
.../cloud/utils/db/TransactionContextBuilder.java | 70 ++-----
.../utils/log/CglibThrowableRendererTest.java | 2 +-
utils/test/resources/testContext.xml | 20 +--
20 files changed, 383 insertions(+), 196 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 3c93b8a..6bab4fd 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -35,27 +35,18 @@
<!--
@DB support
-->
- <aop:config>
- <aop:aspect id="dbContextBuilder" ref="transactionContextBuilder">
- <aop:pointcut id="captureAnyMethod"
- expression="execution(* *(..))"
- />
-
- <aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod"/>
- </aop:aspect>
-
- <aop:aspect id="actionEventInterceptorAspect" ref="actionEventInterceptor">
- <aop:pointcut id="captureEventMethod"
- expression="execution(* *(..)) and @annotation(com.cloud.event.ActionEvent)"
- />
-
- <aop:around pointcut-ref="captureEventMethod" method="AroundAnyMethod"/>
- </aop:aspect>
- </aop:config>
-
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
<bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
+ <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
+ <property name="Interceptors">
+ <list>
+ <ref bean="transactionContextBuilder" />
+ <ref bean="actionEventInterceptor" />
+ </list>
+ </property>
+ </bean>
+
<!--
RPC/Async/EventBus
-->
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index f7a3236..925d90a 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -138,8 +138,7 @@ public class ApiDispatcher {
UserContext ctx = UserContext.current();
ctx.setAccountId(cmd.getEntityOwnerId());
- BaseCmd realCmdObj = ComponentContext.getTargetObject(cmd);
- if (realCmdObj instanceof BaseAsyncCmd) {
+ if (cmd instanceof BaseAsyncCmd) {
BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmd;
String startEventId = params.get("ctxStartEventId");
@@ -171,8 +170,6 @@ public class ApiDispatcher {
Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
Map<String, Object> unpackedParams = cmd.unpackParams(params);
- cmd = ComponentContext.getTargetObject(cmd);
-
if (cmd instanceof BaseListCmd) {
Object pageSizeObj = unpackedParams.get(ApiConstants.PAGE_SIZE);
Long pageSize = null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 3c08575..d842819 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -388,16 +388,15 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
Long callerUserId = ctx.getCallerUserId();
Account caller = ctx.getCaller();
- BaseCmd realCmdObj = ComponentContext.getTargetObject(cmdObj);
// Queue command based on Cmd super class:
// BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
// BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd.
// BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
- if (realCmdObj instanceof BaseAsyncCmd) {
+ if (cmdObj instanceof BaseAsyncCmd) {
Long objectId = null;
String objectUuid = null;
- if (realCmdObj instanceof BaseAsyncCreateCmd) {
+ if (cmdObj instanceof BaseAsyncCreateCmd) {
BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj;
_dispatcher.dispatchCreateCmd(createCmd, params);
objectId = createCmd.getEntityId();
@@ -433,7 +432,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
ctx.setAccountId(asyncCmd.getEntityOwnerId());
Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
- AsyncJobVO job = new AsyncJobVO(callerUserId, caller.getId(), realCmdObj.getClass().getName(),
+ AsyncJobVO job = new AsyncJobVO(callerUserId, caller.getId(), cmdObj.getClass().getName(),
ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType());
long jobId = _asyncMgr.submitAsyncJob(job);
@@ -457,22 +456,22 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
// if the command is of the listXXXCommand, we will need to also return the
// the job id and status if possible
// For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views.
- if (realCmdObj instanceof BaseListCmd && !(realCmdObj instanceof ListVMsCmd) && !(realCmdObj instanceof ListRoutersCmd)
- && !(realCmdObj instanceof ListSecurityGroupsCmd)
- && !(realCmdObj instanceof ListTagsCmd)
- && !(realCmdObj instanceof ListEventsCmd)
- && !(realCmdObj instanceof ListVMGroupsCmd)
- && !(realCmdObj instanceof ListProjectsCmd)
- && !(realCmdObj instanceof ListProjectAccountsCmd)
- && !(realCmdObj instanceof ListProjectInvitationsCmd)
- && !(realCmdObj instanceof ListHostsCmd)
- && !(realCmdObj instanceof ListVolumesCmd)
- && !(realCmdObj instanceof ListUsersCmd)
- && !(realCmdObj instanceof ListAccountsCmd)
- && !(realCmdObj instanceof ListStoragePoolsCmd)
- && !(realCmdObj instanceof ListDiskOfferingsCmd)
- && !(realCmdObj instanceof ListServiceOfferingsCmd)
- && !(realCmdObj instanceof ListZonesByCmd)
+ if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd)
+ && !(cmdObj instanceof ListSecurityGroupsCmd)
+ && !(cmdObj instanceof ListTagsCmd)
+ && !(cmdObj instanceof ListEventsCmd)
+ && !(cmdObj instanceof ListVMGroupsCmd)
+ && !(cmdObj instanceof ListProjectsCmd)
+ && !(cmdObj instanceof ListProjectAccountsCmd)
+ && !(cmdObj instanceof ListProjectInvitationsCmd)
+ && !(cmdObj instanceof ListHostsCmd)
+ && !(cmdObj instanceof ListVolumesCmd)
+ && !(cmdObj instanceof ListUsersCmd)
+ && !(cmdObj instanceof ListAccountsCmd)
+ && !(cmdObj instanceof ListStoragePoolsCmd)
+ && !(cmdObj instanceof ListDiskOfferingsCmd)
+ && !(cmdObj instanceof ListServiceOfferingsCmd)
+ && !(cmdObj instanceof ListZonesByCmd)
) {
buildAsyncListResponse((BaseListCmd) cmdObj, caller);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/cluster/ClusterManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/cluster/ClusterManagerImpl.java b/server/src/com/cloud/cluster/ClusterManagerImpl.java
index 27e0e03..118de41 100755
--- a/server/src/com/cloud/cluster/ClusterManagerImpl.java
+++ b/server/src/com/cloud/cluster/ClusterManagerImpl.java
@@ -365,11 +365,11 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager {
try {
// schedule a scan task immediately
- if (ComponentContext.getTargetObject(_agentMgr) instanceof ClusteredAgentManagerImpl) {
+ if (_agentMgr instanceof ClusteredAgentManagerImpl) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received notification as part of addHost command to start a host scan task");
}
- ClusteredAgentManagerImpl clusteredAgentMgr = (ClusteredAgentManagerImpl)ComponentContext.getTargetObject(_agentMgr);
+ ClusteredAgentManagerImpl clusteredAgentMgr = (ClusteredAgentManagerImpl)_agentMgr;
clusteredAgentMgr.scheduleHostScanTask();
}
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/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 a6c2565..01eefcd 100644
--- a/server/src/com/cloud/event/ActionEventInterceptor.java
+++ b/server/src/com/cloud/event/ActionEventInterceptor.java
@@ -16,55 +16,22 @@
// under the License.
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;
+import com.cloud.utils.component.ComponentMethodInterceptor;
-public class ActionEventInterceptor {
+public class ActionEventInterceptor implements ComponentMethodInterceptor {
private static final Logger s_logger = Logger.getLogger(ActionEventInterceptor.class);
public ActionEventInterceptor() {
}
- public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable {
- MethodSignature methodSignature = (MethodSignature)call.getSignature();
-
- // 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 {
- ret = call.proceed();
- } catch (Throwable e) {
- success = false;
- interceptException(targetMethod, event);
- throw e;
- } finally {
- if(success){
- interceptComplete(targetMethod, event);
- }
- }
- return ret;
- } else {
- s_logger.error("Unable to find the proxied method behind. Method: " + methodSignature.getMethod().getName());
- }
- return call.proceed();
- }
-
- public EventVO interceptStart(AnnotatedElement element) {
+ @Override
+ public Object interceptStart(Method method, Object target) {
EventVO event = null;
- Method method = (Method)element;
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
if (actionEvent != null) {
boolean async = actionEvent.async();
@@ -83,8 +50,8 @@ public class ActionEventInterceptor {
return event;
}
- public void interceptComplete(AnnotatedElement element, EventVO event) {
- Method method = (Method)element;
+ @Override
+ public void interceptComplete(Method method, Object target, Object event) {
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
if (actionEvent != null) {
UserContext ctx = UserContext.current();
@@ -105,8 +72,8 @@ public class ActionEventInterceptor {
}
}
- public void interceptException(AnnotatedElement element, EventVO event) {
- Method method = (Method)element;
+ @Override
+ public void interceptException(Method method, Object target, Object event) {
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
if (actionEvent != null) {
UserContext ctx = UserContext.current();
@@ -126,7 +93,8 @@ public class ActionEventInterceptor {
}
}
- private boolean needToIntercept(Method method) {
+ @Override
+ public boolean needToIntercept(Method method) {
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
if (actionEvent != null) {
return true;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index cafe95a..4853256 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -1113,7 +1113,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
}
NetworkElement element = _networkModel.getElementImplementingProvider(providers.get(0).getName());
- if (!(ComponentContext.getTargetObject(element) instanceof IpDeployer)) {
+ if (!(element instanceof IpDeployer)) {
s_logger.error("The firewall provider for network " + network.getName() + " don't have ability to deploy IP address!");
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index a4eac36..42544ae 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -611,10 +611,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
}
IpDeployer deployer = null;
NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
- if (!(ComponentContext.getTargetObject(element) instanceof IpDeployingRequester)) {
+ if (!(element instanceof IpDeployingRequester)) {
throw new CloudRuntimeException("Element " + element + " is not a IpDeployingRequester!");
}
- deployer = ((IpDeployingRequester)ComponentContext.getTargetObject(element)).getIpDeployer(network);
+ deployer = ((IpDeployingRequester)element).getIpDeployer(network);
if (deployer == null) {
throw new CloudRuntimeException("Fail to get ip deployer for element: " + element);
}
@@ -1594,13 +1594,13 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
if (vmProfile.getType() == Type.User && element.getProvider() != null) {
if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp) &&
_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) &&
- (ComponentContext.getTargetObject(element) instanceof DhcpServiceProvider)) {
+ element instanceof DhcpServiceProvider) {
DhcpServiceProvider sp = (DhcpServiceProvider) element;
sp.addDhcpEntry(network, profile, vmProfile, dest, context);
}
if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.UserData) &&
_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.UserData, element.getProvider()) &&
- (ComponentContext.getTargetObject(element) instanceof UserDataServiceProvider)) {
+ element instanceof UserDataServiceProvider) {
UserDataServiceProvider sp = (UserDataServiceProvider) element;
sp.addPasswordAndUserdata(network, profile, vmProfile, dest, context);
}
@@ -3678,15 +3678,15 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
@Override
public StaticNatServiceProvider getStaticNatProviderForNetwork(Network network) {
NetworkElement element = getElementForServiceInNetwork(network, Service.StaticNat);
- assert ComponentContext.getTargetObject(element) instanceof StaticNatServiceProvider;
- return (StaticNatServiceProvider)ComponentContext.getTargetObject(element);
+ assert element instanceof StaticNatServiceProvider;
+ return (StaticNatServiceProvider)element;
}
@Override
public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network) {
NetworkElement element = getElementForServiceInNetwork(network, Service.Lb);
- assert ComponentContext.getTargetObject(element) instanceof LoadBalancingServiceProvider;
- return ( LoadBalancingServiceProvider)ComponentContext.getTargetObject(element);
+ assert element instanceof LoadBalancingServiceProvider;
+ return (LoadBalancingServiceProvider)element;
}
@Override
public boolean isNetworkInlineMode(Network network) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 788e031..e7bdbca 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -404,9 +404,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
Network network = _networksDao.findById(networkId);
NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
NetworkElement newElement = getElementImplementingProvider(newProvider.getName());
- if (ComponentContext.getTargetObject(oldElement) instanceof IpDeployingRequester && ComponentContext.getTargetObject(newElement) instanceof IpDeployingRequester) {
- IpDeployer oldIpDeployer = ((IpDeployingRequester)ComponentContext.getTargetObject(oldElement)).getIpDeployer(network);
- IpDeployer newIpDeployer = ((IpDeployingRequester)ComponentContext.getTargetObject(newElement)).getIpDeployer(network);
+ if (oldElement instanceof IpDeployingRequester && newElement instanceof IpDeployingRequester) {
+ IpDeployer oldIpDeployer = ((IpDeployingRequester)oldElement).getIpDeployer(network);
+ IpDeployer newIpDeployer = ((IpDeployingRequester)newElement).getIpDeployer(network);
if (!oldIpDeployer.getProvider().getName().equals(newIpDeployer.getProvider().getName())) {
throw new InvalidParameterException("There would be multiple providers for IP " + publicIp.getAddress() + "!");
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/server/src/com/cloud/server/StatsCollector.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index 7dcf091..b1f4a57 100755
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -65,6 +65,7 @@ import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ComponentMethodInterceptable;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.UserVmManager;
@@ -77,7 +78,7 @@ import com.cloud.vm.dao.UserVmDao;
*
*/
@Component
-public class StatsCollector {
+public class StatsCollector implements ComponentMethodInterceptable {
public static final Logger s_logger = Logger.getLogger(StatsCollector.class.getName());
private static StatsCollector s_instance = null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/AdapterBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/AdapterBase.java b/utils/src/com/cloud/utils/component/AdapterBase.java
index ea5e961..8353cee 100644
--- a/utils/src/com/cloud/utils/component/AdapterBase.java
+++ b/utils/src/com/cloud/utils/component/AdapterBase.java
@@ -19,7 +19,7 @@ package com.cloud.utils.component;
import java.util.List;
// Typical Adapter implementation.
-public class AdapterBase extends ComponentLifecycleBase implements Adapter {
+public class AdapterBase extends ComponentLifecycleBase implements Adapter, ComponentMethodInterceptable {
public AdapterBase() {
// set default run level for adapter components
@@ -29,7 +29,7 @@ public class AdapterBase extends ComponentLifecycleBase implements Adapter {
public static <T extends Adapter> T getAdapterByName(List<T> adapters, String name) {
for(T adapter : adapters) {
if(adapter.getName() != null && adapter.getName().equalsIgnoreCase(name))
- return ComponentContext.getTargetObject(adapter);
+ return adapter;
}
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ComponentContext.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentContext.java b/utils/src/com/cloud/utils/component/ComponentContext.java
index ca7ad5c..d11d354 100644
--- a/utils/src/com/cloud/utils/component/ComponentContext.java
+++ b/utils/src/com/cloud/utils/component/ComponentContext.java
@@ -59,16 +59,18 @@ public class ComponentContext implements ApplicationContextAware {
public static ApplicationContext getApplicationContext() {
return s_appContext;
- }
-
+ }
+
public static void initComponentsLifeCycle() {
- // Run the SystemIntegrityCheckers first
- Map<String, SystemIntegrityChecker> integrityCheckers = getApplicationContext().getBeansOfType(SystemIntegrityChecker.class);
- for (Entry<String,SystemIntegrityChecker> entry : integrityCheckers.entrySet() ){
- s_logger.info ("Running SystemIntegrityChecker " + entry.getKey());
- entry.getValue().check();
- }
-
+ AutowireCapableBeanFactory beanFactory = s_appContext.getAutowireCapableBeanFactory();
+
+ Map<String, ComponentMethodInterceptable> interceptableComponents = getApplicationContext().getBeansOfType(
+ ComponentMethodInterceptable.class);
+ for(Map.Entry<String, ComponentMethodInterceptable> entry : interceptableComponents.entrySet()) {
+ Object bean = getTargetObject(entry.getValue());
+ beanFactory.configureBean(bean, entry.getKey());
+ }
+
Map<String, ComponentLifecycle> lifecyleComponents = getApplicationContext().getBeansOfType(ComponentLifecycle.class);
Map[] classifiedComponents = new Map[ComponentLifecycle.MAX_RUN_LEVELS];
@@ -103,6 +105,18 @@ public class ComponentContext implements ApplicationContextAware {
avoidMap.put(implClassName, implClassName);
}
}
+
+ // Run the SystemIntegrityCheckers first
+ Map<String, SystemIntegrityChecker> integrityCheckers = getApplicationContext().getBeansOfType(SystemIntegrityChecker.class);
+ for (Entry<String,SystemIntegrityChecker> entry : integrityCheckers.entrySet() ){
+ s_logger.info ("Running SystemIntegrityChecker " + entry.getKey());
+ try {
+ entry.getValue().check();
+ } catch(Throwable e) {
+ s_logger.error("System integrity check failed. Refuse to startup");
+ System.exit(1);
+ }
+ }
// starting phase
avoidMap.clear();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ComponentInstantiationPostProcessor.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentInstantiationPostProcessor.java b/utils/src/com/cloud/utils/component/ComponentInstantiationPostProcessor.java
new file mode 100644
index 0000000..cb64975
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentInstantiationPostProcessor.java
@@ -0,0 +1,152 @@
+// 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.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+import net.sf.cglib.proxy.NoOp;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValues;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
+
+import com.cloud.utils.Pair;
+
+public class ComponentInstantiationPostProcessor implements InstantiationAwareBeanPostProcessor {
+ private static final Logger s_logger = Logger.getLogger(ComponentInstantiationPostProcessor.class);
+
+ private List<ComponentMethodInterceptor> _interceptors = new ArrayList<ComponentMethodInterceptor>();
+ private Callback[] _callbacks;
+ private CallbackFilter _callbackFilter;
+
+ public ComponentInstantiationPostProcessor() {
+ _callbacks = new Callback[2];
+ _callbacks[0] = NoOp.INSTANCE;
+ _callbacks[1] = new InterceptorDispatcher();
+
+ _callbackFilter = new InterceptorFilter();
+ }
+
+ public List<ComponentMethodInterceptor> getInterceptors() {
+ return _interceptors;
+ }
+
+ public void setInterceptors(List<ComponentMethodInterceptor> interceptors) {
+ _interceptors = interceptors;
+ }
+
+ private Callback[] getCallbacks() {
+ return _callbacks;
+ }
+
+ private CallbackFilter getCallbackFilter() {
+ return _callbackFilter;
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName)
+ throws BeansException {
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName)
+ throws BeansException {
+ return bean;
+ }
+
+ @Override
+ public Object postProcessBeforeInstantiation(Class<?> beanClass,
+ String beanName) throws BeansException {
+ if(_interceptors != null && _interceptors.size() > 0) {
+ if(ComponentMethodInterceptable.class.isAssignableFrom(beanClass)) {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(beanClass);
+ enhancer.setCallbacks(getCallbacks());
+ enhancer.setCallbackFilter(getCallbackFilter());
+ enhancer.setNamingPolicy(ComponentNamingPolicy.INSTANCE);
+
+ Object bean = enhancer.create();
+ return bean;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean postProcessAfterInstantiation(Object bean, String beanName)
+ throws BeansException {
+ return true;
+ }
+
+ @Override
+ public PropertyValues postProcessPropertyValues(PropertyValues pvs,
+ PropertyDescriptor[] pds, Object bean, String beanName)
+ throws BeansException {
+ return pvs;
+ }
+
+ protected class InterceptorDispatcher implements MethodInterceptor {
+ @Override
+ public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+ ArrayList<Pair<ComponentMethodInterceptor, Object>> interceptors = new ArrayList<Pair<ComponentMethodInterceptor, Object>>();
+
+ for (ComponentMethodInterceptor interceptor : getInterceptors()) {
+ if (interceptor.needToIntercept(method)) {
+ Object objReturnedInInterceptStart = interceptor.interceptStart(method, target);
+ interceptors.add(new Pair<ComponentMethodInterceptor, Object>(interceptor, objReturnedInInterceptStart));
+ }
+ }
+ boolean success = false;
+ try {
+ Object obj = methodProxy.invokeSuper(target, args);
+ success = true;
+ return obj;
+ } finally {
+ for (Pair<ComponentMethodInterceptor, Object> interceptor : interceptors) {
+ if (success) {
+ interceptor.first().interceptComplete(method, target, interceptor.second());
+ } else {
+ interceptor.first().interceptException(method, target, interceptor.second());
+ }
+ }
+ }
+ }
+ }
+
+ protected class InterceptorFilter implements CallbackFilter {
+ @Override
+ public int accept(Method method) {
+ for(ComponentMethodInterceptor interceptor : getInterceptors()) {
+
+ if (interceptor.needToIntercept(method)) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ComponentMethodInterceptable.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentMethodInterceptable.java b/utils/src/com/cloud/utils/component/ComponentMethodInterceptable.java
new file mode 100644
index 0000000..5a95c43
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentMethodInterceptable.java
@@ -0,0 +1,24 @@
+// 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;
+
+/**
+ * Marker interface to work with CGLIB based CloudStack legacy AOP
+ *
+ */
+public interface ComponentMethodInterceptable {
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ComponentMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentMethodInterceptor.java b/utils/src/com/cloud/utils/component/ComponentMethodInterceptor.java
new file mode 100644
index 0000000..39a81d0
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentMethodInterceptor.java
@@ -0,0 +1,27 @@
+// 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.reflect.Method;
+
+public interface ComponentMethodInterceptor {
+ boolean needToIntercept(Method method);
+
+ Object interceptStart(Method method, Object target);
+ void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart);
+ void interceptException(Method method, Object target, Object objReturnedInInterceptStart);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ComponentNamingPolicy.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ComponentNamingPolicy.java b/utils/src/com/cloud/utils/component/ComponentNamingPolicy.java
new file mode 100644
index 0000000..5659a48
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentNamingPolicy.java
@@ -0,0 +1,63 @@
+// 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 net.sf.cglib.core.NamingPolicy;
+import net.sf.cglib.core.Predicate;
+
+/**
+ * Copied/Modified from Spring source
+ *
+ */
+public class ComponentNamingPolicy implements NamingPolicy {
+
+ public static final ComponentNamingPolicy INSTANCE = new ComponentNamingPolicy();
+
+ public String getClassName(String prefix, String source, Object key, Predicate names) {
+ if (prefix == null) {
+ prefix = "net.sf.cglib.empty.Object";
+ } else if (prefix.startsWith("java")) {
+ prefix = "_" + prefix;
+ }
+ String base =
+ prefix + "_" +
+ source.substring(source.lastIndexOf('.') + 1) +
+ getTag() + "_" +
+ Integer.toHexString(key.hashCode());
+ String attempt = base;
+ int index = 2;
+ while (names.evaluate(attempt))
+ attempt = base + "_" + index++;
+ return attempt;
+ }
+
+ /**
+ * Returns a string which is incorporated into every generated class name.
+ * By default returns "ByCloudStack"
+ */
+ protected String getTag() {
+ return "ByCloudStack";
+ }
+
+ public int hashCode() {
+ return getTag().hashCode();
+ }
+
+ public boolean equals(Object o) {
+ return (o instanceof ComponentNamingPolicy) && ((ComponentNamingPolicy) o).getTag().equals(getTag());
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/component/ManagerBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/component/ManagerBase.java b/utils/src/com/cloud/utils/component/ManagerBase.java
index 529ef62..1908f4e 100644
--- a/utils/src/com/cloud/utils/component/ManagerBase.java
+++ b/utils/src/com/cloud/utils/component/ManagerBase.java
@@ -16,7 +16,7 @@
// under the License.
package com.cloud.utils.component;
-public class ManagerBase extends ComponentLifecycleBase {
+public class ManagerBase extends ComponentLifecycleBase implements ComponentMethodInterceptable {
public ManagerBase() {
// set default run level for manager components
setRunLevel(ComponentLifecycle.RUN_LEVEL_COMPONENT_BOOTSTRAP);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java
index afb1247..f0fc700 100755
--- a/utils/src/com/cloud/utils/db/GenericDaoBase.java
+++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java
@@ -71,6 +71,7 @@ import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ComponentLifecycle;
import com.cloud.utils.component.ComponentLifecycleBase;
+import com.cloud.utils.component.ComponentMethodInterceptable;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.db.SearchCriteria.SelectType;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -114,7 +115,7 @@ import edu.emory.mathcs.backport.java.util.Collections;
*
**/
@DB
-public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID> {
+public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID>, ComponentMethodInterceptable {
private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
@@ -193,15 +194,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
( (Class<?>)((Class<?>)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0];
}
-/*
- s_daoMaps.put(_entityBeanType, ComponentContext.getComponent(this.getClass()));
+ s_daoMaps.put(_entityBeanType, this);
Class<?>[] interphaces = _entityBeanType.getInterfaces();
if (interphaces != null) {
for (Class<?> interphace : interphaces) {
- s_daoMaps.put(interphace, ComponentContext.getComponent(this.getClass()));
+ s_daoMaps.put(interphace, this);
}
}
-*/
+
_table = DbUtil.getTableName(_entityBeanType);
final SqlGenerator generator = new SqlGenerator(_entityBeanType);
@@ -1750,25 +1750,6 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
_name = name;
- Class<?> daoInterface = null;
- for(Class<?> intf : this.getClass().getInterfaces()) {
- if(GenericDao.class.isAssignableFrom(intf)) {
- daoInterface = intf;
- break;
- }
- }
-
- if(daoInterface != null) {
- s_logger.info("Register dao interface in GenericDaoBase entity-DAO map. " + daoInterface.getName());
- s_daoMaps.put(_entityBeanType, (GenericDao<?, ? extends Serializable>) ComponentContext.getComponent(daoInterface));
- Class<?>[] interphaces = _entityBeanType.getInterfaces();
- if (interphaces != null) {
- for (Class<?> interphace : interphaces) {
- s_daoMaps.put(interphace, (GenericDao<?, ? extends Serializable>) ComponentContext.getComponent(daoInterface));
- }
- }
- }
-
final String value = (String)params.get("lock.timeout");
_timeoutSeconds = NumbersUtil.parseInt(value, 300);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/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 7ca33ab..40fcbbf 100644
--- a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
+++ b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
@@ -18,65 +18,20 @@ package com.cloud.utils.db;
import java.lang.reflect.Method;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.log4j.Logger;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.reflect.MethodSignature;
+import com.cloud.utils.component.ComponentMethodInterceptor;
-import com.cloud.utils.component.ComponentMethodProxyCache;
-
-public class TransactionContextBuilder implements MethodInterceptor {
- private static final Logger s_logger = Logger.getLogger(TransactionContextBuilder.class);
+public class TransactionContextBuilder implements ComponentMethodInterceptor {
public TransactionContextBuilder() {
}
- public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable {
- MethodSignature methodSignature = (MethodSignature)call.getSignature();
- Method targetMethod = methodSignature.getMethod();
- if(needToIntercept(targetMethod, call.getTarget())) {
- Transaction txn = Transaction.open(call.getSignature().getName());
- Object ret = null;
- try {
- ret = call.proceed();
- } finally {
- txn.close();
- }
- return ret;
- }
- return call.proceed();
- }
-
@Override
- public Object invoke(MethodInvocation method) throws Throwable {
- Method targetMethod = method.getMethod();
-
- if(needToIntercept(targetMethod, method.getThis())) {
- Transaction txn = Transaction.open(targetMethod.getName());
- Object ret = null;
- try {
- ret = method.proceed();
- } finally {
- txn.close();
- }
- return ret;
- }
- return method.proceed();
- }
-
- private boolean needToIntercept(Method method, Object target) {
+ public boolean needToIntercept(Method method) {
DB db = method.getAnnotation(DB.class);
if (db != null) {
return true;
}
Class<?> clazz = method.getDeclaringClass();
- if(clazz.isInterface()) {
- clazz = target.getClass();
- Method targetMethod = ComponentMethodProxyCache.getTargetMethod(method, target);
- if(targetMethod != null && targetMethod.getAnnotation(DB.class) != null)
- return true;
- }
do {
db = clazz.getAnnotation(DB.class);
@@ -88,4 +43,23 @@ public class TransactionContextBuilder implements MethodInterceptor {
return false;
}
+
+ @Override
+ public Object interceptStart(Method method, Object target) {
+ return Transaction.open(method.getName());
+ }
+
+ @Override
+ public void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart) {
+ Transaction txn = (Transaction)objReturnedInInterceptStart;
+ if(txn != null)
+ txn.close();
+ }
+
+ @Override
+ public void interceptException(Method method, Object target, Object objReturnedInInterceptStart) {
+ Transaction txn = (Transaction)objReturnedInInterceptStart;
+ if(txn != null)
+ txn.close();
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java b/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
index ae50f5b..5e3571a 100644
--- a/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
+++ b/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
@@ -80,7 +80,7 @@ public class CglibThrowableRendererTest extends TestCase {
Writer w = new CharArrayWriter();
Logger alt = getAlternateLogger(w, null);
- TestClass test = ComponentContext.inject(TestClass.class);
+ TestClass test = new TestClass();
try {
test.exception();
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ab744d1/utils/test/resources/testContext.xml
----------------------------------------------------------------------
diff --git a/utils/test/resources/testContext.xml b/utils/test/resources/testContext.xml
index 26cdaae..5cccfcd 100644
--- a/utils/test/resources/testContext.xml
+++ b/utils/test/resources/testContext.xml
@@ -33,22 +33,18 @@
<context:annotation-config />
<context:component-scan base-package="org.apache.cloudstack, com.cloud" />
-
+
<!--
@DB support
-->
- <aop:config proxy-target-class="true">
- <aop:aspect id="dbContextBuilder" ref="transactionContextBuilder">
- <aop:pointcut id="captureAnyMethod"
- expression="execution(* *(..))"
- />
-
- <aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod"/>
- </aop:aspect>
-
- </aop:config>
-
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
+ <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
+ <property name="Interceptors">
+ <list>
+ <ref bean="transactionContextBuilder" />
+ </list>
+ </property>
+ </bean>
</beans>