View Javadoc
1   /*
2    * Copyright 2013-2014 the original author or authors.
3    *
4    * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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  
17  package org.springframework.batch.admin.web;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  import org.springframework.batch.admin.domain.NoSuchBatchJobException;
23  import org.springframework.batch.admin.domain.NoSuchBatchJobInstanceException;
24  import org.springframework.batch.admin.service.NoSuchStepExecutionException;
25  import org.springframework.batch.core.JobParametersInvalidException;
26  import org.springframework.batch.core.launch.JobExecutionNotRunningException;
27  import org.springframework.batch.core.launch.NoSuchJobExecutionException;
28  import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
29  import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
30  import org.springframework.batch.core.repository.JobRestartException;
31  import org.springframework.hateoas.VndErrors;
32  import org.springframework.http.HttpStatus;
33  import org.springframework.util.StringUtils;
34  import org.springframework.web.bind.MissingServletRequestParameterException;
35  import org.springframework.web.bind.annotation.ControllerAdvice;
36  import org.springframework.web.bind.annotation.ExceptionHandler;
37  import org.springframework.web.bind.annotation.ResponseBody;
38  import org.springframework.web.bind.annotation.ResponseStatus;
39  
40  /**
41   * Central class for behavior common to all REST controllers.
42   *
43   * @author Eric Bottard
44   * @author Gunnar Hillert
45   * @author Ilayaperumal Gopinathan
46   * @author Michael Minella
47   * @since 2.0
48   */
49  @ControllerAdvice
50  public class RestControllerAdvice {
51  
52  	private final Log logger = LogFactory.getLog(this.getClass());
53  
54  	/*
55  	 * Note that any controller-specific exception handler is resolved first. So for example, having a
56  	 * onException(Exception e) resolver at a controller level will prevent the one from this class to be triggered.
57  	 */
58  
59  	/**
60  	 * Handles the case where client submitted an ill valued request (missing parameter).
61  	 */
62  	@ExceptionHandler
63  	@ResponseStatus(HttpStatus.BAD_REQUEST)
64  	@ResponseBody
65  	public VndErrors onMissingServletRequestParameterException(MissingServletRequestParameterException e) {
66  		String logref = logDebug(e);
67  		return new VndErrors(logref, e.getMessage());
68  	}
69  
70  	/**
71  	 * Handles the general error case. Report server-side error.
72  	 */
73  	@ExceptionHandler(Exception.class)
74  	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
75  	@ResponseBody
76  	public VndErrors onException(Exception e) {
77  		String logref = logError(e);
78  		String msg = StringUtils.hasText(e.getMessage()) ? e.getMessage() : e.getClass().getSimpleName();
79  		return new VndErrors(logref, msg);
80  	}
81  
82  	@ResponseBody
83  	@ExceptionHandler
84  	@ResponseStatus(HttpStatus.NOT_FOUND)
85  	public VndErrors onNoSuchJobExecutionException(NoSuchJobExecutionException e) {
86  		String logref = logDebug(e);
87  		return new VndErrors(logref, e.getMessage());
88  	}
89  
90  	@ResponseBody
91  	@ExceptionHandler
92  	@ResponseStatus(HttpStatus.NOT_FOUND)
93  	public VndErrors onJobExecutionNotRunningException(JobExecutionNotRunningException e) {
94  		String logref = logDebug(e);
95  		return new VndErrors(logref, e.getMessage());
96  	}
97  
98  	@ResponseBody
99  	@ExceptionHandler
100 	@ResponseStatus(HttpStatus.NOT_FOUND)
101 	public VndErrors onNoSuchStepExecutionException(NoSuchStepExecutionException e) {
102 		String logref = logDebug(e);
103 		return new VndErrors(logref, e.getMessage());
104 	}
105 
106 	private String logDebug(Throwable t) {
107 		logger.debug("Caught exception while handling a request", t);
108 		// TODO: use a more semantically correct VndError 'logref'
109 		return t.getClass().getSimpleName();
110 	}
111 
112 	private String logError(Throwable t) {
113 		logger.error("Caught exception while handling a request", t);
114 		// TODO: use a more semantically correct VndError 'logref'
115 		return t.getClass().getSimpleName();
116 	}
117 
118 	@ResponseBody
119 	@ExceptionHandler
120 	@ResponseStatus(HttpStatus.BAD_REQUEST)
121 	public VndErrors onJobExecutionAlreadyRunningException(JobExecutionAlreadyRunningException e) {
122 		String logref = logDebug(e);
123 		return new VndErrors(logref, e.getMessage());
124 	}
125 
126 	@ResponseBody
127 	@ExceptionHandler
128 	@ResponseStatus(HttpStatus.BAD_REQUEST)
129 	public VndErrors onJobRestartException(JobRestartException e) {
130 		String logref = logDebug(e);
131 		return new VndErrors(logref, e.getMessage());
132 	}
133 
134 	@ResponseBody
135 	@ExceptionHandler
136 	@ResponseStatus(HttpStatus.BAD_REQUEST)
137 	public VndErrors onJobInstanceAlreadyCompleteException(JobInstanceAlreadyCompleteException e) {
138 		String logref = logDebug(e);
139 		return new VndErrors(logref, e.getMessage());
140 	}
141 
142 	@ResponseBody
143 	@ExceptionHandler
144 	@ResponseStatus(HttpStatus.NOT_FOUND)
145 	public VndErrors onNoSuchJobException(NoSuchBatchJobException e) {
146 		String logref = logDebug(e);
147 		return new VndErrors(logref, e.getMessage());
148 	}
149 
150 	@ResponseBody
151 	@ExceptionHandler
152 	@ResponseStatus(HttpStatus.NOT_FOUND)
153 	public VndErrors onNoSuchJobInstanceException(NoSuchBatchJobInstanceException e) {
154 		String logref = logDebug(e);
155 		return new VndErrors(logref, e.getMessage());
156 	}
157 
158 	@ResponseBody
159 	@ExceptionHandler
160 	@ResponseStatus(HttpStatus.BAD_REQUEST)
161 	public VndErrors onJobParametersInvalidException(JobParametersInvalidException e) {
162 		String logref = logDebug(e);
163 		return new VndErrors(logref, e.getMessage());
164 	}
165 }