Search in sources :

Example 1 with BaseAsyncCreateCmd

use of org.apache.cloudstack.api.BaseAsyncCreateCmd in project cloudstack by apache.

the class CommandCreationWorker method handle.

@Override
public void handle(final DispatchTask task) {
    final BaseCmd cmd = task.getCmd();
    if (cmd instanceof BaseAsyncCreateCmd) {
        try {
            CallContext.current().setEventDisplayEnabled(cmd.isDisplay());
            ((BaseAsyncCreateCmd) cmd).create();
        } catch (final ResourceAllocationException e) {
            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, e.getMessage(), e);
        }
    } else {
        throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ATTEMP_TO_CREATE_NON_CREATION_CMD);
    }
}
Also used : ServerApiException(org.apache.cloudstack.api.ServerApiException) BaseAsyncCreateCmd(org.apache.cloudstack.api.BaseAsyncCreateCmd) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) BaseCmd(org.apache.cloudstack.api.BaseCmd)

Example 2 with BaseAsyncCreateCmd

use of org.apache.cloudstack.api.BaseAsyncCreateCmd in project cloudstack by apache.

the class ParamProcessWorker method doAccessChecks.

private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
    Account caller = CallContext.current().getCallingAccount();
    List<Long> entityOwners = cmd.getEntityOwnerIds();
    Account[] owners = null;
    if (entityOwners != null) {
        owners = entityOwners.stream().map(id -> _accountMgr.getAccount(id)).toArray(Account[]::new);
    } else {
        owners = new Account[] { _accountMgr.getAccount(cmd.getEntityOwnerId()) };
    }
    if (cmd instanceof BaseAsyncCreateCmd) {
        // check that caller can access the owner account.
        _accountMgr.checkAccess(caller, null, false, owners);
    }
    if (!entitiesToAccess.isEmpty()) {
        // check that caller can access the owner account.
        _accountMgr.checkAccess(caller, null, false, owners);
        for (Map.Entry<Object, AccessType> entry : entitiesToAccess.entrySet()) {
            Object entity = entry.getKey();
            if (entity instanceof ControlledEntity) {
                _accountMgr.checkAccess(caller, entry.getValue(), true, (ControlledEntity) entity);
            } else if (entity instanceof InfrastructureEntity) {
            // FIXME: Move this code in adapter, remove code from
            // Account manager
            }
        }
    }
}
Also used : Account(com.cloud.user.Account) ControlledEntity(org.apache.cloudstack.acl.ControlledEntity) BaseAsyncCreateCmd(org.apache.cloudstack.api.BaseAsyncCreateCmd) InfrastructureEntity(org.apache.cloudstack.acl.InfrastructureEntity) HashMap(java.util.HashMap) Map(java.util.Map) AccessType(org.apache.cloudstack.acl.SecurityChecker.AccessType)

Example 3 with BaseAsyncCreateCmd

use of org.apache.cloudstack.api.BaseAsyncCreateCmd in project cloudstack by apache.

the class CommandCreationWorkerTest method testHandle.

@Test
public void testHandle() throws ResourceAllocationException {
    // Prepare
    final BaseAsyncCreateCmd asyncCreateCmd = mock(BaseAsyncCreateCmd.class);
    final Map<String, String> params = new HashMap<String, String>();
    Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid");
    UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
    CallContext.register(user, account);
    // Execute
    final CommandCreationWorker creationWorker = new CommandCreationWorker();
    creationWorker.handle(new DispatchTask(asyncCreateCmd, params));
    // Assert
    verify(asyncCreateCmd, times(1)).create();
}
Also used : Account(com.cloud.user.Account) UserVO(com.cloud.user.UserVO) HashMap(java.util.HashMap) BaseAsyncCreateCmd(org.apache.cloudstack.api.BaseAsyncCreateCmd) AccountVO(com.cloud.user.AccountVO) Test(org.junit.Test)

Example 4 with BaseAsyncCreateCmd

use of org.apache.cloudstack.api.BaseAsyncCreateCmd in project cloudstack by apache.

the class ApiServer method queueCommand.

