View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.ksb.messaging.bam.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.config.property.Config;
21  import org.kuali.rice.core.api.config.property.ConfigContext;
22  import org.kuali.rice.core.api.criteria.Predicate;
23  import org.kuali.rice.core.api.criteria.QueryByCriteria;
24  import org.kuali.rice.core.api.reflect.ObjectDefinition;
25  import org.kuali.rice.krad.data.DataObjectService;
26  import org.kuali.rice.krad.data.PersistenceOption;
27  import org.kuali.rice.ksb.api.bus.ServiceConfiguration;
28  import org.kuali.rice.ksb.api.bus.ServiceDefinition;
29  import org.kuali.rice.ksb.messaging.bam.BAMParam;
30  import org.kuali.rice.ksb.messaging.bam.BAMTargetEntry;
31  import org.kuali.rice.ksb.messaging.bam.service.BAMService;
32  
33  import javax.xml.namespace.QName;
34  import java.lang.reflect.Method;
35  import java.sql.Timestamp;
36  import java.util.ArrayList;
37  import java.util.List;
38  
39  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
40  import static org.kuali.rice.core.api.criteria.PredicateFactory.like;
41  
42  public class BAMServiceImpl implements BAMService {
43  
44  	private static final Logger LOG = Logger.getLogger(BAMServiceImpl.class);
45  
46      private DataObjectService dataObjectService;
47  
48  	public BAMTargetEntry recordClientInvocation(ServiceConfiguration serviceConfiguration, Object target, Method method, Object[] params) {
49  		if (isEnabled()) {
50  			try {
51  				LOG.debug("A call was received... for service: " + serviceConfiguration.getServiceName().toString() + " method: " + method.getName());
52  				BAMTargetEntry bamTargetEntry = getBAMTargetEntry(Boolean.FALSE, serviceConfiguration, target, method, params);
53                  return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH);
54  			} catch (Throwable t) {
55  				LOG.error("BAM Failed to record client invocation", t);
56  			}
57  		}
58  		return null;
59  	}
60  
61  	public BAMTargetEntry recordServerInvocation(Object target, ServiceDefinition serviceDefinition, Method method, Object[] params) {
62  		if (isEnabled()) {
63  			try {
64  				LOG.debug("A call was received... for service: " + target.getClass().getName() + " method: " + method.getName());
65  				BAMTargetEntry bamTargetEntry = getBAMTargetEntry(Boolean.TRUE, serviceDefinition, target, method, params);
66                  return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH);
67  			} catch (Throwable t) {
68  				LOG.error("BAM Failed to record server invocation", t);
69  			}
70  		}
71  		return null;
72  	}
73  
74  	public BAMTargetEntry recordClientInvocationError(Throwable throwable, BAMTargetEntry bamTargetEntry) {
75  		if (bamTargetEntry != null) {
76  			try {
77  				setThrowableOnBAMTargetEntry(throwable, bamTargetEntry);
78                  return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH);
79  			} catch (Exception e) {
80  				LOG.error("BAM Failed to record client invocation error", e);
81  			}
82  		}
83  		return null;
84  	}
85  
86  	public BAMTargetEntry recordServerInvocationError(Throwable throwable, BAMTargetEntry bamTargetEntry) {
87  		if (bamTargetEntry != null) {
88  			try {
89  				setThrowableOnBAMTargetEntry(throwable, bamTargetEntry);
90                  return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH);
91  			} catch (Exception e) {
92  				LOG.error("BAM Failed to record service invocation error", e);
93  			}
94  		}
95  		return null;
96  	}
97  
98  	private void setThrowableOnBAMTargetEntry(Throwable throwable, BAMTargetEntry bamTargetEntry) {
99  		if (throwable != null) {
100 			bamTargetEntry.setExceptionMessage(throwable.getMessage());
101 			bamTargetEntry.setExceptionToString(makeStringfit(throwable.toString()));
102 		}
103 	}
104 
105 	private BAMTargetEntry getBAMTargetEntry(Boolean serverInd, ServiceConfiguration serviceConfiguration, Object target, Method method, Object[] params) {
106 		BAMTargetEntry bamEntry = new BAMTargetEntry();
107 		bamEntry.setServerInvocation(serverInd);
108 		bamEntry.setServiceName(serviceConfiguration.getServiceName().toString());
109 		bamEntry.setServiceURL(serviceConfiguration.getEndpointUrl().toExternalForm());
110 		bamEntry.setTargetToString(makeStringfit(target.toString()));
111 		bamEntry.setMethodName(method.getName());
112 		bamEntry.setThreadName(Thread.currentThread().getName());
113 		bamEntry.setCallDate(new Timestamp(System.currentTimeMillis()));
114 		setBamParams(params, bamEntry);
115 		return bamEntry;
116 	}
117 	
118 	private BAMTargetEntry getBAMTargetEntry(Boolean serverInd, ServiceDefinition serviceDefinition, Object target, Method method, Object[] params) {
119 		BAMTargetEntry bamEntry = new BAMTargetEntry();
120 		bamEntry.setServerInvocation(serverInd);
121 		bamEntry.setServiceName(serviceDefinition.getServiceName().toString());
122 		bamEntry.setServiceURL(serviceDefinition.getEndpointUrl().toExternalForm());
123 		bamEntry.setTargetToString(makeStringfit(target.toString()));
124 		bamEntry.setMethodName(method.getName());
125 		bamEntry.setThreadName(Thread.currentThread().getName());
126 		bamEntry.setCallDate(new Timestamp(System.currentTimeMillis()));
127 		setBamParams(params, bamEntry);
128 		return bamEntry;
129 	}
130 
131 	private void setBamParams(Object[] params, BAMTargetEntry bamEntry) {
132 		if (params == null) {
133 			return;
134 		}
135 		for (int i = 0; i < params.length; i++) {
136 			BAMParam bamParam = new BAMParam();
137 			bamParam.setBamTargetEntry(bamEntry);
138 			bamParam.setParam(params[i].toString());
139 			bamEntry.addBamParam(bamParam);
140 		}
141 	}
142 
143 	private String makeStringfit(String string) {
144 		if (string.length() > 1999) {
145 			return string.substring(0, 1999);
146 		}
147 		return string;
148 	}
149 
150 	public boolean isEnabled() {
151 		return Boolean.valueOf(ConfigContext.getCurrentContextConfig().getProperty(Config.BAM_ENABLED));
152 	}
153 
154 	public List<BAMTargetEntry> getCallsForService(QName serviceName) {
155         return getCallsForService(serviceName, null);
156 	}
157 
158     public List<BAMTargetEntry> getCallsForService(QName serviceName, String methodName) {
159         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
160         List<Predicate> predicates = new ArrayList<Predicate>();
161         predicates.add(equal("serviceName", serviceName.toString()));
162         if (StringUtils.isNotBlank(methodName)) {
163             predicates.add(equal("methodName", methodName));
164         }
165         builder.setPredicates(predicates.toArray(new Predicate[predicates.size()]));
166         return dataObjectService.findMatching(BAMTargetEntry.class, builder.build()).getResults();
167     }
168 
169 	public List<BAMTargetEntry> getCallsForRemotedClasses(ObjectDefinition objDef) {
170 		return getCallsForRemotedClasses(objDef, null);
171 	}
172 
173     public List<BAMTargetEntry> getCallsForRemotedClasses(ObjectDefinition objDef, String methodName) {
174         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
175         List<Predicate> predicates = new ArrayList<Predicate>();
176         QName qname = new QName(objDef.getApplicationId(), objDef.getClassName());
177         predicates.add(like("serviceName", qname.toString() + "*"));
178         if (StringUtils.isNotBlank(methodName)) {
179             predicates.add(equal("methodName", methodName));
180         }
181         builder.setPredicates(predicates.toArray(new Predicate[predicates.size()]));
182         return dataObjectService.findMatching(BAMTargetEntry.class, builder.build()).getResults();
183     }
184 
185 	public void clearBAMTables() {
186         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
187         dataObjectService.deleteMatching(BAMTargetEntry.class, builder.build());
188         dataObjectService.deleteMatching(BAMParam.class, builder.build());
189 	}
190 
191     public DataObjectService getDataObjectService() {
192         return dataObjectService;
193     }
194 
195     public void setDataObjectService(DataObjectService dataObjectService) {
196         this.dataObjectService = dataObjectService;
197     }
198 
199 }