public void init() { BaseCmd.setComponents(new ApiResponseHelper()); BaseListCmd.configure(); _systemAccount = _accountMgr.getSystemAccount(); _systemUser = _accountMgr.getSystemUser(); _dispatcher = ApiDispatcher.getInstance(); Integer apiPort = null; // api port, null by default ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); SearchCriteria<ConfigurationVO> sc = configDao.createSearchCriteria(); sc.addAnd("name", SearchCriteria.Op.EQ, "integration.api.port"); List<ConfigurationVO> values = configDao.search(sc, null); if ((values != null) && (values.size() > 0)) { ConfigurationVO apiPortConfig = values.get(0); if (apiPortConfig.getValue() != null) { apiPort = Integer.parseInt(apiPortConfig.getValue()); } } Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation( APICommand.class, new String[] {"org.apache.cloudstack.api", "com.cloud.api"}); for (Class<?> cmdClass : cmdClasses) { String apiName = cmdClass.getAnnotation(APICommand.class).name(); if (_apiNameCmdClassMap.containsKey(apiName)) { s_logger.error("API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName); continue; } _apiNameCmdClassMap.put(apiName, cmdClass); } encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())); String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; } if (apiPort != null) { ListenerThread listenerThread = new ListenerThread(this, apiPort); listenerThread.start(); } }
private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception { CallContext ctx = CallContext.current(); Long callerUserId = ctx.getCallingUserId(); Account caller = ctx.getCallingAccount(); // Queue command based on Cmd super class: // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as // BaseAsyncCmd. // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized // and returned. if (cmdObj instanceof BaseAsyncCmd) { Long objectId = null; String objectUuid = null; if (cmdObj instanceof BaseAsyncCreateCmd) { BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; _dispatcher.dispatchCreateCmd(createCmd, params); objectId = createCmd.getEntityId(); objectUuid = createCmd.getEntityUuid(); params.put("id", objectId.toString()); } else { ApiDispatcher.processParameters(cmdObj, params); } BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj; if (callerUserId != null) { params.put("ctxUserId", callerUserId.toString()); } if (caller != null) { params.put("ctxAccountId", String.valueOf(caller.getId())); } long startEventId = ctx.getStartEventId(); asyncCmd.setStartEventId(startEventId); // save the scheduled event Long eventId = ActionEventUtils.onScheduledActionEvent( (callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), 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()); Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId; AsyncJobVO job = new AsyncJobVO( ctx.getContextId(), callerUserId, caller.getId(), cmdObj.getClass().getName(), ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null); job.setDispatcher(_asyncDispatcher.getName()); long jobId = _asyncMgr.submitAsyncJob(job); if (jobId == 0L) { String errorMsg = "Unable to schedule async job for command " + job.getCmd(); s_logger.warn(errorMsg); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg); } if (objectId != null) { String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid; return getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd) asyncCmd, objUuid); } else { SerializationContext.current().setUuidTranslation(true); return getBaseAsyncResponse(jobId, asyncCmd); } } else { _dispatcher.dispatch(cmdObj, params, false); // if the command is of the listXXXCommand, we will need to also return the // the job id and status if possible // For those listXXXCommand which we have already created DB views, this step is not needed // since async job is joined in their db views. 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 ListZonesByCmd)) { buildAsyncListResponse((BaseListCmd) cmdObj, caller); } SerializationContext.current().setUuidTranslation(true); return ApiResponseSerializer.toSerializedString( (ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); } }
@Override public boolean start() { Integer apiPort = null; // api port, null by default SearchCriteria<ConfigurationVO> sc = _configDao.createSearchCriteria(); sc.addAnd("name", SearchCriteria.Op.EQ, Config.IntegrationAPIPort.key()); List<ConfigurationVO> values = _configDao.search(sc, null); if ((values != null) && (values.size() > 0)) { ConfigurationVO apiPortConfig = values.get(0); if (apiPortConfig.getValue() != null) { apiPort = Integer.parseInt(apiPortConfig.getValue()); } } Map<String, String> configs = _configDao.getConfiguration(); String strSnapshotLimit = configs.get(Config.ConcurrentSnapshotsThresholdPerHost.key()); if (strSnapshotLimit != null) { Long snapshotLimit = NumbersUtil.parseLong(strSnapshotLimit, 1L); if (snapshotLimit.longValue() <= 0) { s_logger.debug( "Global config parameter " + Config.ConcurrentSnapshotsThresholdPerHost.toString() + " is less or equal 0; defaulting to unlimited"); } else { _dispatcher.setCreateSnapshotQueueSizeLimit(snapshotLimit); } } Set<Class<?>> cmdClasses = new HashSet<Class<?>>(); for (PluggableService pluggableService : _pluggableServices) { cmdClasses.addAll(pluggableService.getCommands()); if (s_logger.isDebugEnabled()) { s_logger.debug("Discovered plugin " + pluggableService.getClass().getSimpleName()); } } for (Class<?> cmdClass : cmdClasses) { APICommand at = cmdClass.getAnnotation(APICommand.class); if (at == null) { throw new CloudRuntimeException( String.format( "%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName())); } String apiName = at.name(); if (_apiNameCmdClassMap.containsKey(apiName)) { s_logger.error("API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName); continue; } _apiNameCmdClassMap.put(apiName, cmdClass); } encodeApiResponse = Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key())); String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; } if (apiPort != null) { ListenerThread listenerThread = new ListenerThread(this, apiPort); listenerThread.start(); } return true; }