}
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) {