Skip to content

Commit f304df4

Browse files
committed
Add ActionEventIntercepter to implement origianl ActionEventCallback in Spring AOP
1 parent 96bd1d4 commit f304df4

5 files changed

Lines changed: 150 additions & 9 deletions

File tree

client/tomcatconf/applicationContext.xml.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<context:annotation-config />
3434

3535
<context:component-scan base-package="org.apache.cloudstack, com.cloud" />
36-
36+
3737
<!--
3838
@DB support
3939
-->
@@ -44,7 +44,7 @@
4444
<aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod"/>
4545
</aop:aspect>
4646
</aop:config>
47-
47+
4848
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
4949

5050
<!--

server/src/com/cloud/dc/dao/HostPodDaoImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@
4040
import com.cloud.utils.db.Transaction;
4141
import com.cloud.vm.VMInstanceVO;
4242
import com.cloud.vm.VirtualMachine;
43+
import com.cloud.vm.dao.VMInstanceDao;
4344
import com.cloud.vm.dao.VMInstanceDaoImpl;
4445

4546
@Component
4647
@Local(value={HostPodDao.class})
4748
public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements HostPodDao {
4849
private static final Logger s_logger = Logger.getLogger(HostPodDaoImpl.class);
49-
@Inject VMInstanceDaoImpl _vmDao;
50+
@Inject VMInstanceDao _vmDao;
5051

5152
protected SearchBuilder<HostPodVO> DataCenterAndNameSearch;
5253
protected SearchBuilder<HostPodVO> DataCenterIdSearch;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.event;
18+
19+
import java.lang.reflect.AnnotatedElement;
20+
import java.lang.reflect.Method;
21+
22+
import org.aspectj.lang.ProceedingJoinPoint;
23+
import org.aspectj.lang.annotation.Around;
24+
import org.aspectj.lang.annotation.Aspect;
25+
import org.aspectj.lang.annotation.Pointcut;
26+
import org.aspectj.lang.reflect.MethodSignature;
27+
28+
import com.cloud.user.UserContext;
29+
30+
@Aspect
31+
public class ActionEventInterceptor {
32+
33+
public ActionEventInterceptor() {
34+
}
35+
36+
@Pointcut(value="execution( * *(..))")
37+
public void anyMethod() {
38+
}
39+
40+
@Around("anyMethod() && @annotation(ActionEvent)")
41+
public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable {
42+
MethodSignature methodSignature = (MethodSignature)call.getSignature();
43+
Method targetMethod = methodSignature.getMethod();
44+
if(needToIntercept(targetMethod)) {
45+
EventVO event = interceptStart(targetMethod);
46+
47+
boolean success = true;
48+
Object ret = null;
49+
try {
50+
ret = call.proceed();
51+
} catch (Throwable e) {
52+
success = false;
53+
interceptException(targetMethod, event);
54+
throw e;
55+
} finally {
56+
if(success){
57+
interceptComplete(targetMethod, event);
58+
}
59+
}
60+
return ret;
61+
}
62+
return call.proceed();
63+
}
64+
65+
public EventVO interceptStart(AnnotatedElement element) {
66+
EventVO event = null;
67+
Method method = (Method)element;
68+
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
69+
if (actionEvent != null) {
70+
boolean async = actionEvent.async();
71+
if(async){
72+
UserContext ctx = UserContext.current();
73+
long userId = ctx.getCallerUserId();
74+
long accountId = ctx.getAccountId();
75+
long startEventId = ctx.getStartEventId();
76+
String eventDescription = actionEvent.eventDescription();
77+
if(ctx.getEventDetails() != null){
78+
eventDescription += ". "+ctx.getEventDetails();
79+
}
80+
EventUtils.saveStartedEvent(userId, accountId, actionEvent.eventType(), eventDescription, startEventId);
81+
}
82+
}
83+
return event;
84+
}
85+
86+
public void interceptComplete(AnnotatedElement element, EventVO event) {
87+
Method method = (Method)element;
88+
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
89+
if (actionEvent != null) {
90+
UserContext ctx = UserContext.current();
91+
long userId = ctx.getCallerUserId();
92+
long accountId = ctx.getAccountId();
93+
long startEventId = ctx.getStartEventId();
94+
String eventDescription = actionEvent.eventDescription();
95+
if(ctx.getEventDetails() != null){
96+
eventDescription += ". "+ctx.getEventDetails();
97+
}
98+
if(actionEvent.create()){
99+
//This start event has to be used for subsequent events of this action
100+
startEventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully created entity for "+eventDescription);
101+
ctx.setStartEventId(startEventId);
102+
} else {
103+
EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully completed "+eventDescription, startEventId);
104+
}
105+
}
106+
}
107+
108+
public void interceptException(AnnotatedElement element, EventVO event) {
109+
Method method = (Method)element;
110+
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
111+
if (actionEvent != null) {
112+
UserContext ctx = UserContext.current();
113+
long userId = ctx.getCallerUserId();
114+
long accountId = ctx.getAccountId();
115+
long startEventId = ctx.getStartEventId();
116+
String eventDescription = actionEvent.eventDescription();
117+
if(ctx.getEventDetails() != null){
118+
eventDescription += ". "+ctx.getEventDetails();
119+
}
120+
if(actionEvent.create()){
121+
long eventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while creating entity for "+eventDescription);
122+
ctx.setStartEventId(eventId);
123+
} else {
124+
EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while "+eventDescription, startEventId);
125+
}
126+
}
127+
}
128+
129+
private boolean needToIntercept(Method method) {
130+
ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
131+
if (actionEvent != null) {
132+
return true;
133+
}
134+
135+
return false;
136+
}
137+
}

server/src/com/cloud/host/dao/HostDaoImpl.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
import org.springframework.stereotype.Component;
3535

3636
import com.cloud.cluster.agentlb.HostTransferMapVO;
37+
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
3738
import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
3839
import com.cloud.dc.ClusterVO;
40+
import com.cloud.dc.dao.ClusterDao;
3941
import com.cloud.dc.dao.ClusterDaoImpl;
4042
import com.cloud.host.Host;
4143
import com.cloud.host.Host.Type;
@@ -115,10 +117,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
115117
protected Attribute _msIdAttr;
116118
protected Attribute _pingTimeAttr;
117119

118-
@Inject protected HostDetailsDaoImpl _detailsDao;
119-
@Inject protected HostTagsDaoImpl _hostTagsDao;
120-
@Inject protected HostTransferMapDaoImpl _hostTransferDao;
121-
@Inject protected ClusterDaoImpl _clusterDao;
120+
@Inject protected HostDetailsDao _detailsDao;
121+
@Inject protected HostTagsDao _hostTagsDao;
122+
@Inject protected HostTransferMapDao _hostTransferDao;
123+
@Inject protected ClusterDao _clusterDao;
122124

123125
public HostDaoImpl() {
124126
}

server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.cloud.host.dao.HostDao;
3838
import com.cloud.host.dao.HostDaoImpl;
3939
import com.cloud.server.ResourceTag.TaggedResourceType;
40+
import com.cloud.tags.dao.ResourceTagDao;
4041
import com.cloud.tags.dao.ResourceTagsDaoImpl;
4142
import com.cloud.utils.Pair;
4243

@@ -85,7 +86,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
8586
protected SearchBuilder<VMInstanceVO> NetworkTypeSearch;
8687
protected GenericSearchBuilder<VMInstanceVO, String> DistinctHostNameSearch;
8788

88-
@Inject ResourceTagsDaoImpl _tagsDao;
89+
@Inject ResourceTagDao _tagsDao;
8990
@Inject NicDao _nicDao;
9091

9192
protected Attribute _updateTimeAttr;
@@ -103,7 +104,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
103104
" AND host.pod_id = ? AND host.cluster_id = ? AND host.type = 'Routing' " +
104105
" GROUP BY host.id ORDER BY 2 ASC ";
105106

106-
@Inject protected HostDaoImpl _hostDao;
107+
@Inject protected HostDao _hostDao;
107108

108109
public VMInstanceDaoImpl() {
109110
}

0 commit comments

Comments
 (0)