Add ActionEventIntercepter to implement origianl ActionEventCallback in Spring AOP
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/f304df44 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/f304df44 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/f304df44 Branch: refs/heads/javelin Commit: f304df44dfde40ace5168569202be8b3423f409b Parents: 96bd1d4 Author: Kelven Yang <[email protected]> Authored: Mon Jan 14 17:44:31 2013 -0800 Committer: Kelven Yang <[email protected]> Committed: Mon Jan 14 17:44:31 2013 -0800 ---------------------------------------------------------------------- client/tomcatconf/applicationContext.xml.in | 4 +- server/src/com/cloud/dc/dao/HostPodDaoImpl.java | 3 +- .../com/cloud/event/ActionEventInterceptor.java | 137 +++++++++++++++ server/src/com/cloud/host/dao/HostDaoImpl.java | 10 +- server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java | 5 +- 5 files changed, 150 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f304df44/client/tomcatconf/applicationContext.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 186a168..95913b1 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -33,7 +33,7 @@ <context:annotation-config /> <context:component-scan base-package="org.apache.cloudstack, com.cloud" /> - + <!-- @DB support --> @@ -44,7 +44,7 @@ <aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod"/> </aop:aspect> </aop:config> - + <bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" /> <!-- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f304df44/server/src/com/cloud/dc/dao/HostPodDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java index 4844d02..7b635f0 100644 --- a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java +++ b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java @@ -40,13 +40,14 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDaoImpl; @Component @Local(value={HostPodDao.class}) public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements HostPodDao { private static final Logger s_logger = Logger.getLogger(HostPodDaoImpl.class); - @Inject VMInstanceDaoImpl _vmDao; + @Inject VMInstanceDao _vmDao; protected SearchBuilder<HostPodVO> DataCenterAndNameSearch; protected SearchBuilder<HostPodVO> DataCenterIdSearch; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f304df44/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 new file mode 100644 index 0000000..7bacfa4 --- /dev/null +++ b/server/src/com/cloud/event/ActionEventInterceptor.java @@ -0,0 +1,137 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.event; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; + +import com.cloud.user.UserContext; + +@Aspect +public class ActionEventInterceptor { + + public ActionEventInterceptor() { + } + + @Pointcut(value="execution( * *(..))") + public void anyMethod() { + } + + @Around("anyMethod() && @annotation(ActionEvent)") + public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable { + MethodSignature methodSignature = (MethodSignature)call.getSignature(); + Method targetMethod = methodSignature.getMethod(); + if(needToIntercept(targetMethod)) { + 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; + } + return call.proceed(); + } + + public EventVO interceptStart(AnnotatedElement element) { + EventVO event = null; + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + boolean async = actionEvent.async(); + if(async){ + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + EventUtils.saveStartedEvent(userId, accountId, actionEvent.eventType(), eventDescription, startEventId); + } + } + return event; + } + + public void interceptComplete(AnnotatedElement element, EventVO event) { + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + if(actionEvent.create()){ + //This start event has to be used for subsequent events of this action + startEventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully created entity for "+eventDescription); + ctx.setStartEventId(startEventId); + } else { + EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully completed "+eventDescription, startEventId); + } + } + } + + public void interceptException(AnnotatedElement element, EventVO event) { + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + if(actionEvent.create()){ + long eventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while creating entity for "+eventDescription); + ctx.setStartEventId(eventId); + } else { + EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while "+eventDescription, startEventId); + } + } + } + + private boolean needToIntercept(Method method) { + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + return true; + } + + return false; + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f304df44/server/src/com/cloud/host/dao/HostDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/server/src/com/cloud/host/dao/HostDaoImpl.java index 2a7139c..5d56485 100755 --- a/server/src/com/cloud/host/dao/HostDaoImpl.java +++ b/server/src/com/cloud/host/dao/HostDaoImpl.java @@ -34,8 +34,10 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.cluster.agentlb.HostTransferMapVO; +import com.cloud.cluster.agentlb.dao.HostTransferMapDao; import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; import com.cloud.dc.ClusterVO; +import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterDaoImpl; import com.cloud.host.Host; import com.cloud.host.Host.Type; @@ -115,10 +117,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao protected Attribute _msIdAttr; protected Attribute _pingTimeAttr; - @Inject protected HostDetailsDaoImpl _detailsDao; - @Inject protected HostTagsDaoImpl _hostTagsDao; - @Inject protected HostTransferMapDaoImpl _hostTransferDao; - @Inject protected ClusterDaoImpl _clusterDao; + @Inject protected HostDetailsDao _detailsDao; + @Inject protected HostTagsDao _hostTagsDao; + @Inject protected HostTransferMapDao _hostTransferDao; + @Inject protected ClusterDao _clusterDao; public HostDaoImpl() { } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f304df44/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 2e1d851..c85b2f6 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -37,6 +37,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDaoImpl; import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.Pair; @@ -85,7 +86,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem protected SearchBuilder<VMInstanceVO> NetworkTypeSearch; protected GenericSearchBuilder<VMInstanceVO, String> DistinctHostNameSearch; - @Inject ResourceTagsDaoImpl _tagsDao; + @Inject ResourceTagDao _tagsDao; @Inject NicDao _nicDao; protected Attribute _updateTimeAttr; @@ -103,7 +104,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem " AND host.pod_id = ? AND host.cluster_id = ? AND host.type = 'Routing' " + " GROUP BY host.id ORDER BY 2 ASC "; - @Inject protected HostDaoImpl _hostDao; + @Inject protected HostDao _hostDao; public VMInstanceDaoImpl() { }
