001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 core.tut.pori.context; 017 018import java.io.IOException; 019 020import javax.servlet.ServletException; 021import javax.servlet.http.HttpServlet; 022import javax.servlet.http.HttpServletRequest; 023import javax.servlet.http.HttpServletResponse; 024 025import org.apache.commons.lang3.exception.ExceptionUtils; 026import org.apache.log4j.Logger; 027import org.springframework.security.core.Authentication; 028import org.springframework.security.core.context.SecurityContextHolder; 029 030import core.tut.pori.http.Response; 031import core.tut.pori.http.Response.Status; 032import core.tut.pori.http.ServiceRequest; 033import core.tut.pori.users.UserIdentity; 034 035/** 036 * Servlet class which processes the incoming requests to service requests and delegates them to the service handler. 037 * 038 */ 039public class RESTHandler extends HttpServlet{ 040 /** REST service uri path */ 041 public static final String PATH_REST = "rest/"; 042 private static final Logger LOGGER = Logger.getLogger(RESTHandler.class); 043 private static final long serialVersionUID = -2268900222019910706L; 044 045 @Override 046 protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 047 handleRequest(req, resp); 048 } 049 050 @Override 051 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 052 handleRequest(req, resp); 053 } 054 055 @Override 056 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 057 handleRequest(req, resp); 058 } 059 060 @Override 061 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 062 handleRequest(req, resp); 063 } 064 065 /** 066 * 067 * @param req 068 * @param resp 069 */ 070 private void handleRequest(HttpServletRequest req, HttpServletResponse resp){ 071 String pathInfo = req.getPathInfo(); 072 LOGGER.debug("Received request "+req.getMethod()+" "+pathInfo+" from "+req.getRemoteAddr()); 073 074 Response r = null; 075 ServiceRequest serviceRequest = null; 076 try{ 077 serviceRequest = ServiceRequest.createRequest(getAuthenticatedUser(), req); 078 r = ServiceInitializer.getServiceHandler().invoke(serviceRequest); // chop the trailing separator from method name if present 079 }catch(Throwable ex){ // do not allow exceptions to get through 080 LOGGER.error(ExceptionUtils.getStackTrace(ex)); // make sure the stacktrace gets printed if something else than IllegalArgumentException is thrown 081 r = new Response(); 082 r.setStatus(Status.INTERNAL_SERVER_ERROR); 083 } 084 085 if(serviceRequest != null){ // check if no service or method name is set, and set the default if needed 086 String service = r.getService(); 087 if(service == null){ 088 r.setService(serviceRequest.getServiceName()); 089 } 090 String method = r.getMethod(); 091 if(method == null){ 092 r.setMethod(serviceRequest.getMethodName()); 093 } 094 }else{ 095 LOGGER.warn("Failed to create "+ServiceRequest.class.toString()); 096 } 097 r.writeTo(resp); 098 } 099 100 /** 101 * 102 * @return authenticated user or null if user has not authenticated 103 */ 104 private UserIdentity getAuthenticatedUser(){ 105 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 106 if(auth != null && auth.isAuthenticated()){ 107 Object principal = auth.getPrincipal(); 108 if(principal.getClass() == UserIdentity.class){ 109 return (UserIdentity) principal; 110 }else{ 111 LOGGER.debug("UserDetails not available."); 112 } 113 } 114 return null; 115 } 116}