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 2013/12/20 13:52:49 UTC
svn commit: r1552631 - in /syncope/trunk:
common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java
core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java
Author: ilgrosso
Date: Fri Dec 20 12:52:49 2013
New Revision: 1552631
URL: http://svn.apache.org/r1552631
Log:
[SYNCOPE_464] Added ErrorTO that will display error details (as XML or JSON)
Added:
syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java (with props)
Modified:
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/utils/RestServiceExceptionMapper.java
Added: syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java?rev=1552631&view=auto
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java (added)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java Fri Dec 20 12:52:49 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.
+ */
+package org.apache.syncope.common.reqres;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.AbstractBaseBean;
+import org.apache.syncope.common.types.ClientExceptionType;
+
+@XmlRootElement(name = "error")
+@XmlType
+public class ErrorTO extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 2435764161719225927L;
+
+ private int status;
+
+ private ClientExceptionType type;
+
+ private final List<Object> elements = new ArrayList<Object>();
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(final int status) {
+ this.status = status;
+ }
+
+ public ClientExceptionType getType() {
+ return type;
+ }
+
+ public void setType(final ClientExceptionType type) {
+ this.type = type;
+ }
+
+ @XmlElementWrapper(name = "elements")
+ @XmlElement(name = "element")
+ @JsonProperty("elements")
+ public List<Object> getElements() {
+ return elements;
+ }
+
+}
Propchange: syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/trunk/common/src/main/java/org/apache/syncope/common/reqres/ErrorTO.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1552631&r1=1552630&r2=1552631&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 Dec 20 12:52:49 2013
@@ -18,23 +18,28 @@
*/
package org.apache.syncope.core.rest.utils;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityExistsException;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import javax.ws.rs.BadRequestException;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.syncope.common.types.EntityViolationType;
import org.apache.syncope.common.types.ClientExceptionType;
import org.apache.syncope.common.types.RESTHeaders;
import org.apache.syncope.common.SyncopeClientCompositeException;
import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.reqres.ErrorTO;
import org.apache.syncope.core.persistence.dao.MissingConfKeyException;
import org.apache.syncope.core.persistence.dao.NotFoundException;
import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException;
@@ -60,56 +65,53 @@ public class RestServiceExceptionMapper
public Response toResponse(final Exception ex) {
LOG.error("Exception thrown by REST method: " + ex.getMessage(), ex);
+ ResponseBuilder builder;
+
if (ex instanceof SyncopeClientException) {
SyncopeClientException sce = (SyncopeClientException) ex;
- return (sce.isComposite()
+ builder = sce.isComposite()
? getSyncopeClientCompositeExceptionResponse(sce.asComposite())
- : getSyncopeClientExceptionResponse(sce));
- }
-
- if (ex instanceof AccessDeniedException) {
- return Response.status(Response.Status.UNAUTHORIZED).
- header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED).
- build();
- }
-
- if (ex instanceof UnauthorizedRoleException) {
- return buildResponse(Response.status(Response.Status.UNAUTHORIZED),
- ClientExceptionType.UnauthorizedRole,
- getExMessage(ex));
- }
-
- if (ex instanceof EntityExistsException) {
- return buildResponse(Response.status(Response.Status.CONFLICT),
- ClientExceptionType.EntityExists,
- getExMessage(ex));
- }
-
- if (ex instanceof DataIntegrityViolationException) {
- return buildResponse(Response.status(Response.Status.CONFLICT),
- ClientExceptionType.DataIntegrityViolation,
- getExMessage(ex));
- }
-
- Response response = processNotFoundExceptions(ex);
- if (response != null) {
- return response;
- }
-
- response = processInvalidEntityExceptions(ex);
- if (response != null) {
- return response;
- }
-
- response = processBadRequestExceptions(ex);
- if (response != null) {
- return response;
+ : getSyncopeClientExceptionResponse(sce);
+ } else if (ex instanceof WebApplicationException) {
+ Response response = ((WebApplicationException) ex).getResponse();
+
+ ErrorTO error = new ErrorTO();
+ error.setStatus(response.getStatus());
+ error.setType(ClientExceptionType.Unknown);
+ error.getElements().add(getExMessage(ex));
+
+ builder = JAXRSUtils.fromResponse(response).entity(error);
+ } else if (ex instanceof AccessDeniedException) {
+ builder = Response.status(Response.Status.UNAUTHORIZED).
+ header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED);
+ } else if (ex instanceof UnauthorizedRoleException) {
+ builder = builder(Response.Status.UNAUTHORIZED, ClientExceptionType.UnauthorizedRole, getExMessage(ex));
+ } else if (ex instanceof EntityExistsException) {
+ builder = builder(Response.Status.CONFLICT, ClientExceptionType.EntityExists, getExMessage(ex));
+ } else if (ex instanceof DataIntegrityViolationException) {
+ builder = builder(Response.Status.CONFLICT, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
+ } else {
+ builder = processNotFoundExceptions(ex);
+ if (builder == null) {
+ builder = processInvalidEntityExceptions(ex);
+ if (builder == null) {
+ builder = processBadRequestExceptions(ex);
+ }
+ // ...or just report as InternalServerError
+ if (builder == null) {
+ builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+ header(ClientExceptionType.Unknown.getElementHeaderName(), getExMessage(ex));
+
+ ErrorTO error = new ErrorTO();
+ error.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ error.setType(ClientExceptionType.Unknown);
+ error.getElements().add(getExMessage(ex));
+ builder.entity(error);
+ }
+ }
}
- // Rest is interpreted as InternalServerError
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
- header(ClientExceptionType.Unknown.getElementHeaderName(), getExMessage(ex)).
- build();
+ return builder.build();
}
@Override
@@ -118,47 +120,60 @@ public class RestServiceExceptionMapper
"Call of fromResponse() method is not expected in RestServiceExceptionMapper");
}
- private Response getSyncopeClientExceptionResponse(final SyncopeClientException ex) {
- ResponseBuilder responseBuilder = Response.status(ex.getType().getResponseStatus());
- responseBuilder.header(RESTHeaders.EXCEPTION_TYPE, ex.getType().getHeaderValue());
+ private ResponseBuilder getSyncopeClientExceptionResponse(final SyncopeClientException ex) {
+ ResponseBuilder builder = Response.status(ex.getType().getResponseStatus());
+ builder.header(RESTHeaders.EXCEPTION_TYPE, ex.getType().getHeaderValue());
+
+ ErrorTO error = new ErrorTO();
+ error.setStatus(ex.getType().getResponseStatus().getStatusCode());
+ error.setType(ex.getType());
for (Object element : ex.getElements()) {
- responseBuilder.header(ex.getType().getElementHeaderName(), element);
+ builder.header(ex.getType().getElementHeaderName(), element);
+ error.getElements().add(element);
}
- return responseBuilder.build();
+ return builder.entity(error);
}
- private Response getSyncopeClientCompositeExceptionResponse(final SyncopeClientCompositeException ex) {
+ private ResponseBuilder getSyncopeClientCompositeExceptionResponse(final SyncopeClientCompositeException ex) {
if (ex.getExceptions().size() == 1) {
return getSyncopeClientExceptionResponse(ex.getExceptions().iterator().next());
}
- ResponseBuilder responseBuilder = Response.status(Response.Status.BAD_REQUEST);
+ ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
+
+ List<ErrorTO> errors = new ArrayList<ErrorTO>();
for (SyncopeClientException sce : ex.getExceptions()) {
- responseBuilder.header(RESTHeaders.EXCEPTION_TYPE, sce.getType().getHeaderValue());
+ builder.header(RESTHeaders.EXCEPTION_TYPE, sce.getType().getHeaderValue());
+
+ ErrorTO error = new ErrorTO();
+ error.setStatus(sce.getType().getResponseStatus().getStatusCode());
+ error.setType(sce.getType());
for (Object element : sce.getElements()) {
- responseBuilder.header(sce.getType().getElementHeaderName(), element);
+ builder.header(sce.getType().getElementHeaderName(), element);
+ error.getElements().add(element);
}
+
+ errors.add(error);
}
- return responseBuilder.build();
- }
- private Response processNotFoundExceptions(final Exception ex) {
- ResponseBuilder responseBuilder = Response.status(Response.Status.NOT_FOUND);
+ return builder.entity(errors);
+ }
+ private ResponseBuilder processNotFoundExceptions(final Exception ex) {
if (ex instanceof javax.ws.rs.NotFoundException || ex instanceof NotFoundException) {
- return buildResponse(responseBuilder, ClientExceptionType.NotFound, getExMessage(ex));
+ return builder(Response.Status.NOT_FOUND, ClientExceptionType.NotFound, getExMessage(ex));
} else if (ex instanceof MissingConfKeyException) {
- return buildResponse(responseBuilder, ClientExceptionType.NotFound,
+ return builder(Response.Status.NOT_FOUND, ClientExceptionType.NotFound,
getMessage(ex, ((MissingConfKeyException) ex).getConfKey()));
}
return null;
}
- private Response processInvalidEntityExceptions(final Exception ex) {
+ private ResponseBuilder processInvalidEntityExceptions(final Exception ex) {
InvalidEntityException iee = null;
if (ex instanceof InvalidEntityException) {
@@ -171,58 +186,67 @@ public class RestServiceExceptionMapper
}
if (iee != null) {
- ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
-
ClientExceptionType exType = ClientExceptionType.valueOf("Invalid" + iee.getEntityClassSimpleName());
+ ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
builder.header(RESTHeaders.EXCEPTION_TYPE, exType.getHeaderValue());
+ ErrorTO error = new ErrorTO();
+ error.setStatus(exType.getResponseStatus().getStatusCode());
+ error.setType(exType);
+
for (Map.Entry<Class<?>, Set<EntityViolationType>> violation : iee.getViolations().entrySet()) {
for (EntityViolationType violationType : violation.getValue()) {
builder.header(exType.getElementHeaderName(),
violationType.name() + ": " + violationType.getMessage());
+ error.getElements().add(violationType.name() + ": " + violationType.getMessage());
}
}
- return builder.build();
+ return builder;
}
return null;
}
- private Response processBadRequestExceptions(final Exception ex) {
- ResponseBuilder responseBuilder = Response.status(Response.Status.BAD_REQUEST);
+ private ResponseBuilder processBadRequestExceptions(final Exception ex) {
+ ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
if (ex instanceof BadRequestException) {
if (((BadRequestException) ex).getResponse() == null) {
- return responseBuilder.build();
+ return builder;
} else {
- return ((BadRequestException) ex).getResponse();
+ return JAXRSUtils.fromResponse(((BadRequestException) ex).getResponse());
}
} else if (ex instanceof WorkflowException) {
- return buildResponse(responseBuilder, ClientExceptionType.Workflow, getExMessage(ex));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.Workflow, getExMessage(ex));
} else if (ex instanceof PersistenceException) {
- return buildResponse(responseBuilder, ClientExceptionType.GenericPersistence, getExMessage(ex));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.GenericPersistence, getExMessage(ex));
} else if (ex instanceof org.apache.ibatis.exceptions.PersistenceException) {
- return buildResponse(responseBuilder, ClientExceptionType.Workflow, getMessage(ex,
- "Currently unavailable. Please try later."));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.Workflow,
+ getMessage(ex, "Currently unavailable. Please try later."));
} else if (ex instanceof JpaSystemException) {
- return buildResponse(responseBuilder, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
} else if (ex instanceof ConfigurationException) {
- return buildResponse(responseBuilder, ClientExceptionType.InvalidConnIdConf, getExMessage(ex));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.InvalidConnIdConf, getExMessage(ex));
} else if (ex instanceof ParsingValidationException) {
- return buildResponse(responseBuilder, ClientExceptionType.InvalidValues, getExMessage(ex));
+ return builder(Response.Status.BAD_REQUEST, ClientExceptionType.InvalidValues, getExMessage(ex));
}
return null;
}
- private Response buildResponse(final ResponseBuilder responseBuilder, final ClientExceptionType hType,
- final String msg) {
+ 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);
+
+ ErrorTO error = new ErrorTO();
+ error.setStatus(status.getStatusCode());
+ error.setType(hType);
+ error.getElements().add(msg);
- return responseBuilder.header(RESTHeaders.EXCEPTION_TYPE, hType.getHeaderValue()).
- header(hType.getElementHeaderName(), msg).
- build();
+ return builder.entity(error);
}
private String getMessage(final Throwable ex, final String msg) {