Skip to content

Commit 59c211f

Browse files
committed
Changed async manager to use it's own serializer
1 parent ebbd400 commit 59c211f

3 files changed

Lines changed: 85 additions & 51 deletions

File tree

framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,23 @@
2222
import java.io.ObjectInputStream;
2323
import java.io.ObjectOutputStream;
2424
import java.io.Serializable;
25+
import java.lang.reflect.Constructor;
26+
import java.lang.reflect.InvocationTargetException;
27+
import java.lang.reflect.Type;
2528

2629
import org.apache.commons.codec.binary.Base64;
2730
import org.apache.log4j.Logger;
2831

2932
import com.google.gson.Gson;
3033
import com.google.gson.GsonBuilder;
34+
import com.google.gson.JsonDeserializationContext;
35+
import com.google.gson.JsonDeserializer;
36+
import com.google.gson.JsonElement;
37+
import com.google.gson.JsonObject;
38+
import com.google.gson.JsonParseException;
39+
import com.google.gson.JsonPrimitive;
40+
import com.google.gson.JsonSerializationContext;
41+
import com.google.gson.JsonSerializer;
3142

3243
import com.cloud.utils.exception.CloudRuntimeException;
3344

@@ -43,6 +54,7 @@ public class JobSerializerHelper {
4354
GsonBuilder gsonBuilder = new GsonBuilder();
4455
gsonBuilder.setVersion(1.5);
4556
s_logger.debug("Job GSON Builder initialized.");
57+
gsonBuilder.registerTypeAdapter(Class.class, new ClassTypeAdapter());
4658
s_gson = gsonBuilder.create();
4759
}
4860

@@ -124,4 +136,67 @@ public static Object fromObjectSerializedString(String base64EncodedString) {
124136
throw new CloudRuntimeException("Unable to serialize: " + base64EncodedString, e);
125137
}
126138
}
139+
140+
public static class ClassTypeAdapter implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {
141+
@Override
142+
public JsonElement serialize(Class<?> clazz, Type typeOfResponseObj, JsonSerializationContext ctx) {
143+
return new JsonPrimitive(clazz.getName());
144+
}
145+
146+
@Override
147+
public Class<?> deserialize(JsonElement arg0, Type arg1, JsonDeserializationContext arg2) throws JsonParseException {
148+
String str = arg0.getAsString();
149+
try {
150+
return Class.forName(str);
151+
} catch (ClassNotFoundException e) {
152+
throw new CloudRuntimeException("Unable to find class " + str);
153+
}
154+
}
155+
}
156+
157+
public static class ThrowableTypeAdapter implements JsonSerializer<Throwable>, JsonDeserializer<Throwable> {
158+
159+
@Override
160+
public Throwable deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException {
161+
JsonObject obj = (JsonObject)json;
162+
163+
String className = obj.get("class").getAsString();
164+
try {
165+
Class<Throwable> clazz = (Class<Throwable>)Class.forName(className);
166+
Throwable cause = s_gson.fromJson(obj.get("cause"), Throwable.class);
167+
String msg = obj.get("msg").getAsString();
168+
Constructor<Throwable> constructor = clazz.getConstructor(String.class, Throwable.class);
169+
Throwable th = constructor.newInstance(msg, cause);
170+
return th;
171+
} catch (ClassNotFoundException e) {
172+
throw new JsonParseException("Unable to find " + className);
173+
} catch (NoSuchMethodException e) {
174+
throw new JsonParseException("Unable to find constructor for " + className);
175+
} catch (SecurityException e) {
176+
throw new JsonParseException("Unable to get over security " + className);
177+
} catch (InstantiationException e) {
178+
throw new JsonParseException("Unable to instantiate " + className);
179+
} catch (IllegalAccessException e) {
180+
throw new JsonParseException("Illegal access to " + className, e);
181+
} catch (IllegalArgumentException e) {
182+
throw new JsonParseException("Illegal argument to " + className, e);
183+
} catch (InvocationTargetException e) {
184+
throw new JsonParseException("Cannot invoke " + className, e);
185+
}
186+
}
187+
188+
@Override
189+
public JsonElement serialize(Throwable th, Type type, JsonSerializationContext ctx) {
190+
JsonObject json = new JsonObject();
191+
192+
json.add("class", new JsonPrimitive(th.getClass().getName()));
193+
json.add("cause", s_gson.toJsonTree(th.getCause()));
194+
json.add("msg", new JsonPrimitive(th.getMessage()));
195+
// json.add("stack", s_gson.toJsonTree(th.getStackTrace()));
196+
197+
return json;
198+
}
199+
200+
}
201+
127202
}

server/src/com/cloud/api/ResponseObjectTypeAdapter.java

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@
1616
// under the License.
1717
package com.cloud.api;
1818

19-
import java.lang.reflect.Method;
2019
import java.lang.reflect.Type;
2120

22-
import org.apache.cloudstack.api.ResponseObject;
2321
import org.apache.log4j.Logger;
2422

