comparison servlet/src/digilib/servlet/Scaler.java @ 804:587c90bc5976 stream

first version using officially approved Servlet 3.0 async support.
author robcast
date Sat, 19 Feb 2011 22:01:12 +0100
parents 034ab33984d2
children d811204ce5a4
comparison
equal deleted inserted replaced
802:034ab33984d2 804:587c90bc5976
1 package digilib.servlet; 1 package digilib.servlet;
2 2
3 import java.io.File; 3 import java.io.File;
4 import java.io.IOException; 4 import java.io.IOException;
5 import java.util.List; 5 import java.util.List;
6 import java.util.concurrent.ExecutionException; 6
7 import java.util.concurrent.Future; 7 import javax.servlet.AsyncContext;
8
9 import javax.servlet.ServletConfig; 8 import javax.servlet.ServletConfig;
10 import javax.servlet.ServletContext; 9 import javax.servlet.ServletContext;
11 import javax.servlet.ServletException; 10 import javax.servlet.ServletException;
11 import javax.servlet.annotation.WebServlet;
12 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServlet;
13 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse; 14 import javax.servlet.http.HttpServletResponse;
15 15
16 import org.apache.log4j.Logger; 16 import org.apache.log4j.Logger;
18 import digilib.auth.AuthOpException; 18 import digilib.auth.AuthOpException;
19 import digilib.auth.AuthOps; 19 import digilib.auth.AuthOps;
20 import digilib.image.DocuImage; 20 import digilib.image.DocuImage;
21 import digilib.image.ImageJobDescription; 21 import digilib.image.ImageJobDescription;
22 import digilib.image.ImageOpException; 22 import digilib.image.ImageOpException;
23 import digilib.image.ImageWorker;
24 import digilib.io.DocuDirCache; 23 import digilib.io.DocuDirCache;
25 import digilib.io.DocuDirectory; 24 import digilib.io.DocuDirectory;
26 import digilib.io.ImageInput; 25 import digilib.io.ImageInput;
27 import digilib.util.DigilibJobCenter; 26 import digilib.util.DigilibJobCenter;
28 27
29 @SuppressWarnings("serial") 28 @WebServlet(name="Scaler", urlPatterns={"/Scaler", "/servlet/Scaler/*"}, asyncSupported=true)
30 public class Scaler extends HttpServlet { 29 public class Scaler extends HttpServlet {
31 30
31 private static final long serialVersionUID = 5289386646192471549L;
32
32 /** digilib servlet version (for all components) */ 33 /** digilib servlet version (for all components) */
33 public static final String version = "1.9.0a3"; 34 public static final String version = "1.9.1a2";
34 35
35 /** servlet error codes */ 36 /** servlet error codes */
36 public static enum Error {UNKNOWN, AUTH, FILE, IMAGE}; 37 public static enum Error {UNKNOWN, AUTH, FILE, IMAGE};
37 38
38 /** type of error message */ 39 /** type of error message */
52 53
53 /** Image executor */ 54 /** Image executor */
54 DigilibJobCenter<DocuImage> imageJobCenter; 55 DigilibJobCenter<DocuImage> imageJobCenter;
55 56
56 /** authentication error image file */ 57 /** authentication error image file */
57 File denyImgFile; 58 static File denyImgFile;
58 59
59 /** image error image file */ 60 /** image error image file */
60 File errorImgFile; 61 static File errorImgFile;
61 62
62 /** not found error image file */ 63 /** not found error image file */
63 File notfoundImgFile; 64 static File notfoundImgFile;
64 65
65 /** send files as is? */ 66 /** send files as is? */
66 boolean sendFileAllowed = true; 67 boolean sendFileAllowed = true;
67 68
68 /** DigilibConfiguration instance */ 69 /** DigilibConfiguration instance */
181 throw new ServletException("NO VALID digilib CONFIGURATION!"); 182 throw new ServletException("NO VALID digilib CONFIGURATION!");
182 } 183 }
183 184
184 accountlog.debug("request: " + request.getQueryString()); 185 accountlog.debug("request: " + request.getQueryString());
185 logger.debug("request: " + request.getQueryString()); 186 logger.debug("request: " + request.getQueryString());
186 long startTime = System.currentTimeMillis(); 187 logger.debug("response:"+ response + " committed=" + response.isCommitted());
188 final long startTime = System.currentTimeMillis();
187 189
188 // parse request 190 // parse request
189 DigilibRequest dlRequest = new DigilibRequest(request); 191 DigilibRequest dlRequest = new DigilibRequest(request);
190 // extract the job information 192 // extract the job information
191 ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig); 193 final ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig);
192 194
193 // type of error reporting 195 // type of error reporting
194 ErrMsg errMsgType = ErrMsg.IMAGE; 196 ErrMsg errMsgType = ErrMsg.IMAGE;
195 if (dlRequest.hasOption("errtxt")) { 197 if (dlRequest.hasOption("errtxt")) {
196 errMsgType = ErrMsg.TEXT; 198 errMsgType = ErrMsg.TEXT;
244 if (imageJobCenter.isBusy()) { 246 if (imageJobCenter.isBusy()) {
245 logger.error("Servlet overloaded!"); 247 logger.error("Servlet overloaded!");
246 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); 248 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
247 return; 249 return;
248 } 250 }
251
252 // worker job is done asynchronously
253 AsyncContext asyncCtx = request.startAsync(request, response);
249 // create job 254 // create job
250 ImageWorker job = new ImageWorker(dlConfig, jobTicket); 255 AsyncServletWorker job = new AsyncServletWorker(dlConfig, jobTicket, asyncCtx, errMsgType, startTime);
251 // submit job 256 // submit job
252 Future<DocuImage> jobResult = imageJobCenter.submit(job); 257 imageJobCenter.submit(job);
253 // wait for result 258 // we're done for now
254 DocuImage img = jobResult.get();
255 // send image
256 ServletOps.sendImage(img, null, response, logger);
257 logger.debug("Job Processing Time: "
258 + (System.currentTimeMillis() - startTime) + "ms");
259 259
260 } catch (ImageOpException e) { 260 } catch (ImageOpException e) {
261 logger.error(e.getClass() + ": " + e.getMessage()); 261 logger.error(e.getClass() + ": " + e.getMessage());
262 digilibError(errMsgType, Error.IMAGE, null, response); 262 digilibError(errMsgType, Error.IMAGE, null, response);
263 } catch (IOException e) { 263 } catch (IOException e) {
264 logger.error(e.getClass() + ": " + e.getMessage()); 264 logger.error(e.getClass() + ": " + e.getMessage());
265 digilibError(errMsgType, Error.FILE, null, response); 265 digilibError(errMsgType, Error.FILE, null, response);
266 } catch (AuthOpException e) { 266 } catch (AuthOpException e) {
267 logger.error(e.getClass() + ": " + e.getMessage()); 267 logger.error(e.getClass() + ": " + e.getMessage());
268 digilibError(errMsgType, Error.AUTH, null, response); 268 digilibError(errMsgType, Error.AUTH, null, response);
269 } catch (InterruptedException e) { 269 }
270 logger.error(e.getClass() + ": " + e.getMessage());
271 } catch (ExecutionException e) {
272 logger.error(e.getClass() + ": " + e.getMessage());
273 String causeMsg = e.getCause().getMessage();
274 logger.error("caused by: " + causeMsg);
275 digilibError(errMsgType, Error.IMAGE, causeMsg, response);
276 }
277
278 } 270 }
279 271
280 /** 272 /**
281 * Sends an error to the client as text or image. 273 * Sends an error to the client as text or image.
282 * 274 *
283 * @param type 275 * @param type
284 * @param error 276 * @param error
285 * @param msg 277 * @param msg
286 * @param response 278 * @param response
287 */ 279 */
288 public void digilibError(ErrMsg type, Error error, String msg, 280 public static void digilibError(ErrMsg type, Error error, String msg,
289 HttpServletResponse response) { 281 HttpServletResponse response) {
290 try { 282 try {
291 File img = null; 283 File img = null;
292 int status = 0; 284 int status = 0;
293 if (error == Error.AUTH) { 285 if (error == Error.AUTH) {
304 status = HttpServletResponse.SC_NOT_FOUND; 296 status = HttpServletResponse.SC_NOT_FOUND;
305 } else { 297 } else {
306 if (msg == null) { 298 if (msg == null) {
307 msg = "ERROR: Other image error!"; 299 msg = "ERROR: Other image error!";
308 } 300 }
309 img = this.errorImgFile; 301 img = errorImgFile;
310 status = HttpServletResponse.SC_BAD_REQUEST; 302 status = HttpServletResponse.SC_BAD_REQUEST;
311 } 303 }
312 if (response.isCommitted()) { 304 if (response.isCommitted()) {
313 // response already committed 305 // response already committed
314 logger.error("Unable to send error: " + msg); 306 logger.warn("Response committed for error "+msg);
315 return;
316 } 307 }
317 if (type == ErrMsg.TEXT) { 308 if (type == ErrMsg.TEXT) {
318 ServletOps.htmlMessage(msg, response); 309 ServletOps.htmlMessage(msg, response);
319 } else if (type == ErrMsg.CODE) { 310 } else if (type == ErrMsg.CODE) {
320 response.sendError(status, msg); 311 response.sendError(status, msg);