diff --git a/api/src/com/cloud/dao/EntityManager.java b/api/src/com/cloud/dao/EntityManager.java index 552e69dabd4..4ddfcec685f 100644 --- a/api/src/com/cloud/dao/EntityManager.java +++ b/api/src/com/cloud/dao/EntityManager.java @@ -45,7 +45,7 @@ public interface EntityManager { * @param xid external id * @return T if found, null if not. */ - public T findByXid(Class entityType, String xid); + public T findByXId(Class entityType, String xid); /** * Lists all entities. Use this method at your own risk. diff --git a/api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java b/api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java index 709d107387a..6e50a159f20 100644 --- a/api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java @@ -16,15 +16,16 @@ // under the License. package org.apache.cloudstack.api; +import org.apache.cloudstack.api.response.DomainResponse; + public abstract class BaseListDomainResourcesCmd extends BaseListCmd { @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "If set to false, " + "list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false") private Boolean listAll; - @IdentityMapper(entityTableName = "domain") - @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.LONG, description = "list only resources" + - " belonging to the domain specified") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, + description="list only resources belonging to the domain specified") private Long domainId; @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN, description = "defaults to false," + diff --git a/api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java b/api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java index d5232bc0a72..836527fc7c7 100644 --- a/api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java @@ -16,10 +16,12 @@ // under the License. package org.apache.cloudstack.api; +import org.apache.cloudstack.api.response.ProjectResponse; + public abstract class BaseListProjectAndAccountResourcesCmd extends BaseListAccountResourcesCmd { - @IdentityMapper(entityTableName = "projects") - @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.LONG, description = "list objects by project") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType=ProjectResponse.class, + description="list objects by project") private Long projectId; public Long getProjectId() { diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java index e7cd44be04a..a1461fbba12 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java @@ -20,10 +20,10 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.UserResponse; import com.cloud.user.Account; import com.cloud.user.User; @@ -42,8 +42,8 @@ public class CreateUserCmd extends BaseCmd { @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, required=true, description="Creates the user under the specified account. If no account is specified, the username will be used as the account name.") private String accountName; - @IdentityMapper(entityTableName="domain") - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Creates the user under the specified domain. Has to be accompanied with the account parameter") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, + description="Creates the user under the specified domain. Has to be accompanied with the account parameter") private Long domainId; @Parameter(name=ApiConstants.EMAIL, type=CommandType.STRING, required=true, description="email") diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index ba9cafb32e3..8c85bc6965f 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -39,8 +38,7 @@ public class DeleteUserCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="Deletes a user") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, required=true, description="Deletes a user") private Long id; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java index b726b913d2f..403014bb6c5 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -42,8 +41,8 @@ public class DisableUserCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="Disables user by user ID.") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, + required=true, description="Disables user by user ID.") private Long id; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java index 0ac28c33089..0e88627c43a 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -39,8 +38,8 @@ public class EnableUserCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="Enables user by user ID.") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, + required=true, description="Enables user by user ID.") private Long id; diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java index 7d918b2090d..fba7a62eedd 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListAccountResourcesCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; @@ -39,8 +38,7 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd { @Parameter(name=ApiConstants.ACCOUNT_TYPE, type=CommandType.LONG, description="List users by account type. Valid types include admin, domain-admin, read-only-admin, or user.") private Long accountType; - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="List user by ID.") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, description="List user by ID.") private Long id; @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="List users by state of the user account.") @@ -81,7 +79,6 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - ListResponse response = _queryService.searchForUsers(this); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java index 30cfd15650b..a29739385c1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -39,8 +38,8 @@ public class LockUserCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="Locks user by user ID.") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, + required=true, description="Locks user by user ID.") private Long id; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java index becba814bc4..b762ac66e99 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java @@ -20,10 +20,10 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.RegisterResponse; +import org.apache.cloudstack.api.response.UserResponse; import com.cloud.user.Account; import com.cloud.user.User; @@ -37,8 +37,8 @@ public class RegisterCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="User id") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, + required=true, description="User id") private Long id; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java index 8a6789d34d6..b2f4399d172 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -49,8 +48,8 @@ public class UpdateUserCmd extends BaseCmd { @Parameter(name=ApiConstants.FIRSTNAME, type=CommandType.STRING, description="first name") private String firstname; - @IdentityMapper(entityTableName="user") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="User id") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, + required=true, description="User uuid") private Long id; @Parameter(name=ApiConstants.LASTNAME, type=CommandType.STRING, description="last name") diff --git a/api/src/org/apache/cloudstack/api/command/user/user/AddVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/user/AddVpnUserCmd.java index e8f8fc9cb3e..d62b992c9b0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/user/AddVpnUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/user/AddVpnUserCmd.java @@ -21,10 +21,11 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ProjectResponse; import org.apache.cloudstack.api.response.VpnUsersResponse; import com.cloud.domain.Domain; import com.cloud.event.EventTypes; @@ -50,12 +51,12 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the vpn user. Must be used with domainId.") private String accountName; - @IdentityMapper(entityTableName="projects") - @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="add vpn user to the specific project") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType=ProjectResponse.class, + description="add vpn user to the specific project") private Long projectId; - @IdentityMapper(entityTableName="domain") - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, + description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") private Long domainId; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/user/ListVpnUsersCmd.java b/api/src/org/apache/cloudstack/api/command/user/user/ListVpnUsersCmd.java index 1fa15b597f9..f98d3c8ec7b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/user/ListVpnUsersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/user/ListVpnUsersCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; @@ -40,8 +39,8 @@ public class ListVpnUsersCmd extends BaseListProjectAndAccountResourcesCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @IdentityMapper(entityTableName="vpn_users") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the ID of the vpn user") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VpnUsersResponse.class, + description="The uuid of the Vpn user") private Long id; @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, description="the username of the vpn user.") diff --git a/api/src/org/apache/cloudstack/api/command/user/user/RemoveVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/user/RemoveVpnUserCmd.java index 5e144bdaf76..eee343ce760 100644 --- a/api/src/org/apache/cloudstack/api/command/user/user/RemoveVpnUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/user/RemoveVpnUserCmd.java @@ -21,10 +21,11 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ProjectResponse; import org.apache.cloudstack.api.response.SuccessResponse; import com.cloud.event.EventTypes; import com.cloud.user.Account; @@ -45,12 +46,12 @@ public class RemoveVpnUserCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the vpn user. Must be used with domainId.") private String accountName; - @IdentityMapper(entityTableName="projects") - @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="remove vpn user from the project") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType=ProjectResponse.class, + description="remove vpn user from the project") private Long projectId; - @IdentityMapper(entityTableName="domain") - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, + description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") private Long domainId; ///////////////////////////////////////////////////// @@ -99,7 +100,6 @@ public class RemoveVpnUserCmd extends BaseAsyncCmd { return "Remove Remote Access VPN user for account " + getEntityOwnerId() + " username= " + getUserName(); } - @Override public String getEventType() { return EventTypes.EVENT_VPN_USER_REMOVE; diff --git a/api/src/org/apache/cloudstack/api/response/ProjectResponse.java b/api/src/org/apache/cloudstack/api/response/ProjectResponse.java index c47e7b6fc09..e7d4dd31cee 100644 --- a/api/src/org/apache/cloudstack/api/response/ProjectResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ProjectResponse.java @@ -19,12 +19,15 @@ package org.apache.cloudstack.api.response; import java.util.ArrayList; import java.util.List; +import com.cloud.projects.Project; import org.apache.cloudstack.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Entity; +@Entity(value = Project.class) @SuppressWarnings("unused") public class ProjectResponse extends BaseResponse { diff --git a/api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java b/api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java index d87921abde7..ef847e7b2b1 100644 --- a/api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java @@ -16,12 +16,15 @@ // under the License. package org.apache.cloudstack.api.response; +import com.cloud.configuration.ResourceLimit; import org.apache.cloudstack.api.ApiConstants; import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Entity; +@Entity(value = ResourceLimit.class) @SuppressWarnings("unused") public class ResourceLimitResponse extends BaseResponse implements ControlledEntityResponse { @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account of the resource limit") diff --git a/api/src/org/apache/cloudstack/api/response/UserResponse.java b/api/src/org/apache/cloudstack/api/response/UserResponse.java index bb161264d12..8c070fd5eb8 100644 --- a/api/src/org/apache/cloudstack/api/response/UserResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserResponse.java @@ -18,10 +18,14 @@ package org.apache.cloudstack.api.response; import java.util.Date; -import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; -import org.apache.cloudstack.api.BaseResponse; +import com.cloud.serializer.Param; +import com.cloud.user.User; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Entity; + +@Entity(value = User.class) public class UserResponse extends BaseResponse { @SerializedName("id") @Param(description="the user ID") private String id; @@ -68,7 +72,6 @@ public class UserResponse extends BaseResponse { @SerializedName("accountid") @Param(description="the account ID of the user") private String accountId; - public String getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java b/api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java index eace392e0de..18b33a1e737 100644 --- a/api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java @@ -16,12 +16,15 @@ // under the License. package org.apache.cloudstack.api.response; +import com.cloud.network.VpnUser; import org.apache.cloudstack.api.ApiConstants; import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Entity; +@Entity(value = VpnUser.class) @SuppressWarnings("unused") public class VpnUsersResponse extends BaseResponse implements ControlledEntityResponse{ @SerializedName(ApiConstants.ID) @Param(description="the vpn userID") diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 646bab9b7ce..e75a15cccff 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -17,6 +17,8 @@ package com.cloud.api; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; @@ -28,6 +30,7 @@ import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Matcher; +import com.cloud.dao.EntityManager; import org.apache.cloudstack.api.*; import org.apache.log4j.Logger; @@ -62,17 +65,16 @@ import com.cloud.utils.exception.CSExceptionErrorCode; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.uuididentity.dao.IdentityDao; -/** - * A class that dispatches API commands to the appropriate manager for execution. - */ +// ApiDispatcher: A class that dispatches API commands to the appropriate manager for execution. public class ApiDispatcher { private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName()); ComponentLocator _locator; Long _createSnapshotQueueSizeLimit; - @Inject AsyncJobManager _asyncMgr = null; + @Inject private AsyncJobManager _asyncMgr = null; + @Inject private AccountManager _accountMgr = null; + @Inject EntityManager _entityMgr = null; @Inject IdentityDao _identityDao = null; - @Inject AccountManager _accountMgr = null; Map> _daoNameMap = new HashMap>(); // singleton class @@ -105,7 +107,6 @@ public class ApiDispatcher { } public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map params) { - List entitiesToAccess = new ArrayList(); setupParameters(cmd, params, entitiesToAccess); @@ -150,15 +151,12 @@ public class ApiDispatcher { } } - private void doAccessChecks(BaseAsyncCreateCmd cmd, - List entitiesToAccess) { - + private void doAccessChecks(BaseAsyncCreateCmd cmd, List entitiesToAccess) { //owner Account caller = UserContext.current().getCaller(); - Account owner = s_instance._accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); + Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); List callerRoles = determineRole(caller); - List ownerRoles = determineRole(owner); //check permission to call this command for the caller @@ -166,10 +164,9 @@ public class ApiDispatcher { checkACLOnCommand(cmd); //check that caller can access the owner account. - s_instance._accountMgr.checkAccess(caller, null, true, owner); + _accountMgr.checkAccess(caller, null, true, owner); checkACLOnEntities(caller, entitiesToAccess); - } @@ -190,15 +187,14 @@ public class ApiDispatcher { //checkACLOnEntities if(!entitiesToAccess.isEmpty()){ for(ControlledEntity entity : entitiesToAccess) - s_instance._accountMgr.checkAccess(caller, null, true, entity); + _accountMgr.checkAccess(caller, null, true, entity); } - } public void dispatch(BaseCmd cmd, Map params) { List entitiesToAccess = new ArrayList(); setupParameters(cmd, params, entitiesToAccess); - + if(!entitiesToAccess.isEmpty()){ //owner Account caller = UserContext.current().getCaller(); @@ -390,6 +386,7 @@ public class ApiDispatcher { } } + // Process all the fields of the cmd object using reflection to recursively process super class Field[] fields = cmd.getClass().getDeclaredFields(); Class superClass = cmd.getClass().getSuperclass(); while (BaseCmd.class.isAssignableFrom(superClass)) { @@ -404,20 +401,22 @@ public class ApiDispatcher { } for (Field field : fields) { - - //plug Services - PlugService plugServiceAnnotation = field.getAnnotation(PlugService.class); - if(plugServiceAnnotation != null){ - plugService(field, cmd); - } - + //plug Services + PlugService plugServiceAnnotation = field.getAnnotation(PlugService.class); + if(plugServiceAnnotation != null){ + plugService(field, cmd); + } + //APITODO: change the checking here Parameter parameterAnnotation = field.getAnnotation(Parameter.class); if ((parameterAnnotation == null) || !parameterAnnotation.expose()) { continue; } - + // APITODO Will remove this IdentityMapper identityMapper = field.getAnnotation(IdentityMapper.class); + //ACL checkAccess = field.getAnnotation(ACL.class); + + Validator validators = field.getAnnotation(Validator.class); Object paramObj = unpackedParams.get(parameterAnnotation.name()); if (paramObj == null) { if (parameterAnnotation.required()) { @@ -587,37 +586,80 @@ public class ApiDispatcher { case INTEGER: 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 LONG: { - Long val = null; - if (identityMapper != null) - val = s_instance._identityDao.getIdentityId(identityMapper, token); - else - val = Long.valueOf(token); + 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: + //APITODO: FIXME if there is any APICmd that has List + break; + case LONG: { + Long val = null; + if (identityMapper != null) + val = s_instance._identityDao.getIdentityId(identityMapper, token); + else + val = Long.valueOf(token); - listParam.add(val); + listParam.add(val); + } + break; + case SHORT: + listParam.add(Short.valueOf(token)); + case STRING: + listParam.add(token); + break; + } } - break; - case SHORT: - listParam.add(Short.valueOf(token)); - case STRING: - listParam.add(token); - break; + field.set(cmdObj, listParam); + break; + case UUID: + // There may be multiple entities defined on the @Entity of a Response.class + // UUID CommandType would expect only one entityType, so use the first entityType + Class[] entities = annotation.entityType()[0].getAnnotation(Entity.class).value(); + Long id = null; + // 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) { + // findByXId returns a VO object using uuid, use reflect to get the Id + Object objVO = s_instance._entityMgr.findByXId(entity, paramObj.toString()); + if (objVO == null) { + continue; } + Method method = null; + try { + method = objVO.getClass().getMethod("getId", null); + } catch (NoSuchMethodException e) { + continue; + } catch (SecurityException e) { + continue; + } + // Invoke the getId method, get the internal long ID + // If that fails hide exceptions as the uuid may not exist + try { + id = (Long) method.invoke(objVO); + } catch (InvocationTargetException e) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + // Return on first non-null Id for the uuid entity + if (id != null) + break; } - field.set(cmdObj, listParam); + // If id is null, entity with the uuid was not found, throw exception + if (id == null) { + throw new InvalidParameterValueException("No entity with " + field.getName() + "(uuid)=" + + paramObj.toString() + " was found in the database."); + } + field.set(cmdObj, id); break; case LONG: - case UUID: + // APITODO: Remove identityMapper, simply convert the over the wire param to Long if (identityMapper != null) field.set(cmdObj, s_instance._identityDao.getIdentityId(identityMapper, paramObj.toString())); else diff --git a/server/src/com/cloud/dao/EntityManagerImpl.java b/server/src/com/cloud/dao/EntityManagerImpl.java index 1430c0834b2..4d7f7fb2dd7 100644 --- a/server/src/com/cloud/dao/EntityManagerImpl.java +++ b/server/src/com/cloud/dao/EntityManagerImpl.java @@ -45,8 +45,9 @@ public class EntityManagerImpl implements EntityManager, Manager { } @Override - public T findByXid(Class entityType, String xid) { - return null; + public T findByXId(Class entityType, String xid) { + GenericDao dao = (GenericDao)GenericDaoBase.getDao(entityType); + return dao.findByXId(xid); } @Override diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java index f36c4d80164..082748a532a 100755 --- a/utils/src/com/cloud/utils/db/GenericDao.java +++ b/utils/src/com/cloud/utils/db/GenericDao.java @@ -54,6 +54,9 @@ public interface GenericDao { T findByIdIncludingRemoved(ID id); T findById(ID id, boolean fresh); + + // Finds a VO object using uuid + T findByXId(ID uuid); /** * @return VO object ready to be used for update. It won't have any fields filled in. diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index be0fe89f3a7..6bc49bf963e 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -913,6 +913,14 @@ public abstract class GenericDaoBase implements Gene } } + @Override @DB(txn=false) + @SuppressWarnings("unchecked") + public T findByXId(final ID uuid) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid); + return findOneBy(sc); + } + @Override @DB(txn=false) public T findByIdIncludingRemoved(ID id) { return findById(id, true, null);