25-
import org.apache.cloudstack.api.response.ExceptionResponse;
26-
import org.apache.cloudstack.api.response.SuccessResponse;
2723
import com.google.gson.JsonElement;
2824
import com.google.gson.JsonObject;
2925
import com.google.gson.JsonSerializationContext;
3026
import com.google.gson.JsonSerializer;
3127

28+
import org.apache.cloudstack.api.ResponseObject;
29+
import org.apache.cloudstack.api.response.ExceptionResponse;
30+
import org.apache.cloudstack.api.response.SuccessResponse;
31+
3232
public class ResponseObjectTypeAdapter implements JsonSerializer<ResponseObject> {
33-
public static final Logger s_logger = Logger.getLogger(ResponseObjectTypeAdapter.class.getName());
33+
public static final Logger s_logger = Logger.getLogger(ResponseObjectTypeAdapter.class);
3434

3535
@Override
3636
public JsonElement serialize(ResponseObject responseObj, Type typeOfResponseObj, JsonSerializationContext ctx) {
@@ -48,45 +48,4 @@ public JsonElement serialize(ResponseObject responseObj, Type typeOfResponseObj,
4848
return obj;
4949
}
5050
}
51-
52-
private static Method getGetMethod(Object o, String propName) {
53-
Method method = null;
54-
String methodName = getGetMethodName("get", propName);
55-
try {
56-
method = o.getClass().getMethod(methodName);
57-
} catch (SecurityException e1) {
58-
s_logger.error("Security exception in getting ResponseObject " + o.getClass().getName() + " get method for property: " + propName);
59-
} catch (NoSuchMethodException e1) {
60-
if (s_logger.isTraceEnabled()) {
61-
s_logger.trace("ResponseObject " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName
62-
+ ", will check is-prefixed method to see if it is boolean property");
63-
}
64-
}
65-
66-
if (method != null)
67-
return method;
68-
69-
methodName = getGetMethodName("is", propName);
70-
try {
71-
method = o.getClass().getMethod(methodName);
72-
} catch (SecurityException e1) {
73-
s_logger.error("Security exception in getting ResponseObject " + o.getClass().getName() + " get method for property: " + propName);
74-
} catch (NoSuchMethodException e1) {
75-
s_logger.warn("ResponseObject " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName);
76-
}
77-
return method;
78-
}
79-
80-
private static String getGetMethodName(String prefix, String fieldName) {
81-
StringBuffer sb = new StringBuffer(prefix);
82-
83-
if (fieldName.length() >= prefix.length() && fieldName.substring(0, prefix.length()).equals(prefix)) {
84-
return fieldName;
85-
} else {
86-
sb.append(fieldName.substring(0, 1).toUpperCase());
87-
sb.append(fieldName.substring(1));
88-
}
89-
90-
return sb.toString();
91-
}
9251
}

server/src/com/cloud/async/AsyncJobManagerImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.apache.cloudstack.framework.jobs.impl.AsyncJobMBeanImpl;
5252
import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor;
5353
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
54+
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
5455
import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
5556
import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO;
5657
import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager;
@@ -60,7 +61,6 @@
6061
import org.apache.cloudstack.framework.messagebus.PublishScope;
6162
import org.apache.cloudstack.messagebus.TopicConstants;
6263

63-
import com.cloud.api.ApiSerializerHelper;
6464
import com.cloud.cluster.ClusterManager;
6565
import com.cloud.cluster.ClusterManagerListener;
6666
import com.cloud.cluster.ManagementServerHostVO;
@@ -234,7 +234,7 @@ public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object r
234234
job.setInstanceId(null);
235235

236236
if (resultObject != null) {
237-
job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
237+
job.setResult(JobSerializerHelper.toSerializedString(resultObject));
238238
}
239239

240240
job.setLastUpdated(DateUtil.currentGMTTime());
@@ -281,7 +281,7 @@ public void updateAsyncJobStatus(long jobId, int processStatus, Object resultObj
281281

282282
job.setProcessStatus(processStatus);
283283
if(resultObject != null) {
284-
job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
284+
job.setResult(JobSerializerHelper.toSerializedString(resultObject));
285285
}
286286
job.setLastUpdated(DateUtil.currentGMTTime());
287287
_jobDao.update(jobId, job);
@@ -531,7 +531,7 @@ public void run() {
531531

532532
// execute the job
533533
if(s_logger.isDebugEnabled()) {
534-
s_logger.debug("Executing " + job.getCmd() + " for job-" + job.getId());
534+
s_logger.debug("Executing " + job);
535535
}
536536

537537
if((getAndResetPendingSignals(job) & AsyncJobConstants.SIGNAL_MASK_WAKEUP) != 0) {
@@ -913,7 +913,7 @@ private static ExceptionResponse getResetResultResponse(String errorMessage) {
913913
}
914914

915915
private static String getSerializedErrorMessage(String errorMessage) {
916-
return ApiSerializerHelper.toSerializedString(getResetResultResponse(errorMessage));
916+
return JobSerializerHelper.toSerializedString(getResetResultResponse(errorMessage));
917917
}
918918

919919
@Override

0 commit comments

Comments
 (0)