From 59c211fca7df48e3b5976ecf950e0c76764916e7 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 7 Jun 2013 20:28:43 -0700 Subject: [PATCH] Changed async manager to use it's own serializer --- .../jobs/impl/JobSerializerHelper.java | 75 +++++++++++++++++++ .../cloud/api/ResponseObjectTypeAdapter.java | 51 ++----------- .../com/cloud/async/AsyncJobManagerImpl.java | 10 +-- 3 files changed, 85 insertions(+), 51 deletions(-) diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java index 17dd1ccc276..33a1df79b37 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java @@ -22,12 +22,23 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import com.cloud.utils.exception.CloudRuntimeException; @@ -43,6 +54,7 @@ public class JobSerializerHelper { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setVersion(1.5); s_logger.debug("Job GSON Builder initialized."); + gsonBuilder.registerTypeAdapter(Class.class, new ClassTypeAdapter()); s_gson = gsonBuilder.create(); } @@ -124,4 +136,67 @@ public class JobSerializerHelper { throw new CloudRuntimeException("Unable to serialize: " + base64EncodedString, e); } } + + public static class ClassTypeAdapter implements JsonSerializer>, JsonDeserializer> { + @Override + public JsonElement serialize(Class clazz, Type typeOfResponseObj, JsonSerializationContext ctx) { + return new JsonPrimitive(clazz.getName()); + } + + @Override + public Class deserialize(JsonElement arg0, Type arg1, JsonDeserializationContext arg2) throws JsonParseException { + String str = arg0.getAsString(); + try { + return Class.forName(str); + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException("Unable to find class " + str); + } + } + } + + public static class ThrowableTypeAdapter implements JsonSerializer, JsonDeserializer { + + @Override + public Throwable deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException { + JsonObject obj = (JsonObject)json; + + String className = obj.get("class").getAsString(); + try { + Class clazz = (Class)Class.forName(className); + Throwable cause = s_gson.fromJson(obj.get("cause"), Throwable.class); + String msg = obj.get("msg").getAsString(); + Constructor constructor = clazz.getConstructor(String.class, Throwable.class); + Throwable th = constructor.newInstance(msg, cause); + return th; + } catch (ClassNotFoundException e) { + throw new JsonParseException("Unable to find " + className); + } catch (NoSuchMethodException e) { + throw new JsonParseException("Unable to find constructor for " + className); + } catch (SecurityException e) { + throw new JsonParseException("Unable to get over security " + className); + } catch (InstantiationException e) { + throw new JsonParseException("Unable to instantiate " + className); + } catch (IllegalAccessException e) { + throw new JsonParseException("Illegal access to " + className, e); + } catch (IllegalArgumentException e) { + throw new JsonParseException("Illegal argument to " + className, e); + } catch (InvocationTargetException e) { + throw new JsonParseException("Cannot invoke " + className, e); + } + } + + @Override + public JsonElement serialize(Throwable th, Type type, JsonSerializationContext ctx) { + JsonObject json = new JsonObject(); + + json.add("class", new JsonPrimitive(th.getClass().getName())); + json.add("cause", s_gson.toJsonTree(th.getCause())); + json.add("msg", new JsonPrimitive(th.getMessage())); +// json.add("stack", s_gson.toJsonTree(th.getStackTrace())); + + return json; + } + + } + } diff --git a/server/src/com/cloud/api/ResponseObjectTypeAdapter.java b/server/src/com/cloud/api/ResponseObjectTypeAdapter.java index b49792334f4..627f6666526 100644 --- a/server/src/com/cloud/api/ResponseObjectTypeAdapter.java +++ b/server/src/com/cloud/api/ResponseObjectTypeAdapter.java @@ -16,21 +16,21 @@ // under the License. package com.cloud.api; -import java.lang.reflect.Method; import java.lang.reflect.Type; -import org.apache.cloudstack.api.ResponseObject; import org.apache.log4j.Logger; -import org.apache.cloudstack.api.response.ExceptionResponse; -import org.apache.cloudstack.api.response.SuccessResponse; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.response.ExceptionResponse; +import org.apache.cloudstack.api.response.SuccessResponse; + public class ResponseObjectTypeAdapter implements JsonSerializer { - public static final Logger s_logger = Logger.getLogger(ResponseObjectTypeAdapter.class.getName()); + public static final Logger s_logger = Logger.getLogger(ResponseObjectTypeAdapter.class); @Override public JsonElement serialize(ResponseObject responseObj, Type typeOfResponseObj, JsonSerializationContext ctx) { @@ -48,45 +48,4 @@ public class ResponseObjectTypeAdapter implements JsonSerializer return obj; } } - - private static Method getGetMethod(Object o, String propName) { - Method method = null; - String methodName = getGetMethodName("get", propName); - try { - method = o.getClass().getMethod(methodName); - } catch (SecurityException e1) { - s_logger.error("Security exception in getting ResponseObject " + o.getClass().getName() + " get method for property: " + propName); - } catch (NoSuchMethodException e1) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("ResponseObject " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName - + ", will check is-prefixed method to see if it is boolean property"); - } - } - - if (method != null) - return method; - - methodName = getGetMethodName("is", propName); - try { - method = o.getClass().getMethod(methodName); - } catch (SecurityException e1) { - s_logger.error("Security exception in getting ResponseObject " + o.getClass().getName() + " get method for property: " + propName); - } catch (NoSuchMethodException e1) { - s_logger.warn("ResponseObject " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName); - } - return method; - } - - private static String getGetMethodName(String prefix, String fieldName) { - StringBuffer sb = new StringBuffer(prefix); - - if (fieldName.length() >= prefix.length() && fieldName.substring(0, prefix.length()).equals(prefix)) { - return fieldName; - } else { - sb.append(fieldName.substring(0, 1).toUpperCase()); - sb.append(fieldName.substring(1)); - } - - return sb.toString(); - } } diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java index 40ebe2b7f10..7951a709ccd 100644 --- a/server/src/com/cloud/async/AsyncJobManagerImpl.java +++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java @@ -51,6 +51,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobJournalVO; import org.apache.cloudstack.framework.jobs.impl.AsyncJobMBeanImpl; import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; +import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper; import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem; import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO; import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager; @@ -60,7 +61,6 @@ import org.apache.cloudstack.framework.messagebus.MessageDetector; import org.apache.cloudstack.framework.messagebus.PublishScope; import org.apache.cloudstack.messagebus.TopicConstants; -import com.cloud.api.ApiSerializerHelper; import com.cloud.cluster.ClusterManager; import com.cloud.cluster.ClusterManagerListener; import com.cloud.cluster.ManagementServerHostVO; @@ -234,7 +234,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, job.setInstanceId(null); if (resultObject != null) { - job.setResult(ApiSerializerHelper.toSerializedString(resultObject)); + job.setResult(JobSerializerHelper.toSerializedString(resultObject)); } job.setLastUpdated(DateUtil.currentGMTTime()); @@ -281,7 +281,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, job.setProcessStatus(processStatus); if(resultObject != null) { - job.setResult(ApiSerializerHelper.toSerializedString(resultObject)); + job.setResult(JobSerializerHelper.toSerializedString(resultObject)); } job.setLastUpdated(DateUtil.currentGMTTime()); _jobDao.update(jobId, job); @@ -531,7 +531,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, // execute the job if(s_logger.isDebugEnabled()) { - s_logger.debug("Executing " + job.getCmd() + " for job-" + job.getId()); + s_logger.debug("Executing " + job); } if((getAndResetPendingSignals(job) & AsyncJobConstants.SIGNAL_MASK_WAKEUP) != 0) { @@ -913,7 +913,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } private static String getSerializedErrorMessage(String errorMessage) { - return ApiSerializerHelper.toSerializedString(getResetResultResponse(errorMessage)); + return JobSerializerHelper.toSerializedString(getResetResultResponse(errorMessage)); } @Override