Updated Branches:
  refs/heads/master 32499e86b -> f3e0efc4f

REST exception handling modifications


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/f3e0efc4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/f3e0efc4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/f3e0efc4

Branch: refs/heads/master
Commit: f3e0efc4f655073d99adf711cfed4875f1fceace
Parents: 32499e8
Author: Pradeep Fernando <[email protected]>
Authored: Tue Dec 17 11:48:11 2013 +0530
Committer: Pradeep Fernando <[email protected]>
Committed: Tue Dec 17 11:48:11 2013 +0530

----------------------------------------------------------------------
 .../org/apache/stratos/rest/endpoint/Utils.java | 40 ++++++++++++++++++++
 .../endpoint/exception/RestAPIException.java    | 20 ++++++++++
 .../handlers/CustomExceptionMapper.java         | 37 ++++++++++++++++++
 .../handlers/StratosAuthenticationHandler.java  | 19 ++++++++--
 .../handlers/StratosAuthorizingHandler.java     | 14 +++++--
 .../rest/endpoint/services/StratosAdmin.java    |  2 +-
 .../src/main/webapp/WEB-INF/cxf-servlet.xml     |  2 +
 .../src/main/webapp/WEB-INF/web.xml             |  4 +-
 8 files changed, 128 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/Utils.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/Utils.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/Utils.java
