Handle proxy object situation in dispatching API command

This commit is contained in:
Kelven Yang 2013-01-16 11:28:09 -08:00
parent 339c09bdef
commit 4c1257bf18
3 changed files with 36 additions and 17 deletions

View File

@ -65,6 +65,7 @@ import com.cloud.user.AccountManager;
import com.cloud.user.UserContext; import com.cloud.user.UserContext;
import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil;
import com.cloud.utils.ReflectUtil; import com.cloud.utils.ReflectUtil;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.exception.CSExceptionErrorCode; import com.cloud.utils.exception.CSExceptionErrorCode;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -325,6 +326,8 @@ public class ApiDispatcher {
List<Object> entitiesToAccess = new ArrayList<Object>(); List<Object> entitiesToAccess = new ArrayList<Object>();
Map<String, Object> unpackedParams = cmd.unpackParams(params); Map<String, Object> unpackedParams = cmd.unpackParams(params);
cmd = ComponentContext.getTargetObject(cmd);
if (cmd instanceof BaseListCmd) { if (cmd instanceof BaseListCmd) {
Object pageSizeObj = unpackedParams.get(ApiConstants.PAGE_SIZE); Object pageSizeObj = unpackedParams.get(ApiConstants.PAGE_SIZE);
Long pageSize = null; Long pageSize = null;

View File

@ -106,6 +106,7 @@ import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer; import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.aop.framework.Advised;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.api.response.ApiResponseSerializer; import com.cloud.api.response.ApiResponseSerializer;
@ -348,6 +349,7 @@ public class ApiServer implements HttpRequestHandler {
cmdObj.configure(); cmdObj.configure();
cmdObj.setFullUrlParams(paramMap); cmdObj.setFullUrlParams(paramMap);
cmdObj.setResponseType(responseType); cmdObj.setResponseType(responseType);
// This is where the command is either serialized, or directly dispatched // This is where the command is either serialized, or directly dispatched
response = queueCommand(cmdObj, paramMap); response = queueCommand(cmdObj, paramMap);
buildAuditTrail(auditTrailSb, command[0], response); buildAuditTrail(auditTrailSb, command[0], response);
@ -405,14 +407,16 @@ public class ApiServer implements HttpRequestHandler {
Long callerUserId = ctx.getCallerUserId(); Long callerUserId = ctx.getCallerUserId();
Account caller = ctx.getCaller(); Account caller = ctx.getCaller();
BaseCmd realCmdObj = ComponentContext.getTargetObject(cmdObj);
// Queue command based on Cmd super class: // Queue command based on Cmd super class:
// BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
// BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd. // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd.
// BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned. // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
if (cmdObj instanceof BaseAsyncCmd) { if (realCmdObj instanceof BaseAsyncCmd) {
Long objectId = null; Long objectId = null;
String objectUuid = null; String objectUuid = null;
if (cmdObj instanceof BaseAsyncCreateCmd) { if (realCmdObj instanceof BaseAsyncCreateCmd) {
BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj;
_dispatcher.dispatchCreateCmd(createCmd, params); _dispatcher.dispatchCreateCmd(createCmd, params);
objectId = createCmd.getEntityId(); objectId = createCmd.getEntityId();
@ -472,19 +476,19 @@ public class ApiServer implements HttpRequestHandler {
// if the command is of the listXXXCommand, we will need to also return the // if the command is of the listXXXCommand, we will need to also return the
// the job id and status if possible // the job id and status if possible
// For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views. // For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views.
if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd) if (realCmdObj instanceof BaseListCmd && !(realCmdObj instanceof ListVMsCmd) && !(realCmdObj instanceof ListRoutersCmd)
&& !(cmdObj instanceof ListSecurityGroupsCmd) && !(realCmdObj instanceof ListSecurityGroupsCmd)
&& !(cmdObj instanceof ListTagsCmd) && !(realCmdObj instanceof ListTagsCmd)
&& !(cmdObj instanceof ListEventsCmd) && !(realCmdObj instanceof ListEventsCmd)
&& !(cmdObj instanceof ListVMGroupsCmd) && !(realCmdObj instanceof ListVMGroupsCmd)
&& !(cmdObj instanceof ListProjectsCmd) && !(realCmdObj instanceof ListProjectsCmd)
&& !(cmdObj instanceof ListProjectAccountsCmd) && !(realCmdObj instanceof ListProjectAccountsCmd)
&& !(cmdObj instanceof ListProjectInvitationsCmd) && !(realCmdObj instanceof ListProjectInvitationsCmd)
&& !(cmdObj instanceof ListHostsCmd) && !(realCmdObj instanceof ListHostsCmd)
&& !(cmdObj instanceof ListVolumesCmd) && !(realCmdObj instanceof ListVolumesCmd)
&& !(cmdObj instanceof ListUsersCmd) && !(realCmdObj instanceof ListUsersCmd)
&& !(cmdObj instanceof ListAccountsCmd) && !(realCmdObj instanceof ListAccountsCmd)
&& !(cmdObj instanceof ListStoragePoolsCmd) && !(realCmdObj instanceof ListStoragePoolsCmd)
) { ) {
buildAsyncListResponse((BaseListCmd) cmdObj, caller); buildAsyncListResponse((BaseListCmd) cmdObj, caller);
} }

View File

@ -131,6 +131,18 @@ public class ComponentContext implements ApplicationContextAware {
return instance.getClass(); return instance.getClass();
} }
public static <T> T getTargetObject(Object instance) {
if(instance instanceof Advised) {
try {
return (T)((Advised)instance).getTargetSource().getTarget();
} catch (Exception e) {
return (T)instance;
}
}
return (T)instance;
}
public static <T> T inject(Class<T> clz) { public static <T> T inject(Class<T> clz) {
T instance = s_appContext.getAutowireCapableBeanFactory().createBean(clz); T instance = s_appContext.getAutowireCapableBeanFactory().createBean(clz);
return inject(instance); return inject(instance);