You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2014/05/30 14:29:19 UTC

svn commit: r1598567 - in /syncope/trunk: client/src/main/java/org/apache/syncope/client/rest/ common/src/main/java/org/apache/syncope/common/ common/src/main/java/org/apache/syncope/common/types/ core/src/main/java/org/apache/syncope/core/rest/utils/ ...

Author: ilgrosso
Date: Fri May 30 12:29:19 2014
New Revision: 1598567

URL: http://svn.apache.org/r1598567
Log:
[SYNCOPE-479] Now using X-Application-Error-Code and  X-Application-Error-Info header names for error reporting - more REST best practices

Modified:
    syncope/trunk/client/src/main/java/org/apache/syncope/client/rest/RestClientExceptionMapper.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/SyncopeClientException.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/services/AbstractServiceImpl.java

Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/rest/RestClientExceptionMapper.java
URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/rest/RestClientExceptionMapper.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/client/src/main/java/org/apache/syncope/client/rest/RestClientExceptionMapper.java (original)
+++ syncope/trunk/client/src/main/java/org/apache/syncope/client/rest/RestClientExceptionMapper.java Fri May 30 12:29:19 2014
@@ -27,6 +27,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.ExceptionMapper;
 import javax.ws.rs.ext.Provider;
 import javax.xml.ws.WebServiceException;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.types.RESTHeaders;
