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