You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/02/07 22:46:53 UTC
[44/50] [abbrv] git commit: updated refs/heads/rbac to 3b58a45
Revert "CLOUDSTACK-6003 fixing plus refactoring dispatcher" as it breaks API dispatching for commands having Map<String,String> as a parameter type
This reverts commit 447430c3df38c36d947c44c4aebd961d8cbb14c4.
Conflicts:
api/src/org/apache/cloudstack/api/BaseCmd.java
server/src/com/cloud/api/ApiDispatcher.java
server/src/com/cloud/network/as/AutoScaleManagerImpl.java
server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/782c5306
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/782c5306
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/782c5306
Branch: refs/heads/rbac
Commit: 782c53068564b96d11a09775d489a6e1b38adbd8
Parents: 9167286
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Thu Feb 6 14:34:43 2014 -0800
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Thu Feb 6 14:46:58 2014 -0800
----------------------------------------------------------------------
.../org/apache/cloudstack/api/ApiConstants.java | 5 -
api/src/org/apache/cloudstack/api/BaseCmd.java | 155 +++---
.../org/apache/cloudstack/api/BaseListCmd.java | 30 +-
.../autoscale/CreateAutoScaleVmProfileCmd.java | 30 +-
.../core/spring-server-core-misc-context.xml | 10 -
.../com/cloud/api/ApiAsyncJobDispatcher.java | 26 +-
server/src/com/cloud/api/ApiDispatcher.java | 485 +++++++++++++++++-
server/src/com/cloud/api/ApiServer.java | 345 ++++++-------
server/src/com/cloud/api/ApiServlet.java | 134 ++---
server/src/com/cloud/api/ParameterHandler.java | 138 ------
.../api/dispatch/CommandCreationWorker.java | 55 ---
.../com/cloud/api/dispatch/DispatchChain.java | 45 --
.../api/dispatch/DispatchChainFactory.java | 68 ---
.../com/cloud/api/dispatch/DispatchWorker.java | 34 --
.../dispatch/ParamGenericValidationWorker.java | 95 ----
.../cloud/api/dispatch/ParamProcessWorker.java | 429 ----------------
.../dispatch/ParamSemanticValidationWorker.java | 40 --
.../cloud/network/as/AutoScaleManagerImpl.java | 490 +++++++++----------
.../VirtualNetworkApplianceManagerImpl.java | 14 +-
.../storage/snapshot/SnapshotSchedulerImpl.java | 107 ++--
.../test/com/cloud/api/ApiDispatcherTest.java | 106 ++++
.../api/dispatch/CommandCreationWorkerTest.java | 48 --
.../api/dispatch/DispatchChainFactoryTest.java | 54 --
.../ParamGenericValidationWorkerTest.java | 163 ------
.../api/dispatch/ParamProcessWorkerTest.java | 107 ----
.../ParamSemanticValidationWorkerTest.java | 48 --
26 files changed, 1227 insertions(+), 2034 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 749a814..d500303 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -48,12 +48,10 @@ public class ApiConstants {
public static final String CLUSTER_ID = "clusterid";
public static final String CLUSTER_NAME = "clustername";
public static final String CLUSTER_TYPE = "clustertype";
- public static final String COMMAND = "command";
public static final String COMPONENT = "component";
public static final String CPU_NUMBER = "cpunumber";
public static final String CPU_SPEED = "cpuspeed";
public static final String CREATED = "created";
- public static final String CTX_START_EVENT_ID = "ctxStartEventId";
public static final String CUSTOMIZED = "customized";
public static final String CUSTOMIZED_IOPS = "customizediops";
public static final String CUSTOM_ID = "customid";
@@ -80,7 +78,6 @@ public class ApiConstants {
public static final String IP6_DNS2 = "ip6dns2";
public static final String DOMAIN = "domain";
public static final String DOMAIN_ID = "domainid";
- public static final String DOMAIN__ID = "domainId";
public static final String DURATION = "duration";
public static final String EMAIL = "email";
public static final String END_DATE = "enddate";
@@ -211,7 +208,6 @@ public class ApiConstants {
public static final String SENT = "sent";
public static final String SENT_BYTES = "sentbytes";
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
- public static final String SESSIONKEY = "sessionkey";
public static final String SHOW_CAPACITIES = "showcapacities";
public static final String SHOW_REMOVED = "showremoved";
public static final String SIZE = "size";
@@ -280,7 +276,6 @@ public class ApiConstants {
public static final String NETWORKRATE = "networkrate";
public static final String HOST_TAGS = "hosttags";
public static final String SSH_KEYPAIR = "keypair";
- public static final String HTTPMETHOD = "httpmethod";
public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
public static final String HOST_CPU_NUM = "hostcpunum";
public static final String HOST_MEM_CAPACITY = "hostmemcapacity";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index 5b50153..0e83cee 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -17,22 +17,17 @@
package org.apache.cloudstack.api;
-import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.inject.Inject;
-import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.alert.AlertService;
-import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
@@ -79,7 +74,6 @@ import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.DomainService;
import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.ReflectUtil;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.UUIDManager;
import com.cloud.vm.UserVmService;
@@ -103,8 +97,6 @@ public abstract class BaseCmd {
public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+");
private static final DateFormat s_outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
- protected static final Map<Class<?>, List<Field>> fieldsForCmdClass = new HashMap<Class<?>, List<Field>>();
-
private Object _responseObject = null;
private Map<String, String> fullUrlParams;
@@ -213,7 +205,7 @@ public abstract class BaseCmd {
return httpMethod;
}
- public void setHttpMethod(final String method) {
+ public void setHttpMethod(String method) {
if (method != null) {
if (method.equalsIgnoreCase("GET"))
httpMethod = HTTPMethod.GET;
@@ -235,7 +227,7 @@ public abstract class BaseCmd {
return responseType;
}
- public void setResponseType(final String responseType) {
+ public void setResponseType(String responseType) {
this.responseType = responseType;
}
@@ -253,7 +245,7 @@ public abstract class BaseCmd {
return _responseObject;
}
- public void setResponseObject(final Object responseObject) {
+ public void setResponseObject(Object responseObject) {
_responseObject = responseObject;
}
@@ -261,7 +253,7 @@ public abstract class BaseCmd {
return _mgr;
}
- public static String getDateString(final Date date) {
+ public static String getDateString(Date date) {
if (date == null) {
return "";
}
@@ -272,83 +264,101 @@ public abstract class BaseCmd {
return formattedString;
}
- protected List<Field> getAllFieldsForClass(final Class<?> clazz) {
- List<Field> filteredFields = fieldsForCmdClass.get(clazz);
+ // FIXME: move this to a utils method so that maps can be unpacked and integer/long values can be appropriately cast
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public Map<String, Object> unpackParams(Map<String, String> params) {
+ Map<String, Object> lowercaseParams = new HashMap<String, Object>();
+ for (String key : params.keySet()) {
+ int arrayStartIndex = key.indexOf('[');
+ int arrayStartLastIndex = key.lastIndexOf('[');
+ if (arrayStartIndex != arrayStartLastIndex) {
+ throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+ }
- // If list of fields was not cached yet
- if (filteredFields == null) {
- final List<Field> allFields = ReflectUtil.getAllFieldsForClass(this.getClass(), BaseCmd.class);
- filteredFields = new ArrayList<Field>();
+ if (arrayStartIndex > 0) {
+ int arrayEndIndex = key.indexOf(']');
+ int arrayEndLastIndex = key.lastIndexOf(']');
+ if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) {
+ // malformed parameter
+ throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+ }
- for (final Field field : allFields) {
- final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
- if ((parameterAnnotation != null) && parameterAnnotation.expose()) {
- filteredFields.add(field);
+ // Now that we have an array object, check for a field name in the case of a complex object
+ int fieldIndex = key.indexOf('.');
+ String fieldName = null;
+ if (fieldIndex < arrayEndIndex) {
+ throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+ } else {
+ fieldName = key.substring(fieldIndex + 1);
}
- }
- // Cache the prepared list for future use
- fieldsForCmdClass.put(clazz, filteredFields);
- }
- return filteredFields;
- }
+ // parse the parameter name as the text before the first '[' character
+ String paramName = key.substring(0, arrayStartIndex);
+ paramName = paramName.toLowerCase();
+
+ Map<Integer, Map> mapArray = null;
+ Map<String, Object> mapValue = null;
+ String indexStr = key.substring(arrayStartIndex + 1, arrayEndIndex);
+ int index = 0;
+ boolean parsedIndex = false;
+ try {
+ if (indexStr != null) {
+ index = Integer.parseInt(indexStr);
+ parsedIndex = true;
+ }
+ } catch (NumberFormatException nfe) {
+ s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error.");
+ }
- protected Account getCurrentContextAccount() {
- return CallContext.current().getCallingAccount();
- }
+ if (!parsedIndex) {
+ throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+ }
- /**
- * this method doesn't return all the @{link Parameter}, but only the ones exposed
- * and allowed for current @{link RoleType}
- *
- * @return
- */
- public List<Field> getParamFields() {
- final List<Field> allFields = getAllFieldsForClass(this.getClass());
- final List<Field> validFields = new ArrayList<Field>();
- final Account caller = getCurrentContextAccount();
-
- for (final Field field : allFields) {
- final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
-
- //TODO: Annotate @Validate on API Cmd classes, FIXME how to process Validate
- final RoleType[] allowedRoles = parameterAnnotation.authorized();
- boolean roleIsAllowed = true;
- if (allowedRoles.length > 0) {
- roleIsAllowed = false;
- for (final RoleType allowedRole : allowedRoles) {
- if (allowedRole.getValue() == caller.getType()) {
- roleIsAllowed = true;
- break;
+ Object value = lowercaseParams.get(paramName);
+ if (value == null) {
+ // for now, assume object array with sub fields
+ mapArray = new HashMap<Integer, Map>();
+ mapValue = new HashMap<String, Object>();
+ mapArray.put(Integer.valueOf(index), mapValue);
+ } else if (value instanceof Map) {
+ mapArray = (HashMap)value;
+ mapValue = mapArray.get(Integer.valueOf(index));
+ if (mapValue == null) {
+ mapValue = new HashMap<String, Object>();
+ mapArray.put(Integer.valueOf(index), mapValue);
}
}
- }
- if (roleIsAllowed) {
- validFields.add(field);
+ // we are ready to store the value for a particular field into the map for this object
+ mapValue.put(fieldName, params.get(key));
+
+ lowercaseParams.put(paramName, mapArray);
} else {
- s_logger.debug("Ignoring paremeter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
+ lowercaseParams.put(key.toLowerCase(), params.get(key));
}
}
-
- return validFields;
+ return lowercaseParams;
}
- protected long getInstanceIdFromJobSuccessResult(final String result) {
+ protected long getInstanceIdFromJobSuccessResult(String result) {
s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName());
return 0;
}
- public static boolean isAdmin(final short accountType) {
+ public static boolean isAdmin(short accountType) {
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
}
- public static boolean isRootAdmin(final short accountType) {
+ public static boolean isRootAdmin(short accountType) {
return ((accountType == Account.ACCOUNT_TYPE_ADMIN));
}
- public void setFullUrlParams(final Map<String, String> map) {
+ public void setFullUrlParams(Map<String, String> map) {
fullUrlParams = map;
}
@@ -356,18 +366,18 @@ public abstract class BaseCmd {
return fullUrlParams;
}
- public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
+ public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
if (accountName != null) {
if (domainId == null) {
throw new InvalidParameterValueException("Account must be specified with domainId parameter");
}
- final Domain domain = _domainService.getDomain(domainId);
+ Domain domain = _domainService.getDomain(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Unable to find domain by id");
}
- final Account account = _accountService.getActiveAccountByName(accountName, domainId);
+ Account account = _accountService.getActiveAccountByName(accountName, domainId);
if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
if (!enabledOnly || account.getState() == Account.State.enabled) {
return account.getId();
@@ -384,12 +394,12 @@ public abstract class BaseCmd {
}
if (projectId != null) {
- final Project project = _projectService.getProject(projectId);
+ Project project = _projectService.getProject(projectId);
if (project != null) {
if (!enabledOnly || project.getState() == Project.State.Active) {
return project.getProjectAccountId();
} else {
- final PermissionDeniedException ex =
+ PermissionDeniedException ex =
new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
" as it's no longer active");
ex.addProxyObject(project.getUuid(), "projectId");
@@ -401,11 +411,4 @@ public abstract class BaseCmd {
}
return null;
}
-
- /**
- * To be overwritten by any class who needs specific validation
- */
- public void validateSpecificParameters(final Map<String, Object> params){
- // To be overwritten by any class who needs specific validation
- }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/api/src/org/apache/cloudstack/api/BaseListCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseListCmd.java b/api/src/org/apache/cloudstack/api/BaseListCmd.java
index 1876995..c1a4b4c 100644
--- a/api/src/org/apache/cloudstack/api/BaseListCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseListCmd.java
@@ -16,10 +16,7 @@
// under the License.
package org.apache.cloudstack.api;
-import java.util.Map;
-
import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.utils.exception.CSExceptionErrorCode;
public abstract class BaseListCmd extends BaseCmd {
@@ -86,7 +83,7 @@ public abstract class BaseListCmd extends BaseCmd {
public Long getPageSizeVal() {
Long defaultPageSize = s_maxPageSize;
- final Integer pageSizeInt = getPageSize();
+ Integer pageSizeInt = getPageSize();
if (pageSizeInt != null) {
defaultPageSize = pageSizeInt.longValue();
}
@@ -99,12 +96,12 @@ public abstract class BaseListCmd extends BaseCmd {
public Long getStartIndex() {
Long startIndex = Long.valueOf(0);
- final Long pageSizeVal = getPageSizeVal();
+ Long pageSizeVal = getPageSizeVal();
if (pageSizeVal == null) {
startIndex = null;
} else if (page != null) {
- final int pageNum = page.intValue();
+ int pageNum = page.intValue();
if (pageNum > 0) {
startIndex = Long.valueOf(pageSizeVal * (pageNum - 1));
}
@@ -115,25 +112,4 @@ public abstract class BaseListCmd extends BaseCmd {
public ApiCommandJobType getInstanceType() {
return ApiCommandJobType.None;
}
-
- @Override
- public void validateSpecificParameters(final Map<String, Object> params){
- super.validateSpecificParameters(params);
-
- final Object pageSizeObj = params.get(ApiConstants.PAGE_SIZE);
- Long pageSize = null;
- if (pageSizeObj != null) {
- pageSize = Long.valueOf((String)pageSizeObj);
- }
-
- if (params.get(ApiConstants.PAGE) == null &&
- pageSize != null &&
- !pageSize.equals(BaseListCmd.s_pageSizeUnlimited)) {
- final ServerApiException ex = new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
- ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName()));
- throw ex;
- } else if (pageSize == null && (params.get(ApiConstants.PAGE) != null)) {
- throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified");
- }
- }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
index ccdd557..bee1b22 100644
--- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
@@ -151,7 +151,7 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
}
Account account = null;
if (autoscaleUserId != null) {
- final User user = _entityMgr.findById(User.class, autoscaleUserId);
+ User user = _entityMgr.findById(User.class, autoscaleUserId);
account = _entityMgr.findById(Account.class, user.getAccountId());
} else {
account = CallContext.current().getCallingAccount();
@@ -167,21 +167,21 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
}
if (otherDeployParams == null)
return;
- final String[] keyValues = otherDeployParams.split("&"); // hostid=123, hypervisor=xenserver
- for (final String keyValue : keyValues) { // keyValue == "hostid=123"
- final String[] keyAndValue = keyValue.split("="); // keyValue = hostid, 123
+ String[] keyValues = otherDeployParams.split("&"); // hostid=123, hypervisor=xenserver
+ for (String keyValue : keyValues) { // keyValue == "hostid=123"
+ String[] keyAndValue = keyValue.split("="); // keyValue = hostid, 123
if (keyAndValue.length != 2) {
throw new InvalidParameterValueException("Invalid parameter in otherDeployParam : " + keyValue);
}
- final String paramName = keyAndValue[0]; // hostid
- final String paramValue = keyAndValue[1]; // 123
+ String paramName = keyAndValue[0]; // hostid
+ String paramValue = keyAndValue[1]; // 123
otherDeployParamMap.put(paramName, paramValue);
}
}
- public HashMap<String, Object> getDeployParamMap() {
+ public HashMap<String, String> getDeployParamMap() {
createOtherDeployParamMap();
- final HashMap<String, Object> deployParams = new HashMap<String, Object>(otherDeployParamMap);
+ HashMap<String, String> deployParams = new HashMap<String, String>(otherDeployParamMap);
deployParams.put("command", "deployVirtualMachine");
deployParams.put("zoneId", zoneId.toString());
deployParams.put("serviceOfferingId", serviceOfferingId.toString());
@@ -189,7 +189,7 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
return deployParams;
}
- public String getOtherDeployParam(final String param) {
+ public String getOtherDeployParam(String param) {
if (param == null) {
return null;
}
@@ -232,19 +232,19 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
@Override
public void execute() {
- final AutoScaleVmProfile result = _entityMgr.findById(AutoScaleVmProfile.class, getEntityId());
- final AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result);
+ AutoScaleVmProfile result = _entityMgr.findById(AutoScaleVmProfile.class, getEntityId());
+ AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result);
response.setResponseName(getCommandName());
- setResponseObject(response);
+ this.setResponseObject(response);
}
@Override
public void create() throws ResourceAllocationException {
- final AutoScaleVmProfile result = _autoScaleService.createAutoScaleVmProfile(this);
+ AutoScaleVmProfile result = _autoScaleService.createAutoScaleVmProfile(this);
if (result != null) {
- setEntityId(result.getId());
- setEntityUuid(result.getUuid());
+ this.setEntityId(result.getId());
+ this.setEntityUuid(result.getUuid());
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Autoscale Vm Profile");
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
----------------------------------------------------------------------
diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
index f35ee5e..fd2f5fb 100644
--- a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
+++ b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
@@ -50,16 +50,6 @@
<bean id="apiDispatcher" class="com.cloud.api.ApiDispatcher" />
- <bean id="dispatchChainFactory" class="com.cloud.api.dispatch.DispatchChainFactory" />
-
- <bean id="paramSemanticValidationWorker" class="com.cloud.api.dispatch.ParamSemanticValidationWorker" />
-
- <bean id="paramProcessWorker" class="com.cloud.api.dispatch.ParamProcessWorker" />
-
- <bean id="paramGenericValidationWorker" class="com.cloud.api.dispatch.ParamGenericValidationWorker" />
-
- <bean id="commandCreationWorker" class="com.cloud.api.dispatch.CommandCreationWorker" />
-
<bean id="apiResponseHelper" class="com.cloud.api.ApiResponseHelper" />
<bean id="apiServer" class="com.cloud.api.ApiServer">
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
index 565e3a4..71ac616 100644
--- a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
+++ b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
@@ -70,30 +70,30 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
});
}
- protected void runJobInContext(final AsyncJob job) {
+ protected void runJobInContext(AsyncJob job) {
BaseAsyncCmd cmdObj = null;
try {
- final Class<?> cmdClass = Class.forName(job.getCmd());
+ Class<?> cmdClass = Class.forName(job.getCmd());
cmdObj = (BaseAsyncCmd)cmdClass.newInstance();
cmdObj = ComponentContext.inject(cmdObj);
cmdObj.configure();
cmdObj.setJob(job);
- final Type mapType = new TypeToken<Map<String, String>>() {
+ Type mapType = new TypeToken<Map<String, String>>() {
}.getType();
- final Gson gson = ApiGsonHelper.getBuilder().create();
- final Map<String, Object> params = gson.fromJson(job.getCmdInfo(), mapType);
+ Gson gson = ApiGsonHelper.getBuilder().create();
+ Map<String, String> params = gson.fromJson(job.getCmdInfo(), mapType);
// whenever we deserialize, the UserContext needs to be updated
- final String userIdStr = (String) params.get("ctxUserId");
- final String acctIdStr = (String) params.get("ctxAccountId");
+ String userIdStr = params.get("ctxUserId");
+ String acctIdStr = params.get("ctxAccountId");
Long userId = null;
Account accountObject = null;
if (cmdObj instanceof BaseAsyncCreateCmd) {
- final BaseAsyncCreateCmd create = (BaseAsyncCreateCmd)cmdObj;
- create.setEntityId(Long.parseLong((String) params.get("id")));
- create.setEntityUuid((String) params.get("uuid"));
+ BaseAsyncCreateCmd create = (BaseAsyncCreateCmd)cmdObj;
+ create.setEntityId(Long.parseLong(params.get("id")));
+ create.setEntityUuid(params.get("uuid"));
}
User user = null;
@@ -116,19 +116,19 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
} finally {
CallContext.unregister();
}
- } catch (final Throwable e) {
+ } catch (Throwable e) {
String errorMsg = null;
int errorCode = ApiErrorCode.INTERNAL_ERROR.getHttpCode();
if (!(e instanceof ServerApiException)) {
s_logger.error("Unexpected exception while executing " + job.getCmd(), e);
errorMsg = e.getMessage();
} else {
- final ServerApiException sApiEx = (ServerApiException)e;
+ ServerApiException sApiEx = (ServerApiException)e;
errorMsg = sApiEx.getDescription();
errorCode = sApiEx.getErrorCode().getHttpCode();
}
- final ExceptionResponse response = new ExceptionResponse();
+ ExceptionResponse response = new ExceptionResponse();
response.setErrorCode(errorCode);
response.setErrorText(errorMsg);
response.setResponseName((cmdObj == null) ? "unknowncommandresponse" : cmdObj.getCommandName());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/782c5306/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 7d9b7d7..ed95c72 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -16,67 +16,126 @@
// under the License.
package com.cloud.api;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
import org.apache.cloudstack.api.BaseCustomIdCmd;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.EntityReference;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
+import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
+import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.log4j.Logger;
-import com.cloud.api.dispatch.DispatchChain;
-import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.ReflectUtil;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CSExceptionErrorCode;
+import com.cloud.utils.exception.CloudRuntimeException;
public class ApiDispatcher {
private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
Long _createSnapshotQueueSizeLimit;
-
@Inject
AsyncJobManager _asyncMgr = null;
+ @Inject
+ AccountManager _accountMgr = null;
+ @Inject
+ EntityManager _entityMgr = null;
- @Inject()
- protected DispatchChainFactory dispatchChainFactory = null;
-
- protected DispatchChain standardDispatchChain = null;
+ private static ApiDispatcher s_instance;
- protected DispatchChain asyncCreationDispatchChain = null;
+ public static ApiDispatcher getInstance() {
+ return s_instance;
+ }
public ApiDispatcher() {
}
@PostConstruct
- public void setup() {
- standardDispatchChain = dispatchChainFactory.getStandardDispatchChain();
- asyncCreationDispatchChain = dispatchChainFactory.getAsyncCreationDispatchChain();
+ void init() {
+ s_instance = this;
}
- public void setCreateSnapshotQueueSizeLimit(final Long snapshotLimit) {
+ public void setCreateSnapshotQueueSizeLimit(Long snapshotLimit) {
_createSnapshotQueueSizeLimit = snapshotLimit;
}
- public void dispatchCreateCmd(final BaseAsyncCreateCmd cmd, final Map<String, Object> params) throws Exception {
- asyncCreationDispatchChain.dispatch(cmd, params);
+ public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) throws Exception {
+ processParameters(cmd, params);
+
+ cmd.create();
+
}
- public void dispatch(final BaseCmd cmd, final Map<String, Object> params, final boolean execute) throws Exception {
- // Let the chain of responsibility dispatch gradually
- standardDispatchChain.dispatch(cmd, params);
+ private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
+ Account caller = CallContext.current().getCallingAccount();
+ Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
- final CallContext ctx = CallContext.current();
+ if (cmd instanceof BaseAsyncCreateCmd) {
+ //check that caller can access the owner account.
+ _accountMgr.checkAccess(caller, null, true, owner);
+ }
+
+ if (!entitiesToAccess.isEmpty()) {
+ //check that caller can access the owner account.
+ _accountMgr.checkAccess(caller, null, true, owner);
+ for (Object entity : entitiesToAccess.keySet()) {
+ if (entity instanceof ControlledEntity) {
+ _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity);
+ } else if (entity instanceof InfrastructureEntity) {
+ //FIXME: Move this code in adapter, remove code from Account manager
+ }
+ }
+ }
+ }
+
+ public void dispatch(BaseCmd cmd, Map<String, String> params, boolean execute) throws Exception {
+ processParameters(cmd, params);
+ CallContext ctx = CallContext.current();
if (cmd instanceof BaseAsyncCmd) {
- final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
- final String startEventId = (String) params.get(ApiConstants.CTX_START_EVENT_ID);
+ BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
+ String startEventId = params.get("ctxStartEventId");
ctx.setStartEventId(Long.valueOf(startEventId));
// Synchronise job on the object if needed
@@ -107,6 +166,392 @@ public class ApiDispatcher {
}
cmd.execute();
+
}
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public static void processParameters(BaseCmd cmd, Map<String, String> params) {
+ Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
+ Map<String, Object> unpackedParams = cmd.unpackParams(params);
+
+ if (cmd instanceof BaseListCmd) {
+ Object pageSizeObj = unpackedParams.get(ApiConstants.PAGE_SIZE);
+ Long pageSize = null;
+ if (pageSizeObj != null) {
+ pageSize = Long.valueOf((String)pageSizeObj);
+ }
+
+ if ((unpackedParams.get(ApiConstants.PAGE) == null) && (pageSize != null && !pageSize.equals(BaseListCmd.s_pageSizeUnlimited))) {
+ ServerApiException ex = new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
+ ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName()));
+ throw ex;
+ } else if (pageSize == null && (unpackedParams.get(ApiConstants.PAGE) != null)) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified");
+ }
+ }
+
+ List<Field> fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(), BaseCmd.class);
+
+ for (Field field : fields) {
+ Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+ if ((parameterAnnotation == null) || !parameterAnnotation.expose()) {
+ continue;
+ }
+
+ //TODO: Annotate @Validate on API Cmd classes, FIXME how to process Validate
+ RoleType[] allowedRoles = parameterAnnotation.authorized();
+ if (allowedRoles.length > 0) {
+ boolean permittedParameter = false;
+ Account caller = CallContext.current().getCallingAccount();
+ for (RoleType allowedRole : allowedRoles) {
+ if (allowedRole.getValue() == caller.getType()) {
+ permittedParameter = true;
+ break;
+ }
+ }
+ if (!permittedParameter) {
+ s_logger.debug("Ignoring paremeter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
+ continue;
+ }
+ }
+
+ Object paramObj = unpackedParams.get(parameterAnnotation.name());
+ if (paramObj == null) {
+ if (parameterAnnotation.required()) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+ cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to missing parameter " + parameterAnnotation.name());
+ }
+ continue;
+ }
+
+ // marshall the parameter into the correct type and set the field value
+ try {
+ setFieldValue(field, cmd, paramObj, parameterAnnotation);
+ } catch (IllegalArgumentException argEx) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unable to execute API command " + cmd.getCommandName() + " due to invalid value " + paramObj + " for parameter " +
+ parameterAnnotation.name());
+ }
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+ cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value " + paramObj + " for parameter " +
+ parameterAnnotation.name());
+ } catch (ParseException parseEx) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+ }
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " +
+ cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + ", please pass dates in the format mentioned in the api documentation");
+ } catch (InvalidParameterValueException invEx) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+ cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value. " + invEx.getMessage());
+ } catch (CloudRuntimeException cloudEx) {
+ s_logger.error("CloudRuntimeException", cloudEx);
+ // FIXME: Better error message? This only happens if the API command is not executable, which typically
+ //means
+ // there was
+ // and IllegalAccessException setting one of the parameters.
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal error executing API command " +
+ cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+ }
+
+ //check access on the resource this field points to
+ try {
+ ACL checkAccess = field.getAnnotation(ACL.class);
+ CommandType fieldType = parameterAnnotation.type();
+
+ if (checkAccess != null) {
+ // Verify that caller can perform actions in behalf of vm owner
+ //acumulate all Controlled Entities together.
+
+ //parse the array of resource types and in case of map check access on key or value or both as specified in @acl
+ //implement external dao for classes that need findByName
+ //for maps, specify access to be checkd on key or value.
+
+ // find the controlled entity DBid by uuid
+ if (parameterAnnotation.entityType() != null) {
+ Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
+
+ for (Class entity : entityList) {
+ // Check if the parameter type is a single
+ // Id or list of id's/name's
+ switch (fieldType) {
+ case LIST:
+ CommandType listType = parameterAnnotation.collectionType();
+ switch (listType) {
+ case LONG:
+ case UUID:
+ List<Long> listParam = (List<Long>)field.get(cmd);
+ for (Long entityId : listParam) {
+ Object entityObj = s_instance._entityMgr.findById(entity, entityId);
+ entitiesToAccess.put(entityObj, checkAccess.accessType());
+ }
+ break;
+ /*
+ * case STRING: List<String> listParam =
+ * new ArrayList<String>(); listParam =
+ * (List)field.get(cmd); for(String
+ * entityName: listParam){
+ * ControlledEntity entityObj =
+ * (ControlledEntity
+ * )daoClassInstance(entityId);
+ * entitiesToAccess.add(entityObj); }
+ * break;
+ */
+ default:
+ break;
+ }
+ break;
+ case LONG:
+ case UUID:
+ Object entityObj = s_instance._entityMgr.findById(entity, (Long)field.get(cmd));
+ entitiesToAccess.put(entityObj, checkAccess.accessType());
+ break;
+ default:
+ break;
+ }
+
+ if (ControlledEntity.class.isAssignableFrom(entity)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("ControlledEntity name is:" + entity.getName());
+ }
+ }
+
+ if (InfrastructureEntity.class.isAssignableFrom(entity)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("InfrastructureEntity name is:" + entity.getName());
+ }
+ }
+ }
+
+ }
+
+ }
+
+ } catch (IllegalArgumentException e) {
+ s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
+ throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+ " is not accessible]");
+ } catch (IllegalAccessException e) {
+ s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
+ throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+ " is not accessible]");
+ }
+
+ }
+
+ //check access on the entities.
+ getInstance().doAccessChecks(cmd, entitiesToAccess);
+
+ }
+
+ private static Long translateUuidToInternalId(String uuid, Parameter annotation) {
+ if (uuid.equals("-1")) {
+ // FIXME: This is to handle a lot of hardcoded special cases where -1 is sent
+ // APITODO: Find and get rid of all hardcoded params in API Cmds and service layer
+ return -1L;
+ }
+ Long internalId = null;
+ // If annotation's empty, the cmd existed before 3.x try conversion to long
+ boolean isPre3x = annotation.since().isEmpty();
+ // Match against Java's UUID regex to check if input is uuid string
+ boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
+ // Enforce that it's uuid for newly added apis from version 3.x
+ if (!isPre3x && !isUuid)
+ return null;
+ // Allow both uuid and internal id for pre3x apis
+ if (isPre3x && !isUuid) {
+ try {
+ internalId = Long.parseLong(uuid);
+ } catch (NumberFormatException e) {
+ internalId = null;
+ }
+ if (internalId != null)
+ return internalId;
+ }
+ // There may be multiple entities defined on the @EntityReference of a Response.class
+ // UUID CommandType would expect only one entityType, so use the first entityType
+ Class<?>[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value();
+ // Go through each entity which is an interface to a VO class and get a VO object
+ // Try to getId() for the object using reflection, break on first non-null value
+ for (Class<?> entity : entities) {
+ // For backward compatibility, we search within removed entities and let service layer deal
+ // with removed ones, return empty response or error
+ Object objVO = s_instance._entityMgr.findByUuidIncludingRemoved(entity, uuid);
+ if (objVO == null) {
+ continue;
+ }
+ // Invoke the getId method, get the internal long ID
+ // If that fails hide exceptions as the uuid may not exist
+ try {
+ internalId = ((InternalIdentity)objVO).getId();
+ } catch (IllegalArgumentException e) {
+ } catch (NullPointerException e) {
+ }
+ // Return on first non-null Id for the uuid entity
+ if (internalId != null)
+ break;
+ }
+ if (internalId == null) {
+ if (s_logger.isDebugEnabled())
+ s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
+ throw new InvalidParameterValueException("Invalid parameter " + annotation.name() + " value=" + uuid +
+ " due to incorrect long value format, or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.");
+ }
+ return internalId;
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private static void setFieldValue(Field field, BaseCmd cmdObj, Object paramObj, Parameter annotation) throws IllegalArgumentException, ParseException {
+ try {
+ field.setAccessible(true);
+ CommandType fieldType = annotation.type();
+ switch (fieldType) {
+ case BOOLEAN:
+ field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
+ break;
+ case DATE:
+ // This piece of code is for maintaining backward compatibility
+ // and support both the date formats(Bug 9724)
+ // Do the date messaging for ListEventsCmd only
+ if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd ||
+ cmdObj instanceof ArchiveAlertsCmd || cmdObj instanceof DeleteAlertsCmd) {
+ boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
+ if (isObjInNewDateFormat) {
+ DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT;
+ synchronized (newFormat) {
+ field.set(cmdObj, newFormat.parse(paramObj.toString()));
+ }
+ } else {
+ DateFormat format = BaseCmd.INPUT_FORMAT;
+ synchronized (format) {
+ Date date = format.parse(paramObj.toString());
+ if (field.getName().equals("startDate")) {
+ date = messageDate(date, 0, 0, 0);
+ } else if (field.getName().equals("endDate")) {
+ date = messageDate(date, 23, 59, 59);
+ }
+ field.set(cmdObj, date);
+ }
+ }
+ } else {
+ DateFormat format = BaseCmd.INPUT_FORMAT;
+ synchronized (format) {
+ format.setLenient(false);
+ field.set(cmdObj, format.parse(paramObj.toString()));
+ }
+ }
+ break;
+ case FLOAT:
+ // Assuming that the parameters have been checked for required before now,
+ // we ignore blank or null values and defer to the command to set a default
+ // value for optional parameters ...
+ if (paramObj != null && isNotBlank(paramObj.toString())) {
+ field.set(cmdObj, Float.valueOf(paramObj.toString()));
+ }
+ break;
+ case INTEGER:
+ // Assuming that the parameters have been checked for required before now,
+ // we ignore blank or null values and defer to the command to set a default
+ // value for optional parameters ...
+ if (paramObj != null && isNotBlank(paramObj.toString())) {
+ field.set(cmdObj, Integer.valueOf(paramObj.toString()));
+ }
+ break;
+ case LIST:
+ List listParam = new ArrayList();
+ StringTokenizer st = new StringTokenizer(paramObj.toString(), ",");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ CommandType listType = annotation.collectionType();
+ switch (listType) {
+ case INTEGER:
+ listParam.add(Integer.valueOf(token));
+ break;
+ case UUID:
+ if (token.isEmpty())
+ break;
+ Long internalId = translateUuidToInternalId(token, annotation);
+ listParam.add(internalId);
+ break;
+ case LONG: {
+ listParam.add(Long.valueOf(token));
+ }
+ break;
+ case SHORT:
+ listParam.add(Short.valueOf(token));
+ case STRING:
+ listParam.add(token);
+ break;
+ }
+ }
+ field.set(cmdObj, listParam);
+ break;
+ case UUID:
+ if (paramObj.toString().isEmpty())
+ break;
+ Long internalId = translateUuidToInternalId(paramObj.toString(), annotation);
+ field.set(cmdObj, internalId);
+ break;
+ case LONG:
+ field.set(cmdObj, Long.valueOf(paramObj.toString()));
+ break;
+ case SHORT:
+ field.set(cmdObj, Short.valueOf(paramObj.toString()));
+ break;
+ case STRING:
+ if ((paramObj != null) && paramObj.toString().length() > annotation.length()) {
+ s_logger.error("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+ throw new InvalidParameterValueException("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+ }
+ field.set(cmdObj, paramObj.toString());
+ break;
+ case TZDATE:
+ field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString()));
+ break;
+ case MAP:
+ default:
+ field.set(cmdObj, paramObj);
+ break;
+ }
+ } catch (IllegalAccessException ex) {
+ s_logger.error("Error initializing command " + cmdObj.getCommandName() + ", field " + field.getName() + " is not accessible.");
+ throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() +
+ " is not accessible]");
+ }
+ }
+
+ private static boolean isObjInNewDateFormat(String string) {
+ Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
+ return matcher.matches();
+ }
+
+ private static Date messageDate(Date date, int hourOfDay, int minute, int second) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ return cal.getTime();
+ }
+
+ public static void plugService(Field field, BaseCmd cmd) {
+
+ Class<?> fc = field.getType();
+ Object instance = null;
+
+ if (instance == null) {
+ throw new CloudRuntimeException("Unable to plug service " + fc.getSimpleName() + " in command " + cmd.getClass().getSimpleName());
+ }
+
+ try {
+ field.setAccessible(true);
+ field.set(cmd, instance);
+ } catch (IllegalArgumentException e) {
+ s_logger.error("IllegalArgumentException at plugService for command " + cmd.getCommandName() + ", field " + field.getName());
+ throw new CloudRuntimeException("Internal error at plugService for command " + cmd.getCommandName() + " [Illegal argumet at field " + field.getName() + "]");
+ } catch (IllegalAccessException e) {
+ s_logger.error("Error at plugService for command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
+ throw new CloudRuntimeException("Internal error at plugService for command " + cmd.getCommandName() + " [field " + field.getName() + " is not accessible]");
+ }
+ }
}