diff --git a/api/src/com/cloud/api/response/ExceptionResponse.java b/api/src/com/cloud/api/response/ExceptionResponse.java index 49542de481e..b200f8c8170 100644 --- a/api/src/com/cloud/api/response/ExceptionResponse.java +++ b/api/src/com/cloud/api/response/ExceptionResponse.java @@ -17,10 +17,14 @@ */ package com.cloud.api.response; +import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; public class ExceptionResponse extends BaseResponse { + @SerializedName("uuid") @Param(description="uuid associated with this error") + private IdentityProxy id; + @SerializedName("errorcode") @Param(description="numeric code associated with this error") private Integer errorCode; @@ -42,4 +46,15 @@ public class ExceptionResponse extends BaseResponse { public void setErrorText(String errorText) { this.errorText = errorText; } + + public void setProxyObject(String table_name, Long id) { + this.id = new IdentityProxy(); + this.id.setTableName(table_name); + this.id.setValue(id); + return; + } + + public IdentityProxy getProxyObject() { + return id; + } } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index b9d3d29ac11..43165f47d70 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -350,7 +350,7 @@ public class ApiServer implements HttpRequestHandler { writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null); } catch (ServerApiException se) { - String responseText = getSerializedApiError(se.getErrorCode(), se.getDescription(), parameterMap, responseType); + String responseText = getSerializedApiError(se.getErrorCode(), se.getDescription(), parameterMap, responseType, se); writeResponse(response, responseText, se.getErrorCode(), responseType, se.getDescription()); sb.append(" " + se.getErrorCode() + " " + se.getDescription()); } catch (RuntimeException e) { @@ -434,7 +434,7 @@ public class ApiServer implements HttpRequestHandler { IdentityProxy id = ref.getProxyObject(); if (id != null) { e.setProxyObject(id.getTableName(), id.getValue()); - } + } throw e; } else if (ex instanceof PermissionDeniedException) { PermissionDeniedException ref = (PermissionDeniedException)ex; @@ -981,7 +981,7 @@ public class ApiServer implements HttpRequestHandler { } } - public String getSerializedApiError(int errorCode, String errorText, Map apiCommandParams, String responseType) { + public String getSerializedApiError(int errorCode, String errorText, Map apiCommandParams, String responseType, Exception ex) { String responseName = null; String cmdClassName = null; @@ -1009,12 +1009,41 @@ public class ApiServer implements HttpRequestHandler { apiResponse.setErrorCode(errorCode); apiResponse.setErrorText(errorText); apiResponse.setResponseName(responseName); - + // Also copy over the IdentityProxy object into this new apiResponse, from + // the exception caught. When invoked from handle(), the exception here can + // be either ServerApiException, PermissionDeniedException or InvalidParameterValue + // Exception. When invoked from ApiServlet's processRequest(), this can be + // a standard exception like NumberFormatException. We'll leave standard ones alone. + if (ex != null) { + if (ex instanceof ServerApiException || ex instanceof PermissionDeniedException + || ex instanceof InvalidParameterValueException) { + // Cast the exception appropriately and retrieve the IdentityProxy + if (ex instanceof ServerApiException) { + ServerApiException ref = (ServerApiException) ex; + IdentityProxy uuidproxy = ref.getProxyObject(); + if (uuidproxy != null) { + apiResponse.setProxyObject(uuidproxy.getTableName(), uuidproxy.getValue()); + } + } else if (ex instanceof PermissionDeniedException) { + PermissionDeniedException ref = (PermissionDeniedException) ex; + IdentityProxy uuidproxy = ref.getProxyObject(); + if (uuidproxy != null) { + apiResponse.setProxyObject(uuidproxy.getTableName(), uuidproxy.getValue()); + } + } else if (ex instanceof InvalidParameterValueException) { + InvalidParameterValueException ref = (InvalidParameterValueException) ex; + IdentityProxy uuidproxy = ref.getProxyObject(); + if (uuidproxy != null) { + apiResponse.setProxyObject(uuidproxy.getTableName(), uuidproxy.getValue()); + } + } + } + } SerializationContext.current().setUuidTranslation(true); responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType); } catch (Exception e) { - s_logger.error("Exception responding to http request", e); + s_logger.error("Exception responding to http request", e); } return responseText; } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 4e1fe904584..a293df9aa63 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -183,7 +183,7 @@ public class ApiServlet extends HttpServlet { s_logger.warn("Invalid domain id entered by user"); auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "Invalid domain id entered, please enter a valid one"); String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid domain id entered, please enter a valid one", params, - responseType); + responseType, null); writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType); } } @@ -220,7 +220,7 @@ public class ApiServlet extends HttpServlet { auditTrailSb.append(" " + BaseCmd.ACCOUNT_ERROR + " " + ex.getMessage() != null ? ex.getMessage() : "failed to authenticate user, check if username/password are correct"); String serializedResponse = _apiServer.getSerializedApiError(BaseCmd.ACCOUNT_ERROR, ex.getMessage() != null ? ex.getMessage() - : "failed to authenticate user, check if username/password are correct", params, responseType); + : "failed to authenticate user, check if username/password are correct", params, responseType, null); writeResponse(resp, serializedResponse, BaseCmd.ACCOUNT_ERROR, responseType); return; } @@ -248,7 +248,7 @@ public class ApiServlet extends HttpServlet { } catch (IllegalStateException ise) { } auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); - String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType); + String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType, null); writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType); return; } @@ -259,7 +259,7 @@ public class ApiServlet extends HttpServlet { if (command == null) { s_logger.info("missing command, ignoring request..."); auditTrailSb.append(" " + HttpServletResponse.SC_BAD_REQUEST + " " + "no command specified"); - String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType); + String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType, null); writeResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType); return; } @@ -274,7 +274,7 @@ public class ApiServlet extends HttpServlet { } auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); - String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType); + String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType, null); writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType); return; } @@ -302,7 +302,7 @@ public class ApiServlet extends HttpServlet { String response = _apiServer.handleRequest(params, false, responseType, auditTrailSb); writeResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType); } catch (ServerApiException se) { - String serializedResponseText = _apiServer.getSerializedApiError(se.getErrorCode(), se.getDescription(), params, responseType); + String serializedResponseText = _apiServer.getSerializedApiError(se.getErrorCode(), se.getDescription(), params, responseType, null); resp.setHeader("X-Description", se.getDescription()); writeResponse(resp, serializedResponseText, se.getErrorCode(), responseType); auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription()); @@ -316,14 +316,14 @@ public class ApiServlet extends HttpServlet { } auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials and/or request signature"); - String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature", params, responseType); + String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature", params, responseType, null); writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType); } } catch (Exception ex) { if (ex instanceof ServerApiException && ((ServerApiException) ex).getErrorCode() == BaseCmd.UNSUPPORTED_ACTION_ERROR) { ServerApiException se = (ServerApiException) ex; - String serializedResponseText = _apiServer.getSerializedApiError(se.getErrorCode(), se.getDescription(), params, responseType); + String serializedResponseText = _apiServer.getSerializedApiError(se.getErrorCode(), se.getDescription(), params, responseType, null); resp.setHeader("X-Description", se.getDescription()); writeResponse(resp, serializedResponseText, se.getErrorCode(), responseType); auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription()); diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index 920ce58799f..3500a7f9433 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -78,7 +78,7 @@ public class ApiResponseSerializer { if ((responses != null) && !responses.isEmpty()) { Integer count = ((ListResponse) result).getCount(); - String jsonStr = gson.toJson(responses.get(0)); + String jsonStr = gson.toJson(responses.get(0)); jsonStr = unescape(jsonStr); if (count != null && count != 0) { @@ -96,9 +96,10 @@ public class ApiResponseSerializer { } else if (result instanceof SuccessResponse) { sb.append("{ \"success\" : \"" + ((SuccessResponse) result).getSuccess() + "\"} "); } else if (result instanceof ExceptionResponse) { - String jsonErrorText =gson.toJson(((ExceptionResponse) result).getErrorText()); - jsonErrorText = unescape(jsonErrorText); - sb.append("{\"errorcode\" : " + ((ExceptionResponse) result).getErrorCode() + ", \"errortext\" : " + jsonErrorText + "} "); + // Convert into json the whole exception object and not just the error text. + String jsonErrorText = gson.toJson((ExceptionResponse) result); + jsonErrorText = unescape(jsonErrorText); + sb.append(jsonErrorText); } else { String jsonStr = gson.toJson(result); if ((jsonStr != null) && !"".equals(jsonStr)) { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index e0baf6859a1..fcd9c936a5c 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1836,7 +1836,9 @@ public class ManagementServerImpl implements ManagementServer { boolean sameDomain = (domains.size() == 1 && domains.get(0).getId() == domainId); if (!domains.isEmpty() && !sameDomain) { - throw new InvalidParameterValueException("Failed to update domain id=" + domainId + "; domain with name " + domainName + " already exists in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system"); + ex.setProxyObject("domain", domainId); + throw ex; } }