@@ -75,9 +76,9 @@ public class RestClientExceptionMapper i
     }
 
     private SyncopeClientCompositeException checkSyncopeClientCompositeException(final Response response) {
-        List<Object> exTypesInHeaders = response.getHeaders().get(RESTHeaders.EXCEPTION_TYPE.toString());
+        List<Object> exTypesInHeaders = response.getHeaders().get(RESTHeaders.ERROR_CODE);
         if (exTypesInHeaders == null) {
-            LOG.debug("No " + RESTHeaders.EXCEPTION_TYPE + " provided");
+            LOG.debug("No " + RESTHeaders.ERROR_CODE + " provided");
             return null;
         }
 
@@ -90,18 +91,22 @@ public class RestClientExceptionMapper i
             try {
                 exceptionType = ClientExceptionType.fromHeaderValue(exTypeAsString);
             } catch (IllegalArgumentException e) {
-                LOG.error("Unexpected value of " + RESTHeaders.EXCEPTION_TYPE + ": " + exTypeAsString, e);
+                LOG.error("Unexpected value of " + RESTHeaders.ERROR_CODE + ": " + exTypeAsString, e);
             }
             if (exceptionType != null) {
                 handledExceptions.add(exTypeAsString);
 
                 final SyncopeClientException clientException = SyncopeClientException.build(exceptionType);
 
-                if (response.getHeaders().get(exceptionType.getElementHeaderName()) != null
-                        && !response.getHeaders().get(exceptionType.getElementHeaderName()).isEmpty()) {
+                if (response.getHeaders().get(RESTHeaders.ERROR_INFO) != null
+                        && !response.getHeaders().get(RESTHeaders.ERROR_INFO).isEmpty()) {
 
-                    clientException.getElements().addAll(
-                            response.getHeaders().get(exceptionType.getElementHeaderName()));
+                    for (Object value : response.getHeaders().get(RESTHeaders.ERROR_INFO)) {
+                        final String element = value.toString();
+                        if (element.startsWith(exceptionType.getHeaderValue())) {
+                            clientException.getElements().add(StringUtils.substringAfter(value.toString(), ":"));
+                        }
+                    }
                 }
                 compException.addException(clientException);
             }

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/SyncopeClientException.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/SyncopeClientException.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/SyncopeClientException.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/SyncopeClientException.java Fri May 30 12:29:19 2014
@@ -28,7 +28,7 @@ public class SyncopeClientException exte
 
     private ClientExceptionType type;
 
-    private final List<Object> elements = new ArrayList<Object>();
+    private final List<String> elements = new ArrayList<String>();
 
     public static SyncopeClientException build(final ClientExceptionType type) {
         if (type == ClientExceptionType.Composite) {
@@ -66,7 +66,7 @@ public class SyncopeClientException exte
         this.type = type;
     }
 
-    public List<Object> getElements() {
+    public List<String> getElements() {
         return elements;
     }
 

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java Fri May 30 12:29:19 2014
@@ -91,8 +91,8 @@ public enum ClientExceptionType {
         return name();
     }
 
-    public String getElementHeaderName() {
-        return getHeaderValue() + ".element";
+    public String getInfoHeaderValue(final String value) {
+        return getHeaderValue() + ":" + value;
     }
 
     public Response.Status getResponseStatus() {

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java Fri May 30 12:29:19 2014
@@ -55,8 +55,15 @@ public final class RESTHeaders {
 
     /**
      * Declares the type of exception being raised.
+     *
+     * @see ClientExceptionType
+     */
+    public static final String ERROR_CODE = "X-Application-Error-Code";
+
+    /**
+     * Declares additional information for the exception being raised.
      */
-    public static final String EXCEPTION_TYPE = "Syncope.ExceptionType";
+    public static final String ERROR_INFO = "X-Application-Error-Info";
 
     /**
      * Mediatype for PNG images, not defined in <tt>javax.ws.rs.core.MediaType</tt>.

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java Fri May 30 12:29:19 2014
@@ -100,7 +100,8 @@ public class RestServiceExceptionMapper 
                 // ...or just report as InternalServerError
                 if (builder == null) {
                     builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).
-                            header(ClientExceptionType.Unknown.getElementHeaderName(), getExMessage(ex));
+                            header(RESTHeaders.ERROR_INFO,
+                                    ClientExceptionType.Unknown.getInfoHeaderValue(getExMessage(ex)));
 
                     ErrorTO error = new ErrorTO();
                     error.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
@@ -122,14 +123,14 @@ public class RestServiceExceptionMapper 
 
     private ResponseBuilder getSyncopeClientExceptionResponse(final SyncopeClientException ex) {
         ResponseBuilder builder = Response.status(ex.getType().getResponseStatus());
-        builder.header(RESTHeaders.EXCEPTION_TYPE, ex.getType().getHeaderValue());
+        builder.header(RESTHeaders.ERROR_CODE, ex.getType().getHeaderValue());
 
         ErrorTO error = new ErrorTO();
         error.setStatus(ex.getType().getResponseStatus().getStatusCode());
         error.setType(ex.getType());
 
-        for (Object element : ex.getElements()) {
-            builder.header(ex.getType().getElementHeaderName(), element);
+        for (String element : ex.getElements()) {
+            builder.header(RESTHeaders.ERROR_INFO, ex.getType().getInfoHeaderValue(element));
             error.getElements().add(element);
         }
 
@@ -145,14 +146,14 @@ public class RestServiceExceptionMapper 
 
         List<ErrorTO> errors = new ArrayList<ErrorTO>();
         for (SyncopeClientException sce : ex.getExceptions()) {
-            builder.header(RESTHeaders.EXCEPTION_TYPE, sce.getType().getHeaderValue());
+            builder.header(RESTHeaders.ERROR_CODE, sce.getType().getHeaderValue());
 
             ErrorTO error = new ErrorTO();
             error.setStatus(sce.getType().getResponseStatus().getStatusCode());
             error.setType(sce.getType());
 
-            for (Object element : sce.getElements()) {
-                builder.header(sce.getType().getElementHeaderName(), element);
+            for (String element : sce.getElements()) {
+                builder.header(RESTHeaders.ERROR_INFO, ex.getType().getInfoHeaderValue(element));
                 error.getElements().add(element);
             }
 
@@ -192,7 +193,7 @@ public class RestServiceExceptionMapper 
                     : ClientExceptionType.valueOf("Invalid" + iee.getEntityClassSimpleName());
 
             ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
-            builder.header(RESTHeaders.EXCEPTION_TYPE, exType.getHeaderValue());
+            builder.header(RESTHeaders.ERROR_CODE, exType.getHeaderValue());
 
             ErrorTO error = new ErrorTO();
             error.setStatus(exType.getResponseStatus().getStatusCode());
@@ -200,8 +201,8 @@ public class RestServiceExceptionMapper 
 
             for (Map.Entry<Class<?>, Set<EntityViolationType>> violation : iee.getViolations().entrySet()) {
                 for (EntityViolationType violationType : violation.getValue()) {
-                    builder.header(exType.getElementHeaderName(),
-                            violationType.name() + ": " + violationType.getMessage());
+                    builder.header(RESTHeaders.ERROR_INFO,
+                            exType.getInfoHeaderValue(violationType.name() + ": " + violationType.getMessage()));
                     error.getElements().add(violationType.name() + ": " + violationType.getMessage());
                 }
             }
@@ -241,8 +242,8 @@ public class RestServiceExceptionMapper 
 
     private ResponseBuilder builder(final Response.Status status, final ClientExceptionType hType, final String msg) {
         ResponseBuilder builder = Response.status(status).
-                header(RESTHeaders.EXCEPTION_TYPE, hType.getHeaderValue()).
-                header(hType.getElementHeaderName(), msg);
+                header(RESTHeaders.ERROR_CODE, hType.getHeaderValue()).
+                header(RESTHeaders.ERROR_INFO, hType.getInfoHeaderValue(msg));
 
         ErrorTO error = new ErrorTO();
         error.setStatus(status.getStatusCode());

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/AbstractServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/services/AbstractServiceImpl.java?rev=1598567&r1=1598566&r2=1598567&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/services/AbstractServiceImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/services/AbstractServiceImpl.java Fri May 30 12:29:19 2014
@@ -147,8 +147,8 @@ abstract class AbstractServiceImpl imple
             LOG.error("Invalid page / size specified: {},{}", page, size);
 
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPageOrSize);
-            sce.getElements().add(page);
-            sce.getElements().add(size);
+            sce.getElements().add(String.valueOf(page));
+            sce.getElements().add(String.valueOf(size));
             throw sce;
         }
     }