Changed async manager to use it's own serializer

This commit is contained in:
Alex Huang 2013-06-07 20:28:43 -07:00
parent ebbd4008ad
commit 59c211fca7
3 changed files with 85 additions and 51 deletions

View File

@ -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<Class<?>>, JsonDeserializer<Class<?>> {
@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<Throwable>, JsonDeserializer<Throwable> {
@Override
public Throwable deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException {
JsonObject obj = (JsonObject)json;
String className = obj.get("class").getAsString();
try {
Class<Throwable> clazz = (Class<Throwable>)Class.forName(className);
Throwable cause = s_gson.fromJson(obj.get("cause"), Throwable.class);
String msg = obj.get("msg").getAsString();
Constructor<Throwable> 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;
}
}
}

View File

@ -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<ResponseObject> {
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<ResponseObject>
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();
}
}

View File

@ -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