new file mode 100644
index 0000000..638fb63
--- /dev/null
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/Utils.java
@@ -0,0 +1,40 @@
+package org.apache.stratos.rest.endpoint;/*
+*  Copyright (c) 2005-2012, WSO2 Inc. (http://www.wso2.org) All Rights 
Reserved.
+*
+*  WSO2 Inc. licenses this file to you under the Apache License,
+*  Version 2.0 (the "License"); you may not use this file except
+*  in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+public class Utils {
+
+
+    public static String buildMessage(int errorCode, String errorMessage) {
+        String jsonResponse = "{\"Error\":{" +
+                " \"errorCode\": \" " + errorCode + "\"," +
+                " \"errorMessage\": \" " + errorMessage + "\"," +
+                "}" +
+                "}";
+        return jsonResponse;
+    }
+
+    public static String buildMessage(String errorMessage) {
+        String jsonResponse = "{\"Error\":{" +
+                " \"errorCode\": \" " + -1234 + "\"," +
+                " \"errorMessage\": \" " + errorMessage + "\"," +
+                "}" +
+                "}";
+        return jsonResponse;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/exception/RestAPIException.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/exception/RestAPIException.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/exception/RestAPIException.java
index c483fef..f10d2a2 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/exception/RestAPIException.java
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/exception/RestAPIException.java
@@ -19,11 +19,14 @@
 
 package org.apache.stratos.rest.endpoint.exception;
 
+import javax.ws.rs.core.Response;
+
 public class RestAPIException extends Exception {
 
     private static final long serialVersionUID = 1L;
 
     private String message;
+    private Response.Status httpStatusCode;
 
     public RestAPIException() {
         super();
@@ -34,11 +37,23 @@ public class RestAPIException extends Exception {
         this.message = message;
     }
 
+    public RestAPIException(Response.Status httpStatusCode,String message, 
Throwable cause) {
+        super(message, cause);
+        this.message = message;
+        this.httpStatusCode = httpStatusCode;
+    }
+
     public RestAPIException(String message) {
         super(message);
         this.message = message;
     }
 
+    public RestAPIException(Response.Status httpStatusCode, String message) {
+        super(message);
+        this.message = message;
+        this.httpStatusCode = httpStatusCode;
+    }
+
     public RestAPIException(Throwable cause) {
         super(cause);
     }
@@ -47,4 +62,9 @@ public class RestAPIException extends Exception {
         return message;
     }
 
+    public Response.Status getHTTPStatusCode() {
+        return httpStatusCode;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/CustomExceptionMapper.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/CustomExceptionMapper.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/CustomExceptionMapper.java
new file mode 100644
index 0000000..3fe6ea4
--- /dev/null
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/CustomExceptionMapper.java
@@ -0,0 +1,37 @@
+package org.apache.stratos.rest.endpoint.handlers;/*
+*  Copyright (c) 2005-2012, WSO2 Inc. (http://www.wso2.org) All Rights 
Reserved.
+*
+*  WSO2 Inc. licenses this file to you under the Apache License,
+*  Version 2.0 (the "License"); you may not use this file except
+*  in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import org.apache.stratos.rest.endpoint.Utils;
+import org.apache.stratos.rest.endpoint.exception.RestAPIException;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+public class CustomExceptionMapper implements 
ExceptionMapper<RestAPIException> {
+    public Response toResponse(RestAPIException restAPIException) {
+        // if no specific error message specified, spitting out a generaic 
error message
+        String errorMessage = (restAPIException.getMessage() != null)?
+                restAPIException.getMessage():"Error while fullfilling the 
request";
+        // if no specific error specified we are throwing the bad request http 
status code by default
+        Response.Status httpStatus= (restAPIException.getHTTPStatusCode() != 
null)?
+                
restAPIException.getHTTPStatusCode():Response.Status.BAD_REQUEST;
+        return 
Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).
+                
entity(Utils.buildMessage(httpStatus.getStatusCode(),errorMessage)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthenticationHandler.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthenticationHandler.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthenticationHandler.java
index 457026d..f9a42fd 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthenticationHandler.java
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthenticationHandler.java
@@ -26,6 +26,8 @@ import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.stratos.rest.endpoint.ServiceHolder;
+import org.apache.stratos.rest.endpoint.Utils;
+import org.apache.stratos.rest.endpoint.exception.RestAPIException;
 import org.apache.stratos.rest.endpoint.security.StratosSecurityContext;
 import org.wso2.carbon.context.PrivilegedCarbonContext;
 import org.wso2.carbon.core.common.AuthenticationException;
@@ -35,6 +37,7 @@ import org.wso2.carbon.user.api.UserRealm;
 import org.wso2.carbon.user.core.service.RealmService;
 import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
 
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 /**
@@ -61,7 +64,8 @@ public class StratosAuthenticationHandler implements 
RequestHandler {
         if ((username == null) || (password == null) || username.equals("")
                 || password.equals("")) {
             log.error("username or password is seen as null/empty values.");
-            return Response.status(401).header("WWW-Authenticate", 
"Basic").build();
+            return 
Response.status(Response.Status.UNAUTHORIZED).header("WWW-Authenticate", 
"Basic").
+                    
type(MediaType.APPLICATION_JSON).entity(Utils.buildMessage("Username/Password 
cannot be null")).build();
         }
         try {
             RealmService realmService = ServiceHolder.getRealmService();
@@ -72,7 +76,9 @@ public class StratosAuthenticationHandler implements 
RequestHandler {
             UserRealm userRealm = 
AnonymousSessionUtil.getRealmByTenantDomain(registryService, realmService, 
tenantDomain);
             if (userRealm == null) {
                 log .error("Invalid domain or unactivated tenant login");
-                throw new AuthenticationException("Invalid domain or 
unactivated tenant login");
+                // is this the correct HTTP code for this scenario ? (401)
+                return 
Response.status(Response.Status.UNAUTHORIZED).header("WWW-Authenticate", 
"Basic").
+                        
type(MediaType.APPLICATION_JSON).entity(Utils.buildMessage("Tenant not 
found")).build();
             }
             username = MultitenantUtils.getTenantAwareUsername(username);
             if (userRealm.getUserStoreManager().authenticate(username, 
password)) {  // if authenticated
@@ -90,10 +96,15 @@ public class StratosAuthenticationHandler implements 
RequestHandler {
             } else {
                 log.warn("unable to authenticate the request");
                 // authentication failed, request the authetication, add the 
realm name if needed to the value of WWW-Authenticate
-                return Response.status(401).header("WWW-Authenticate", 
"Basic").build();
+                return 
Response.status(Response.Status.UNAUTHORIZED).header("WWW-Authenticate", 
"Basic").
+                        
type(MediaType.APPLICATION_JSON).entity(Utils.buildMessage("Authentication 
failed. Please " +
+                        "check your username/password")).build();
             }
         } catch (Exception exception) {
-            return Response.status(401).header("WWW-Authenticate", 
"Basic").build();
+            log.error("Authentication failed",exception);
+            // server error in the eyes of the client. Hence 5xx HTTP code.
+            return 
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON).
+                    entity(Utils.buildMessage("Unexpected error. Please 
contact the system admin")).build();
         }
 
     }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthorizingHandler.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthorizingHandler.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthorizingHandler.java
index 3227df2..0902182 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthorizingHandler.java
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/handlers/StratosAuthorizingHandler.java
@@ -29,6 +29,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.service.Service;
 import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.stratos.rest.endpoint.Utils;
 import org.wso2.carbon.context.CarbonContext;
 import org.wso2.carbon.context.PrivilegedCarbonContext;
 import org.wso2.carbon.user.api.AuthorizationManager;
@@ -36,6 +37,7 @@ import org.wso2.carbon.user.api.UserRealm;
 import org.wso2.carbon.user.api.UserStoreException;
 import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
 
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
@@ -69,12 +71,18 @@ public class StratosAuthorizingHandler implements 
RequestHandler {
             SecurityContext securityContext = 
message.get(SecurityContext.class);
             Method method = getTargetMethod(message);
             if (!authorize(securityContext, method)) {
-               return Response.status(Response.Status.FORBIDDEN).build();
+               log.warn("User :"+ securityContext.getUserPrincipal().getName() 
+ "trying to perform unauthrorized action" +
+                       " against the resource :"+ method);
+               return 
Response.status(Response.Status.FORBIDDEN).type(MediaType.APPLICATION_JSON).
+                       entity(Utils.buildMessage("The user does not have 
required permissions to " +
+                               "perform this operation")).build();
             }
             return null;
 
-        } catch (Exception ex) {
-            return Response.status(Response.Status.FORBIDDEN).build();
+        } catch (Exception exception) {
+            log.error("Unexpercted error occured while REST api, authorization 
process",exception);
+            return 
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON).
+                    entity(Utils.buildMessage("Unexpected error. Please 
contact the system admin")).build();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/services/StratosAdmin.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/services/StratosAdmin.java
 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/services/StratosAdmin.java
index 850a8ff..bdc7c00 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/services/StratosAdmin.java
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/services/StratosAdmin.java
@@ -331,7 +331,7 @@ public class StratosAdmin extends AbstractAdmin {
     @AuthorizationAction("/permission/protected/manage/monitor/tenants")
     public void unsubscribe(String alias){
         try {
-            ServiceUtils.unsubscribe(alias,getTenantDomain());
+            ServiceUtils.unsubscribe(alias, getTenantDomain());
         } catch (Exception exception) {
             log.error(exception);
         }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml
 
b/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml
index 32164e2..dfb7263 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -31,6 +31,7 @@
         </jaxrs:serviceBeans>
 
         <jaxrs:providers>
+            <ref bean="exceptionHandler"/>
             <ref bean="authenticationFilter"/>
             <ref bean="authorizationFilter"/>
         </jaxrs:providers>
@@ -46,6 +47,7 @@
     <bean id="authorizationFilter" 
class="org.apache.stratos.rest.endpoint.handlers.StratosAuthorizingHandler">
         <property name="securedObject" ref="stratosRestEndpointBean"/>
     </bean>
+    <bean id="exceptionHandler" 
class="org.apache.stratos.rest.endpoint.handlers.CustomExceptionMapper"/>
 
     <!--The below config enables OAuth based authentication/authorization for 
REST API-->
     <!--bean id="OAuthFilter" 
class="org.apache.stratos.rest.endpoint.handlers.OAuthHandler">

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/f3e0efc4/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/web.xml 
b/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/web.xml
index 9e8eb4d..7cef351 100644
--- 
a/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/web.xml
+++ 
b/components/org.apache.stratos.rest.endpoint/src/main/webapp/WEB-INF/web.xml
@@ -26,13 +26,13 @@
     <display-name>S2 Admin Endpoint</display-name>
 
     <servlet>
-        <servlet-name>S2AdminEndpoint</servlet-name>
+        <servlet-name>StratosAdminEndpoint</servlet-name>
         
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
         <load-on-startup>1</load-on-startup>
     </servlet>
 
     <servlet-mapping>
-        <servlet-name>S2AdminEndpoint</servlet-name>
+        <servlet-name>StratosAdminEndpoint</servlet-name>
         <url-pattern>/*</url-pattern>
     </servlet-mapping>
 

Reply via email to