Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 65823F226 for ; Fri, 29 Mar 2013 23:35:57 +0000 (UTC) Received: (qmail 64954 invoked by uid 500); 29 Mar 2013 23:35:53 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 64875 invoked by uid 500); 29 Mar 2013 23:35:53 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 63947 invoked by uid 99); 29 Mar 2013 23:35:52 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 29 Mar 2013 23:35:52 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 6138F834368; Fri, 29 Mar 2013 23:35:52 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mchen@apache.org To: commits@cloudstack.apache.org Date: Fri, 29 Mar 2013 23:36:21 -0000 Message-Id: <44c46eaeefcd4253ad95eb2d1b75cff8@git.apache.org> In-Reply-To: <074bb17f95a142908f6b8dcf07bc1cd4@git.apache.org> References: <074bb17f95a142908f6b8dcf07bc1cd4@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [31/35] git commit: updated refs/heads/object_store to e64030a CLOUDSTACK-1795: implement custom AOP to fully support legacy CloudStack AOP semantcis Signed-off-by: Chip Childers 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/object_store Commit: 3ab744d1009ded8b937edf102d881df3e8208691 Parents: 95011d6 Author: Kelven Yang Authored: Wed Mar 27 13:06:49 2013 +0000 Committer: Kelven Yang 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 @@ - - - - - - - - - - - - - - + + + + + + + + + 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 entitiesToAccess = new HashMap(); Map 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 getAdapterByName(List 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 integrityCheckers = getApplicationContext().getBeansOfType(SystemIntegrityChecker.class); - for (Entry entry : integrityCheckers.entrySet() ){ - s_logger.info ("Running SystemIntegrityChecker " + entry.getKey()); - entry.getValue().check(); - } - + AutowireCapableBeanFactory beanFactory = s_appContext.getAutowireCapableBeanFactory(); + + Map interceptableComponents = getApplicationContext().getBeansOfType( + ComponentMethodInterceptable.class); + for(Map.Entry entry : interceptableComponents.entrySet()) { + Object bean = getTargetObject(entry.getValue()); + beanFactory.configureBean(bean, entry.getKey()); + } + Map 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 integrityCheckers = getApplicationContext().getBeansOfType(SystemIntegrityChecker.class); + for (Entry 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 _interceptors = new ArrayList(); + 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 getInterceptors() { + return _interceptors; + } + + public void setInterceptors(List 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> interceptors = new ArrayList>(); + + for (ComponentMethodInterceptor interceptor : getInterceptors()) { + if (interceptor.needToIntercept(method)) { + Object objReturnedInInterceptStart = interceptor.interceptStart(method, target); + interceptors.add(new Pair(interceptor, objReturnedInInterceptStart)); + } + } + boolean success = false; + try { + Object obj = methodProxy.invokeSuper(target, args); + success = true; + return obj; + } finally { + for (Pair 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 extends ComponentLifecycleBase implements GenericDao { +public abstract class GenericDaoBase extends ComponentLifecycleBase implements GenericDao, 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 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 extends Compone public boolean configure(final String name, final Map 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) ComponentContext.getComponent(daoInterface)); - Class[] interphaces = _entityBeanType.getInterfaces(); - if (interphaces != null) { - for (Class interphace : interphaces) { - s_daoMaps.put(interphace, (GenericDao) 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 @@ - + - - - - - - - - - + + + + + + +