001/** 002 * Copyright 2005-2015 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.ksb.messaging.bam.service.impl; 017 018import org.apache.commons.lang.StringUtils; 019import org.apache.log4j.Logger; 020import org.kuali.rice.core.api.config.property.Config; 021import org.kuali.rice.core.api.config.property.ConfigContext; 022import org.kuali.rice.core.api.criteria.Predicate; 023import org.kuali.rice.core.api.criteria.QueryByCriteria; 024import org.kuali.rice.core.api.reflect.ObjectDefinition; 025import org.kuali.rice.krad.data.DataObjectService; 026import org.kuali.rice.krad.data.PersistenceOption; 027import org.kuali.rice.ksb.api.bus.ServiceConfiguration; 028import org.kuali.rice.ksb.api.bus.ServiceDefinition; 029import org.kuali.rice.ksb.messaging.bam.BAMParam; 030import org.kuali.rice.ksb.messaging.bam.BAMTargetEntry; 031import org.kuali.rice.ksb.messaging.bam.service.BAMService; 032 033import javax.xml.namespace.QName; 034import java.lang.reflect.Method; 035import java.sql.Timestamp; 036import java.util.ArrayList; 037import java.util.List; 038 039import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 040import static org.kuali.rice.core.api.criteria.PredicateFactory.like; 041 042public class BAMServiceImpl implements BAMService { 043 044 private static final Logger LOG = Logger.getLogger(BAMServiceImpl.class); 045 046 private DataObjectService dataObjectService; 047 048 public BAMTargetEntry recordClientInvocation(ServiceConfiguration serviceConfiguration, Object target, Method method, Object[] params) { 049 if (isEnabled()) { 050 try { 051 LOG.debug("A call was received... for service: " + serviceConfiguration.getServiceName().toString() + " method: " + method.getName()); 052 BAMTargetEntry bamTargetEntry = getBAMTargetEntry(Boolean.FALSE, serviceConfiguration, target, method, params); 053 return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH); 054 } catch (Throwable t) { 055 LOG.error("BAM Failed to record client invocation", t); 056 } 057 } 058 return null; 059 } 060 061 public BAMTargetEntry recordServerInvocation(Object target, ServiceDefinition serviceDefinition, Method method, Object[] params) { 062 if (isEnabled()) { 063 try { 064 LOG.debug("A call was received... for service: " + target.getClass().getName() + " method: " + method.getName()); 065 BAMTargetEntry bamTargetEntry = getBAMTargetEntry(Boolean.TRUE, serviceDefinition, target, method, params); 066 return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH); 067 } catch (Throwable t) { 068 LOG.error("BAM Failed to record server invocation", t); 069 } 070 } 071 return null; 072 } 073 074 public BAMTargetEntry recordClientInvocationError(Throwable throwable, BAMTargetEntry bamTargetEntry) { 075 if (bamTargetEntry != null) { 076 try { 077 setThrowableOnBAMTargetEntry(throwable, bamTargetEntry); 078 return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH); 079 } catch (Exception e) { 080 LOG.error("BAM Failed to record client invocation error", e); 081 } 082 } 083 return null; 084 } 085 086 public BAMTargetEntry recordServerInvocationError(Throwable throwable, BAMTargetEntry bamTargetEntry) { 087 if (bamTargetEntry != null) { 088 try { 089 setThrowableOnBAMTargetEntry(throwable, bamTargetEntry); 090 return dataObjectService.save(bamTargetEntry, PersistenceOption.FLUSH); 091 } catch (Exception e) { 092 LOG.error("BAM Failed to record service invocation error", e); 093 } 094 } 095 return null; 096 } 097 098 private void setThrowableOnBAMTargetEntry(Throwable throwable, BAMTargetEntry bamTargetEntry) { 099 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 dataObjectService.deleteAll(BAMTargetEntry.class); 187 dataObjectService.deleteAll(BAMParam.class); 188 } 189 190 public DataObjectService getDataObjectService() { 191 return dataObjectService; 192 } 193 194 public void setDataObjectService(DataObjectService dataObjectService) { 195 this.dataObjectService = dataObjectService; 196 } 197 198}