From 83101a752fcebdc8bdfb23681f8fcf9e6cfa4bdc Mon Sep 17 00:00:00 2001 From: Vijayendra Bhamidipati Date: Thu, 23 Feb 2012 16:07:05 -0800 Subject: [PATCH] Bug 13127: API error text refer to database ids instead of uuids Description: Modified the IdentityTypeAdapter's custom serializer to identify whether this is an exception response that is being serialized, by checking if the idFieldName is set. If so, serialize both uuid and the uuidProperty (for eg, zoneId and "zoneId" (string)) and pass back the json representation of that. Modified XML serializer also to build a list of uuids+fieldnames. Introduced a new field "cserrorcode" in ExceptionResponse. This refers to an error code that can be according to the specific Exception being thrown. This will be serialized as usual. There shouldn't be any need to do a db lookup for conversion for these error codes. --- .../cloud/api/response/ExceptionResponse.java | 5 +- .../com/cloud/api/IdentityTypeAdapter.java | 12 +++- .../api/response/ApiResponseSerializer.java | 55 +++++++------------ .../cloud/server/ManagementServerImpl.java | 3 +- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/api/src/com/cloud/api/response/ExceptionResponse.java b/api/src/com/cloud/api/response/ExceptionResponse.java index 3369a687047..e58abe0882f 100644 --- a/api/src/com/cloud/api/response/ExceptionResponse.java +++ b/api/src/com/cloud/api/response/ExceptionResponse.java @@ -23,12 +23,15 @@ import com.google.gson.annotations.SerializedName; import java.util.ArrayList; public class ExceptionResponse extends BaseResponse { - @SerializedName("uuid") @Param(description="uuid associated with this error") + @SerializedName("uuidList") @Param(description="List of uuids associated with this error") private ArrayList idList = new ArrayList(); @SerializedName("errorcode") @Param(description="numeric code associated with this error") private Integer errorCode; + @SerializedName("cserrorcode") @Param(description="cloudstack error code associated with this error") + private Integer cserrorCode; + @SerializedName("errortext") @Param(description="the text associated with this error") private String errorText; diff --git a/server/src/com/cloud/api/IdentityTypeAdapter.java b/server/src/com/cloud/api/IdentityTypeAdapter.java index 441b6416d95..ba310c74a4d 100644 --- a/server/src/com/cloud/api/IdentityTypeAdapter.java +++ b/server/src/com/cloud/api/IdentityTypeAdapter.java @@ -49,7 +49,17 @@ public class IdentityTypeAdapter implements JsonSerializer, JsonD if(uuid == null) return context.serialize(null); - return new JsonPrimitive(uuid); + // Exceptions set the _idFieldName in the IdentityProxy structure. So if this field is not + // null, prepare a structure of uuid and idFieldName and return the json representation of that. + String idName = src.getidFieldName(); + if (idName != null) { + // Prepare a structure. + JsonObject jsonObj = new JsonObject(); + jsonObj.add("uuid", new JsonPrimitive(uuid)); + jsonObj.add("uuidProperty", new JsonPrimitive(idName)); + return jsonObj; + } + return new JsonPrimitive(uuid); } else { return new JsonPrimitive(String.valueOf(src.getValue())); } diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index 3b5e11efc81..55d54483a89 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -96,37 +96,9 @@ 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()); + String jsonErrorText = gson.toJson((ExceptionResponse) result); jsonErrorText = unescape(jsonErrorText); - sb.append("{\"errorcode\" : " + ((ExceptionResponse) result).getErrorCode() + ", \"errortext\" : " + jsonErrorText + "}"); - // Since the IdentityTypeAdapter only converts the uuid, let's append each idFieldName explicitly. - // Iterate through the list of IdentityProxy objects if any, in the exception. - ArrayList idListref = ((ExceptionResponse) result).getIdProxyList(); - if (idListref != null) { - // Get each uuid from the list IdentityProxy objects. - if (!idListref.isEmpty()) { - // bump off the } at the end. We'll re-add it after the idFieldName. - sb.deleteCharAt(sb.length()-1); - sb.append(","); - for (int i=0; i < idListref.size(); i++) { - IdentityProxy id = idListref.get(i); - String idFieldName = id.getidFieldName(); - String jsonuuidText = gson.toJson(id); - jsonuuidText = unescape(jsonuuidText); - sb.append("{\"uuid\":" + jsonuuidText); - if (idFieldName != null) { - sb.append(",\"uuidProperty\":" + "\"" + idFieldName + "\"" + "}"); - } - if(i < (idListref.size()-1)) { - // more elements to come - sb.append(","); - } - } - // At the end of this, we'll have a response that looks like {"errorcode: " , "errortext" : , {"uuid":, "uuidProperty":} {"uuid":, "uuidProperty":}} - // re-add the } at the end. - sb.append("}"); - } - } + sb.append(jsonErrorText); } else { String jsonStr = gson.toJson(result); if ((jsonStr != null) && !"".equals(jsonStr)) { @@ -231,7 +203,8 @@ public class ApiResponseSerializer { sb.append(""); } } else if (fieldValue instanceof List) { - List subResponseList = (List) fieldValue; + List subResponseList = (List) fieldValue; + boolean usedUuidList = false; for (Object value : subResponseList) { if (value instanceof ResponseObject) { ResponseObject subObj = (ResponseObject) value; @@ -240,20 +213,30 @@ public class ApiResponseSerializer { } serializeResponseObjXML(sb, subObj); } else if (value instanceof IdentityProxy) { - IdentityProxy idProxy = (IdentityProxy)value; + IdentityProxy idProxy = (IdentityProxy)value; String id = (idProxy.getValue() != null ? String.valueOf(idProxy.getValue()) : ""); if(!id.isEmpty()) { IdentityDao identityDao = new IdentityDaoImpl(); id = identityDao.getIdentityUuid(idProxy.getTableName(), id); + } + if(id != null && !id.isEmpty()) { + // If this is the first IdentityProxy field encountered, put in a uuidList tag. + if (!usedUuidList) { + sb.append("<" + serializedName.value() + ">"); + usedUuidList = true; + } + sb.append("<" + "uuid" + ">" + id + ""); } - if(id != null && !id.isEmpty()) - sb.append("<" + serializedName.value() + ">" + id + ""); // Append the new idFieldName property also. String idFieldName = idProxy.getidFieldName(); if (idFieldName != null) { - sb.append("<" + "uuidProperty" + ">" + idFieldName + ""); + sb.append("<" + "uuidProperty" + ">" + idFieldName + ""); } - } + } + } + if (usedUuidList) { + // close the uuidList. + sb.append(""); } } else if (fieldValue instanceof Date) { sb.append("<" + serializedName.value() + ">" + BaseCmd.getDateString((Date) fieldValue) + ""); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 334dafd14fe..4e19c984446 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1837,8 +1837,7 @@ public class ManagementServerImpl implements ManagementServer { if (!domains.isEmpty() && !sameDomain) { InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system"); - ex.addProxyObject("domain", domainId, "domainId"); - ex.addProxyObject("domain", domainId, "domainId"); + ex.addProxyObject("domain", domainId, "domainId"); throw ex; } }