private String queueCommand(final BaseCmd cmdObj, final Map<String, String> params, StringBuilder log) throws Exception {
    final CallContext ctx = CallContext.current();
    final Long callerUserId = ctx.getCallingUserId();
    final Account caller = ctx.getCallingAccount();
    // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
    if (cmdObj instanceof BaseAsyncCmd) {
        Long objectId = null;
        String objectUuid = null;
        if (cmdObj instanceof BaseAsyncCreateCmd) {
            final BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj;
            dispatcher.dispatchCreateCmd(createCmd, params);
            objectId = createCmd.getEntityId();
            objectUuid = createCmd.getEntityUuid();
            params.put("id", objectId.toString());
            Class entityClass = EventTypes.getEntityClassForEvent(createCmd.getEventType());
            if (entityClass != null)
                ctx.putContextParameter(entityClass, objectUuid);
        } else {
            // Extract the uuid before params are processed and id reflects internal db id
            objectUuid = params.get(ApiConstants.ID);
            dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
        }
        final BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj;
        if (callerUserId != null) {
            params.put("ctxUserId", callerUserId.toString());
        }
        if (caller != null) {
            params.put("ctxAccountId", String.valueOf(caller.getId()));
        }
        if (objectUuid != null) {
            params.put("uuid", objectUuid);
        }
        long startEventId = ctx.getStartEventId();
        asyncCmd.setStartEventId(startEventId);
        // save the scheduled event
        final Long eventId = ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? (Long) User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), asyncCmd.isDisplay(), startEventId);
        if (startEventId == 0) {
            // There was no create event before, set current event id as start eventId
            startEventId = eventId;
        }
        params.put("ctxStartEventId", String.valueOf(startEventId));
        params.put("cmdEventType", asyncCmd.getEventType().toString());
        params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters()));
        Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
        // users can provide the job id they want to use, so log as it is a uuid and is unique
        String injectedJobId = asyncCmd.getInjectedJobId();
        uuidMgr.checkUuidSimple(injectedJobId, AsyncJob.class);
        AsyncJobVO job = new AsyncJobVO("", callerUserId, caller.getId(), cmdObj.getClass().getName(), ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null, injectedJobId);
        job.setDispatcher(asyncDispatcher.getName());
        final long jobId = asyncMgr.submitAsyncJob(job);
        if (jobId == 0L) {
            final String errorMsg = "Unable to schedule async job for command " + job.getCmd();
            s_logger.warn(errorMsg);
            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
        }
        final String response;
        if (objectId != null) {
            final String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
            response = getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd) asyncCmd, objUuid);
        } else {
            SerializationContext.current().setUuidTranslation(true);
            response = getBaseAsyncResponse(jobId, asyncCmd);
        }
        // Always log response for async for now, I don't think any sensitive data will be in here.
        // It might be nice to send this through scrubbing similar to how
        // ApiResponseSerializer.toSerializedStringWithSecureLogs works. For now, this gets jobid's
        // in the api logs.
        log.append(response);
        return response;
    } else {
        dispatcher.dispatch(cmdObj, params, false);
        // 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) && !(cmdObj instanceof ListSecurityGroupsCmd) && !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) && !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) && !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) && !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) && !(cmdObj instanceof ListZonesCmd)) {
            buildAsyncListResponse((BaseListCmd) cmdObj, caller);
        }
        SerializationContext.current().setUuidTranslation(true);
        return ApiResponseSerializer.toSerializedStringWithSecureLogs((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType(), log);
    }
}
Also used : UserAccount(com.cloud.user.UserAccount) Account(com.cloud.user.Account) ListHostsCmd(org.apache.cloudstack.api.command.admin.host.ListHostsCmd) AsyncJobVO(org.apache.cloudstack.framework.jobs.impl.AsyncJobVO) ListZonesCmd(org.apache.cloudstack.api.command.user.zone.ListZonesCmd) ServerApiException(org.apache.cloudstack.api.ServerApiException) ListProjectInvitationsCmd(org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd) ListProjectAccountsCmd(org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd) ListAccountsCmd(org.apache.cloudstack.api.command.user.account.ListAccountsCmd) DispatchTask(com.cloud.api.dispatch.DispatchTask) ListUsersCmd(org.apache.cloudstack.api.command.admin.user.ListUsersCmd) BaseListCmd(org.apache.cloudstack.api.BaseListCmd) ListSecurityGroupsCmd(org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd) ListEventsCmd(org.apache.cloudstack.api.command.user.event.ListEventsCmd) ListVolumesCmd(org.apache.cloudstack.api.command.user.volume.ListVolumesCmd) ListDiskOfferingsCmd(org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd) BaseAsyncCreateCmd(org.apache.cloudstack.api.BaseAsyncCreateCmd) ListRoutersCmd(org.apache.cloudstack.api.command.admin.router.ListRoutersCmd) ListProjectsCmd(org.apache.cloudstack.api.command.user.project.ListProjectsCmd) CallContext(org.apache.cloudstack.context.CallContext) ListVMGroupsCmd(org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd) BaseAsyncCmd(org.apache.cloudstack.api.BaseAsyncCmd) ListVMsCmd(org.apache.cloudstack.api.command.user.vm.ListVMsCmd) ListStoragePoolsCmd(org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd) ListServiceOfferingsCmd(org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd) ListTagsCmd(org.apache.cloudstack.api.command.user.tag.ListTagsCmd)

