View Javadoc
1   /**
2    * Copyright 2005-2016 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.exceptionhandling;
17  
18  import javax.xml.namespace.QName;
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.apache.log4j.Logger;
22  import org.kuali.rice.core.api.exception.RiceRuntimeException;
23  import org.kuali.rice.core.api.reflect.ObjectDefinition;
24  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
25  import org.kuali.rice.ksb.api.KsbApiServiceLocator;
26  import org.kuali.rice.ksb.api.bus.Endpoint;
27  import org.kuali.rice.ksb.api.bus.ServiceBus;
28  import org.kuali.rice.ksb.api.messaging.AsynchronousCall;
29  import org.kuali.rice.ksb.messaging.PersistedMessageBO;
30  import org.kuali.rice.ksb.messaging.quartz.MessageServiceExecutorJob;
31  import org.kuali.rice.ksb.messaging.quartz.MessageServiceExecutorJobListener;
32  import org.kuali.rice.ksb.service.KSBServiceLocator;
33  import org.quartz.JobDataMap;
34  import org.quartz.JobDetail;
35  import org.quartz.Scheduler;
36  import org.quartz.SimpleTrigger;
37  import org.quartz.Trigger;
38  
39  
40  /**
41   * Default implementation of {@link ExceptionRoutingService}.  Just saves 
42   * the message in the queue as is, which should be marked Exception by the 
43   * {@link MessageExceptionHandler}.
44   * 
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   *
47   */
48  public class DefaultExceptionServiceImpl implements ExceptionRoutingService {
49  	
50  	private static final Logger LOG = Logger.getLogger(DefaultExceptionServiceImpl.class);
51  
52  	public void placeInExceptionRouting(Throwable throwable, PersistedMessageBO message, Object service) throws Exception {
53  		LOG.error("Exception caught processing message " + message.getRouteQueueId() + " " + message.getServiceName() + ": " + throwable);
54  		
55  		
56  		AsynchronousCall methodCall = null;
57  		if (message.getMethodCall() != null) {
58  			methodCall = message.getMethodCall();
59  		} else {
60  			methodCall = message.getPayload().getMethodCall();
61  		}
62  		message.setMethodCall(methodCall);
63  		MessageExceptionHandler exceptionHandler = getMessageExceptionHandler(methodCall.getServiceConfiguration().getServiceName());
64  		exceptionHandler.handleException(throwable, message, service);
65  	}
66  	
67  	public void placeInExceptionRoutingLastDitchEffort(Throwable throwable, PersistedMessageBO message, Object service) throws Exception {
68  		LOG.error("Exception caught processing message " + message.getRouteQueueId() + " " + message.getServiceName() + ": " + throwable);
69  		
70  		AsynchronousCall methodCall = null;
71  		if (message.getMethodCall() != null) {
72  			methodCall = message.getMethodCall();
73  		} else {
74  			methodCall = message.getPayload().getMethodCall();
75  		}
76  		message.setMethodCall(methodCall);
77  		MessageExceptionHandler exceptionHandler = getMessageExceptionHandler(methodCall.getServiceConfiguration().getServiceName());
78  		exceptionHandler.handleExceptionLastDitchEffort(throwable, message, service);
79  	}
80  	
81  	protected MessageExceptionHandler getMessageExceptionHandler(QName serviceName) {
82  		ServiceBus serviceBus = KsbApiServiceLocator.getServiceBus();
83  		Endpoint endpoint = serviceBus.getEndpoint(serviceName);
84  		if (endpoint == null) {
85  			throw new RiceRuntimeException("No services found for name " + serviceName);
86  		}
87  		String messageExceptionHandlerName = endpoint.getServiceConfiguration().getMessageExceptionHandler();
88  		if (messageExceptionHandlerName == null) {
89  			messageExceptionHandlerName = DefaultMessageExceptionHandler.class.getName();
90  		}
91  		return (MessageExceptionHandler) GlobalResourceLoader.getObject(new ObjectDefinition(messageExceptionHandlerName));
92  	}
93  	
94  	
95  
96  	public void scheduleExecution(Throwable throwable, PersistedMessageBO message, String description) throws Exception {
97  		KSBServiceLocator.getMessageQueueService().delete(message);
98          PersistedMessageBO messageCopy = message.copy();
99  		Scheduler scheduler = KSBServiceLocator.getScheduler();
100 		JobDataMap jobData = new JobDataMap();
101 		jobData.put(MessageServiceExecutorJob.MESSAGE_KEY, messageCopy);
102 		JobDetail jobDetail = new JobDetail("Exception_Message_Job " + Math.random(), "Exception Messaging",
103 			MessageServiceExecutorJob.class);
104 		jobDetail.setJobDataMap(jobData);
105 		if (!StringUtils.isBlank(description)) {
106 		    jobDetail.setDescription(description);
107 		}
108 		jobDetail.addJobListener(MessageServiceExecutorJobListener.NAME);
109 		Trigger trigger = new SimpleTrigger("Exception_Message_Trigger " + Math.random(), "Exception Messaging", messageCopy
110 			.getQueueDate());
111 		trigger.setJobDataMap(jobData);// 1.6 bug required or derby will choke
112 		scheduler.scheduleJob(jobDetail, trigger);    
113 	}
114 		
115 }