83dc9c4314b93856fe2fca5176967ffb5cc93e0d
[portal/sdk.git] /
1 /*
2  * ============LICENSE_START==========================================
3  * ONAP Portal SDK
4  * ===================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  *
8  * Unless otherwise specified, all software contained herein is licensed
9  * under the Apache License, Version 2.0 (the "License");
10  * you may not use this software except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *             http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Unless otherwise specified, all documentation contained herein is licensed
22  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23  * you may not use this documentation except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *             https://creativecommons.org/licenses/by/4.0/
27  *
28  * Unless required by applicable law or agreed to in writing, documentation
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * ============LICENSE_END============================================
35  *
36  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
37  */
38 package org.onap.portalsdk.core.onboarding.crossapi;
39
40 import java.io.BufferedReader;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.InputStreamReader;
44 import java.io.PrintWriter;
45 import java.io.StringWriter;
46 import java.util.List;
47 import java.util.Map;
48
49 import javax.servlet.ServletException;
50 import javax.servlet.annotation.WebServlet;
51 import javax.servlet.http.HttpServlet;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.servlet.http.HttpServletResponse;
54
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57 import org.onap.portalsdk.core.onboarding.exception.PortalAPIException;
58 import org.onap.portalsdk.core.onboarding.listener.PortalTimeoutHandler;
59 import org.onap.portalsdk.core.onboarding.rest.RestWebServiceClient;
60 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
61 import org.onap.portalsdk.core.onboarding.util.PortalApiProperties;
62 import org.onap.portalsdk.core.restful.domain.EcompRole;
63 import org.onap.portalsdk.core.restful.domain.EcompUser;
64
65 import com.fasterxml.jackson.core.JsonProcessingException;
66 import com.fasterxml.jackson.core.type.TypeReference;
67 import com.fasterxml.jackson.databind.DeserializationFeature;
68 import com.fasterxml.jackson.databind.ObjectMapper;
69
70 /**
71  * This servlet performs the functions described below. It listens on a path
72  * like "/api" (see {@link PortalApiConstants#API_PREFIX}). The servlet checks
73  * for authorized access and rejects unauthorized requests.
74  * <OL>
75  * <LI>Proxies user (i.e., browser) requests for web analytics. The GET method
76  * fetches javascript from the Portal and returns it. The POST method forwards
77  * data sent by the browser on to Portal. These requests are checked for a valid
78  * User UID in a header; these requests do NOT use the application
79  * username-password header.</LI>
80  * <LI>Responds to ECOMP Portal API requests to query and update user, role and
81  * user-role information. The servlet proxies all requests on to a local Java
82  * class that implements {@link IPortalRestAPIService}. These requests must have
83  * the application username-password header.</LI>
84  * </OL>
85  * This servlet will not start if the required portal.properties file is not
86  * found on the classpath.
87  */
88
89 @WebServlet(urlPatterns = { PortalApiConstants.API_PREFIX + "/*" })
90 public class PortalRestAPIProxy extends HttpServlet implements IPortalRestAPIService {
91         
92         private static final long serialVersionUID = 1L;
93
94         private static final String APPLICATION_JSON = "application/json";
95
96         private static final Log logger = LogFactory.getLog(PortalRestAPIProxy.class);
97
98         /**
99          * Mapper for JSON to object etc.
100          */
101         private final ObjectMapper mapper = new ObjectMapper();
102
103         /**
104          * Client-supplied class that implements our interface.
105          */
106         private static IPortalRestAPIService portalRestApiServiceImpl;
107
108         public PortalRestAPIProxy() {
109                 // Ensure that any additional fields sent by the Portal
110                 // will be ignored when creating objects.
111                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
112         }
113
114         @Override
115         public void init() throws ServletException {
116                 String className = PortalApiProperties.getProperty(PortalApiConstants.PORTAL_API_IMPL_CLASS);
117                 if (className == null)
118                         throw new ServletException(
119                                         "init: Failed to find class name property " + PortalApiConstants.PORTAL_API_IMPL_CLASS);
120                 try {
121                         logger.debug("init: creating instance of class " + className);
122                         Class<?> implClass = Class.forName(className);
123                         portalRestApiServiceImpl = (IPortalRestAPIService) (implClass.getConstructor().newInstance());
124                 } catch (Exception ex) {
125                         throw new ServletException("init: Failed to find or instantiate class " + className, ex);
126                 }
127         }
128
129         @Override
130         protected void doPost(HttpServletRequest request, HttpServletResponse response)
131                         throws IOException, ServletException {
132                 if (portalRestApiServiceImpl == null) {
133                         // Should never happen due to checks in init()
134                         logger.error("doPost: no service class instance");
135                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
136                         response.getWriter().write(buildJsonResponse(false, "Misconfigured - no instance of service class"));
137                         return;
138                 }
139                 String requestUri = request.getRequestURI();
140                 String responseJson = "";
141                 String storeAnalyticsContextPath = "/storeAnalytics";
142                 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + storeAnalyticsContextPath)) {
143                         String userId;
144                         try {
145                                 userId = getUserId(request);
146                         } catch (PortalAPIException e) {
147                                 logger.error("Issue with invoking getUserId implemenation !!! ", e);
148                                 throw new ServletException(e);
149                         }
150                         if (userId == null || userId.length() == 0) {
151                                 logger.debug("doPost: userId is null or empty");
152                                 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
153                                 responseJson = buildJsonResponse(false, "Not authorized for " + storeAnalyticsContextPath);
154                         } else {
155                                 // User ID obtained from request
156                                 try {
157                                         String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY);
158                                         // for now lets also pass uebkey as user name and password
159                                         String requestBody = readRequestBody(request);
160                                         @SuppressWarnings("unchecked")
161                                         Map<String, String> bodyMap = mapper.readValue(requestBody, Map.class);
162                                         // add user ID
163                                         bodyMap.put("userid", userId);
164                                         requestBody = mapper.writeValueAsString(bodyMap);
165                                         responseJson = RestWebServiceClient.getInstance().postPortalContent(storeAnalyticsContextPath,
166                                                         userId, credential, null, credential, credential, "application/json", requestBody, true);
167                                         logger.debug("doPost: postPortalContent returns " + responseJson);
168                                         response.setStatus(HttpServletResponse.SC_OK);
169                                 } catch (Exception ex) {
170                                         logger.error("doPost: " + storeAnalyticsContextPath + " caught exception", ex);
171                                         responseJson = buildJsonResponse(ex);
172                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
173                                 }
174                         }
175                         writeAndFlush(response, APPLICATION_JSON, responseJson);
176                         return;
177                 } // post analytics
178
179                 boolean secure = false;
180                 try {
181                         secure = isAppAuthenticated(request);
182                 } catch (PortalAPIException ex) {
183                         logger.error("doPost: isAppAuthenticated threw exception", ex);
184                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
185                         response.getWriter().write(buildJsonResponse(false, "Failed to authenticate request"));
186                         return;
187                 }
188                 if (!secure) {
189                         logger.debug("doPost: isAppAuthenticated answered false");
190                         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
191                         writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Not authorized"));
192                         return;
193                 }
194
195                 try {
196                         String requestBody = readRequestBody(request);
197                         if (logger.isDebugEnabled())
198                                 logger.debug("doPost: URI =  " + requestUri + ", payload = " + requestBody);
199
200                         /*
201                          * All APIs:
202                          * 
203                          * 1. /user <-- save user
204                          * 
205                          * 2. /user/{loginId} <-- edit user
206                          * 
207                          * 3. /user/{loginId}/roles <-- save roles for user
208                          */
209
210                         // On success return the empty string.
211
212                         if (requestUri.endsWith("/updateSessionTimeOuts")) {
213                                 if (updateSessionTimeOuts(requestBody)) {
214                                         logger.debug("doPost: updated session timeouts");
215                                         response.setStatus(HttpServletResponse.SC_OK);
216                                 } else {
217                                         String msg = "Failed to update session time outs";
218                                         logger.error("doPost: " + msg);
219                                         responseJson = buildJsonResponse(false, msg);
220                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
221                                 }
222                         } else if (requestUri.endsWith("/timeoutSession")) {
223                                 String portalJSessionId = request.getParameter("portalJSessionId");
224                                 if (portalJSessionId == null) {
225                                         portalJSessionId = "";
226                                 }
227                                 if (timeoutSession(portalJSessionId)) {
228                                         logger.debug("doPost: timed out session");
229                                         response.setStatus(HttpServletResponse.SC_OK);
230                                 } else {
231                                         String msg = "Failed to timeout session";
232                                         logger.error("doPost: " + msg);
233                                         responseJson = buildJsonResponse(false, msg);
234                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
235                                 }
236                         } else
237                         // Example: /user <-- create user
238                         if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/user")) {
239                                 try {
240                                         EcompUser user = mapper.readValue(requestBody, EcompUser.class);
241                                         pushUser(user);
242                                         logger.debug("doPost: pushUser: success");
243                                         responseJson = buildJsonResponse(true, null);
244                                         response.setStatus(HttpServletResponse.SC_OK);
245                                 } catch (Exception ex) {
246                                         responseJson = buildJsonResponse(ex);
247                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
248                                         logger.error("doPost: pushUser: caught exception", ex);
249                                 }
250                         } else
251                         // Example: /user/fi241c <-- edit user fi241c
252                         if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !(requestUri.endsWith("/roles"))) {
253                                 String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1);
254                                 try {
255                                         EcompUser user = mapper.readValue(requestBody, EcompUser.class);
256                                         editUser(loginId, user);
257                                         logger.debug("doPost: editUser: success");
258                                         responseJson = buildJsonResponse(true, null);
259                                         response.setStatus(HttpServletResponse.SC_OK);
260                                 } catch (Exception ex) {
261                                         responseJson = buildJsonResponse(ex);
262                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
263                                         logger.error("doPost: editUser: caught exception", ex);
264                                 }
265                         } else
266                         // Example: /user/{loginId}/roles <-- save roles for user
267                         if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) {
268                                 String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1,
269                                                 requestUri.lastIndexOf('/'));
270                                 try {
271                                         TypeReference<List<EcompRole>> typeRef = new TypeReference<List<EcompRole>>() {
272                                         };
273                                         List<EcompRole> roles = mapper.readValue(requestBody, typeRef);
274                                         pushUserRole(loginId, roles);
275                                         logger.debug("doPost: pushUserRole: success");
276                                         responseJson = buildJsonResponse(true, null);
277                                         response.setStatus(HttpServletResponse.SC_OK);
278                                 } catch (Exception ex) {
279                                         responseJson = buildJsonResponse(ex);
280                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
281                                         logger.error("doPost: pushUserRole: caught exception", ex);
282                                 }
283                         } else {
284                                 String msg = "doPost: no match for request " + requestUri;
285                                 logger.warn(msg);
286                                 responseJson = buildJsonResponse(false, msg);
287                                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
288                         }
289                 } catch (Exception ex) {
290                         logger.error("doPost: Failed to process request " + requestUri, ex);
291                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
292                         responseJson = buildJsonResponse(ex);
293                 }
294
295                 writeAndFlush(response, APPLICATION_JSON, responseJson);
296
297         }
298
299         @Override
300         protected void doGet(HttpServletRequest request, HttpServletResponse response)
301                         throws IOException, ServletException {
302
303                 if (portalRestApiServiceImpl == null) {
304                         // Should never happen due to checks in init()
305                         logger.error("doGet: no service class instance");
306                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
307                         writeAndFlush(response, APPLICATION_JSON,
308                                         buildJsonResponse(false, "Misconfigured - no instance of service class"));
309                         return;
310                 }
311
312                 String requestUri = request.getRequestURI();
313                 String contentType = APPLICATION_JSON;
314                 String webAnalyticsContextPath = "/analytics";
315                 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + webAnalyticsContextPath)) {
316                         String responseString;
317                         String userId;
318                         try {
319                                 userId = getUserId(request);
320                         } catch (PortalAPIException e) {
321                                 logger.error("Issue with invoking getUserId implemenation !!! ", e);
322                                 throw new ServletException(e);
323                         }
324                         if (userId == null || userId.length() == 0) {
325                                 logger.debug("doGet: userId is null or empty");
326                                 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
327                                 responseString = buildJsonResponse(false, "Not authorized for " + webAnalyticsContextPath);
328                         } else {
329                                 // User ID obtained from request
330                                 try {
331                                         String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY);
332                                         // for now lets also pass uebkey as user name and password
333                                         contentType = "text/javascript";
334
335                                         responseString = RestWebServiceClient.getInstance().getPortalContent(webAnalyticsContextPath,
336                                                         userId, credential, null, credential, credential, true);
337                                         if (logger.isDebugEnabled())
338                                                 logger.debug("doGet: " + webAnalyticsContextPath + ": " + responseString);
339                                         response.setStatus(HttpServletResponse.SC_OK);
340                                 } catch (Exception ex) {
341                                         responseString = buildJsonResponse(ex);
342                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
343                                         logger.error("doGet: " + webAnalyticsContextPath + " caught exception", ex);
344                                 }
345                         }
346                         writeAndFlush(response, contentType, responseString);
347                         return;
348                 }
349
350                 boolean secure = false;
351                 try {
352                         secure = isAppAuthenticated(request);
353                 } catch (PortalAPIException ex) {
354                         logger.error("doGet: isAppAuthenticated threw exception", ex);
355                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
356                         writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Failed to authenticate request"));
357                         return;
358                 }
359
360                 if (!secure) {
361                         if (logger.isDebugEnabled())
362                                 logger.debug("doGet: isAppAuthenticated answered false");
363                         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
364                         writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Not authorized"));
365                         return;
366                 }
367
368                 String responseJson = null;
369                 try {
370                         // Ignore any request body in a GET.
371                         logger.debug("doGet: URI =  " + requestUri);
372
373                         /*
374                          * 1. /roles <-- get roles
375                          * 
376                          * 2. /user/{loginId} <-- get user
377                          * 
378                          * 3. /users <-- get all users
379                          * 
380                          * 4. /user/{loginId}/roles <-- get roles for user
381                          */
382
383                         if (requestUri.endsWith("/sessionTimeOuts")) {
384                                 responseJson = getSessionTimeOuts();
385                                 if (responseJson != null && responseJson.length() > 0) {
386                                         logger.debug("doGet: got session timeouts");
387                                         response.setStatus(HttpServletResponse.SC_OK);
388                                 } else {
389                                         String msg = "Failed to get session time outs";
390                                         logger.error("doGet: " + msg);
391                                         responseJson = buildJsonResponse(false, msg);
392                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
393                                 }
394                         } else
395                         // Example: /users <-- get all users
396                         if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/users")) {
397                                 try {
398                                         List<EcompUser> users = getUsers();
399                                         responseJson = mapper.writeValueAsString(users);
400                                         if (logger.isDebugEnabled())
401                                                 logger.debug("doGet: getUsers: " + responseJson);
402                                 } catch (Exception ex) {
403                                         responseJson = buildJsonResponse(ex);
404                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
405                                         logger.error("doGet: getUsers: caught exception", ex);
406                                 }
407                         } else
408                         // Example: /roles <-- get all roles
409
410                         if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/roles")) {
411                                 try {
412                                         List<EcompRole> roles = getAvailableRoles(getUserId(request));
413                                         responseJson = mapper.writeValueAsString(roles);
414                                         if (logger.isDebugEnabled())
415                                                 logger.debug("doGet: getAvailableRoles: " + responseJson);
416                                 } catch (Exception ex) {
417                                         responseJson = buildJsonResponse(ex);
418                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
419                                         logger.error("doGet: getAvailableRoles: caught exception", ex);
420                                 }
421                         } else
422                         // Example: /user/fi241c <-- get user fi241c
423                         if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !requestUri.endsWith("/roles")) {
424                                 String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1);
425                                 try {
426                                         EcompUser user = getUser(loginId);
427                                         responseJson = mapper.writeValueAsString(user);
428                                         if (logger.isDebugEnabled())
429                                                 logger.debug("doGet: getUser: " + responseJson);
430                                 } catch (Exception ex) {
431                                         responseJson = buildJsonResponse(ex);
432                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
433                                         logger.error("doGet: getUser: caught exception", ex);
434                                 }
435                         }
436                         // Example: /user/fi241c/roles <-- get roles for user fi241c
437                         else if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) {
438                                 String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1,
439                                                 requestUri.lastIndexOf('/'));
440                                 try {
441                                         List<EcompRole> roles = getUserRoles(loginId);
442                                         responseJson = mapper.writeValueAsString(roles);
443                                         if (logger.isDebugEnabled())
444                                                 logger.debug("doGet: getUserRoles: " + responseJson);
445                                 } catch (Exception ex) {
446                                         responseJson = buildJsonResponse(ex);
447                                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
448                                         logger.error("doGet: getUserRoles: caught exception", ex);
449                                 }
450                         } else {
451                                 logger.warn("doGet: no match found for request");
452                                 responseJson = buildJsonResponse(false, "No match for request");
453                                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
454                         }
455                 } catch (Exception ex) {
456                         logger.error("doGet: Failed to process request", ex);
457                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
458                         responseJson = buildJsonResponse(ex);
459                 }
460                 writeAndFlush(response, APPLICATION_JSON, responseJson);
461         }
462
463         public String getSessionTimeOuts() {
464                 return PortalTimeoutHandler.gatherSessionExtensions();
465         }
466
467         public boolean timeoutSession(String portalJSessionId) {
468                 return PortalTimeoutHandler.invalidateSession(portalJSessionId);
469         }
470
471         public boolean updateSessionTimeOuts(String sessionMap) {
472                 return PortalTimeoutHandler.updateSessionExtensions(sessionMap);
473         }
474
475         @Override
476         public void pushUser(EcompUser user) throws PortalAPIException {
477                 portalRestApiServiceImpl.pushUser(user);
478         }
479
480         @Override
481         public void editUser(String loginId, EcompUser user) throws PortalAPIException {
482                 portalRestApiServiceImpl.editUser(loginId, user);
483         }
484
485         @Override
486         public EcompUser getUser(String loginId) throws PortalAPIException {
487                 return portalRestApiServiceImpl.getUser(loginId);
488         }
489
490         @Override
491         public List<EcompUser> getUsers() throws PortalAPIException {
492                 return portalRestApiServiceImpl.getUsers();
493         }
494
495         @Override
496         public List<EcompRole> getAvailableRoles(String requestedLoginId) throws PortalAPIException {
497                 return portalRestApiServiceImpl.getAvailableRoles(requestedLoginId);
498         }
499
500         @Override
501         public void pushUserRole(String loginId, List<EcompRole> roles) throws PortalAPIException {
502                 portalRestApiServiceImpl.pushUserRole(loginId, roles);
503         }
504
505         @Override
506         public List<EcompRole> getUserRoles(String loginId) throws PortalAPIException {
507                 return portalRestApiServiceImpl.getUserRoles(loginId);
508         }
509
510         @Override
511         public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException {
512                 return portalRestApiServiceImpl.isAppAuthenticated(request);
513         }
514
515         /**
516          * Sets the content type and writes the response.
517          * 
518          * @param response
519          * @param contentType
520          * @param responseBody
521          * @throws IOException
522          */
523         private void writeAndFlush(HttpServletResponse response, String contentType, String responseBody)
524                         throws IOException {
525                 response.setContentType(contentType);
526                 PrintWriter out = response.getWriter();
527                 out.print(responseBody);
528                 out.flush();
529         }
530
531         /**
532          * Reads the request body and closes the input stream.
533          * 
534          * @param request
535          * @return String read from the request, the empty string if nothing is read.
536          * @throws IOException
537          */
538         private static String readRequestBody(HttpServletRequest request) throws IOException {
539
540                 String body = null;
541                 StringBuilder stringBuilder = new StringBuilder();
542                 BufferedReader bufferedReader = null;
543                 try {
544                         InputStream inputStream = request.getInputStream();
545                         if (inputStream != null) {
546                                 bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
547                                 char[] charBuffer = new char[1024];
548                                 int bytesRead = -1;
549                                 while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
550                                         stringBuilder.append(charBuffer, 0, bytesRead);
551                                 }
552                         } else {
553                                 stringBuilder.append("");
554                         }
555                 } finally {
556                         if (bufferedReader != null) {
557                                 try {
558                                         bufferedReader.close();
559                                 } catch (IOException ex) {
560                                         logger.error("readRequestBody", ex);
561                                 }
562                         }
563                 }
564                 body = stringBuilder.toString();
565                 return body;
566         }
567
568         /**
569          * Builds JSON object with status + message response body.
570          * 
571          * @param success
572          *            True to indicate success, false to signal failure.
573          * @param msg
574          *            Message to include in the response object; ignored if null.
575          * @return
576          * 
577          *         <pre>
578          * { "status" : "ok" (or "error"), "message": "some explanation" }
579          *         </pre>
580          */
581         private String buildJsonResponse(boolean success, String msg) {
582                 PortalAPIResponse response = new PortalAPIResponse(success, msg);
583                 String json = null;
584                 try {
585                         json = mapper.writeValueAsString(response);
586                 } catch (JsonProcessingException ex) {
587                         // Truly should never, ever happen
588                         logger.error("buildJsonResponse", ex);
589                         json = "{ \"status\": \"error\",\"message\":\"" + ex.toString() + "\" }";
590                 }
591                 return json;
592         }
593
594         /**
595          * Builds JSON object with status of error and message containing stack trace
596          * for the specified throwable.
597          * 
598          * @param t
599          *            Throwable with stack trace to use as message
600          * 
601          * @return
602          * 
603          *         <pre>
604          * { "status" : "error", "message": "some-big-stacktrace" }
605          *         </pre>
606          */
607         private String buildJsonResponse(Throwable t) {
608                 StringWriter sw = new StringWriter();
609                 PrintWriter pw = new PrintWriter(sw);
610                 t.printStackTrace(pw);
611                 return buildJsonResponse(false, sw.toString());
612         }
613
614         @Override
615         public String getUserId(HttpServletRequest request) throws PortalAPIException {
616                 return portalRestApiServiceImpl.getUserId(request);
617         }
618
619         public static IPortalRestAPIService getPortalRestApiServiceImpl() {
620                 return portalRestApiServiceImpl;
621         }
622
623         public static void setPortalRestApiServiceImpl(IPortalRestAPIService portalRestApiServiceImpl) {
624                 PortalRestAPIProxy.portalRestApiServiceImpl = portalRestApiServiceImpl;
625         }
626
627 }