Example 5 with BaseAsyncCreateCmd

use of org.apache.cloudstack.api.BaseAsyncCreateCmd in project cloudstack by apache.

the class ApiAsyncJobDispatcher method runJob.

@Override
public void runJob(final AsyncJob job) {
    BaseAsyncCmd cmdObj = null;
    try {
        Class<?> cmdClass = Class.forName(job.getCmd());
        cmdObj = (BaseAsyncCmd) cmdClass.newInstance();
        cmdObj = ComponentContext.inject(cmdObj);
        cmdObj.configure();
        cmdObj.setJob(job);
        Type mapType = new TypeToken<Map<String, String>>() {
        }.getType();
        Gson gson = ApiGsonHelper.getBuilder().create();
        Map<String, String> params = gson.fromJson(job.getCmdInfo(), mapType);
        // whenever we deserialize, the UserContext needs to be updated
        String userIdStr = params.get("ctxUserId");
        String acctIdStr = params.get("ctxAccountId");
        String contextDetails = params.get("ctxDetails");
        Long userId = null;
        Account accountObject = null;
        if (cmdObj instanceof BaseAsyncCreateCmd) {
            BaseAsyncCreateCmd create = (BaseAsyncCreateCmd) cmdObj;
            create.setEntityId(Long.parseLong(params.get("id")));
            create.setEntityUuid(params.get("uuid"));
        }
        User user = null;
        if (userIdStr != null) {
            userId = Long.parseLong(userIdStr);
            user = _entityMgr.findById(User.class, userId);
        }
        if (acctIdStr != null) {
            accountObject = _entityMgr.findById(Account.class, Long.parseLong(acctIdStr));
        }
        CallContext ctx = CallContext.register(user, accountObject);
        if (contextDetails != null) {
            Type objectMapType = new TypeToken<Map<Object, Object>>() {
            }.getType();
            ctx.putContextParameters((Map<Object, Object>) gson.fromJson(contextDetails, objectMapType));
        }
        try {
            // dispatch could ultimately queue the job
            _dispatcher.dispatch(cmdObj, params, true);
            // serialize this to the async job table
            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, ApiSerializerHelper.toSerializedString(cmdObj.getResponseObject()));
        } catch (InvalidParameterValueException ipve) {
            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ipve.getMessage());
        } finally {
            CallContext.unregister();
        }
    } 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 {
            ServerApiException sApiEx = (ServerApiException) e;
            errorMsg = sApiEx.getDescription();
            errorCode = sApiEx.getErrorCode().getHttpCode();
        }
        ExceptionResponse response = new ExceptionResponse();
        response.setErrorCode(errorCode);
        response.setErrorText(errorMsg);
        response.setResponseName((cmdObj == null) ? "unknowncommandresponse" : cmdObj.getCommandName());
        // FIXME:  setting resultCode to ApiErrorCode.INTERNAL_ERROR is not right, usually executors have their exception handling
        // and we need to preserve that as much as possible here
        _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), ApiSerializerHelper.toSerializedString(response));
    }
}
Also used : Account(com.cloud.user.Account) User(com.cloud.user.User) ExceptionResponse(org.apache.cloudstack.api.response.ExceptionResponse) BaseAsyncCreateCmd(org.apache.cloudstack.api.BaseAsyncCreateCmd) Gson(com.google.gson.Gson) CallContext(org.apache.cloudstack.context.CallContext) BaseAsyncCmd(org.apache.cloudstack.api.BaseAsyncCmd) Type(java.lang.reflect.Type) ServerApiException(org.apache.cloudstack.api.ServerApiException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) Map(java.util.Map)

Aggregations

BaseAsyncCreateCmd (org.apache.cloudstack.api.BaseAsyncCreateCmd)5 Account (com.cloud.user.Account)4 ServerApiException (org.apache.cloudstack.api.ServerApiException)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 BaseAsyncCmd (org.apache.cloudstack.api.BaseAsyncCmd)2 CallContext (org.apache.cloudstack.context.CallContext)2 DispatchTask (com.cloud.api.dispatch.DispatchTask)1 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)1 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)1 AccountVO (com.cloud.user.AccountVO)1 User (com.cloud.user.User)1 UserAccount (com.cloud.user.UserAccount)1 UserVO (com.cloud.user.UserVO)1 Gson (com.google.gson.Gson)1 Type (java.lang.reflect.Type)1 ControlledEntity (org.apache.cloudstack.acl.ControlledEntity)1 InfrastructureEntity (org.apache.cloudstack.acl.InfrastructureEntity)1 AccessType (org.apache.cloudstack.acl.SecurityChecker.AccessType)1 BaseCmd (org.apache.cloudstack.api.BaseCmd)1