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