Files
svc-api-x/v1/resources/instance_operation_run.cfc
T

236 lines
11 KiB
Plaintext

<cfcomponent extends="taffy.core.resource" taffy:uri="/instanceOperations/{instanceOperationUid}/run">
<cfsilent>
<cfimport prefix="m" taglib="../lib"/>
<cfset this.helper=CreateObject("component","lib.rest_api_helper")/><!---*** странно, почему мы его видим?---><!---вынести в апп?--->
</cfsilent>
<cffunction name="post" hint="Запуск выполнения операции">
<cfargument name="instanceOperationUid" type="string" required=true hint="type:guid"/>
<cfset local={}/>
<!--- <cfset local.instanceUid=#createGUID()#/> --->
<!--- *** Проверить наличие обязательных CFS параметров
Создать RFS параметры
(валидируем CFS параметры при создании, а не сейчас)
Проверить, что операция уже не выполняется
--->
<cftry>
<!---NOT NULL fields--->
<cfset this.helper.keyExistsAndValid(arguments, "instanceOperationUid", "guid")/>
<!--- Check operation status --->
<cfquery name="local.qCheckStarted" result="local.result">
select io.dt_submit, io.dt_finish, io.submit_result
from instance_operation io
where io.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#" null=#!isValid('guid',arguments.instanceOperationUid)#/>
</cfquery> <!--- <cfdump var=#local.qCheckStarted.dt_finish#/><cfabort/> --->
<cfif local.qCheckStarted.recordCount EQ 0>
<cfreturn representationOf(this.helper.formatMessage("There is no configured instance operation with uid #arguments.instanceOperationUid#","Instance operation not found")).withStatus(404)/>
<cfelseif left(local.qCheckStarted.submit_result,1) EQ "2" AND len(local.qCheckStarted.dt_finish) EQ 0><!--- 201 etc --->
<cfreturn representationOf(this.helper.formatMessage("Operation already started", "Parameter creation disabled for started operation")).withStatus(422)/>
</cfif>
<cfset generateRfsParams(arguments.instanceOperationUid, arguments.usrId)/>
<cfset submitJob(arguments.instanceOperationUid)/>
<cfcatch type="invalidParamValue">
<cfreturn representationOf(this.helper.formatBadRequestError(cfcatch)).withStatus(400)/>
</cfcatch>
<cfcatch type="missingDependency">
<cfreturn representationOf(this.helper.formatException(cfcatch,"Missing Dependency")).withStatus(424)/>
</cfcatch>
</cftry>
<!--- <cfreturn representationOf("Not Implemented yet").withStatus(501)/> --->
<cfset generateRfsParams(arguments.instanceOperationUid)/>
<!--- --->
<cfreturn noData().withStatus(201, "Created") />
</cffunction>
<cffunction name="generateRfsParams">
<cfargument name="instanceOperationUid" type="guid"/>
<cfargument name="usrId" type="numeric"/>
<!---
-- полезный селект, не выбрасывать
<cfquery name="qSvcOperationCfsParam">
select sop.svc_operation_cfs_param_id
,iop.instance_operation_cfs_param_uid::text as instance_operation_cfs_param_uid /*pgjdbc issue fix*/
,iop.param_value
,sop.svc_operation_cfs_param
,sop.data_type
,sop.is_required
,sop.maxlength,sop.minlength,sop.regex,sop.unique_scope
from instance_operation io
join instance e on (io.instance_uid=e.instance_uid)
join svc_operation so on (e.service_id=so.svc_id AND io.operation=so.operation)
join svc_operation_cfs_param sop on (so.svc_operation_id=sop.svc_operation_id)
left outer join instance_operation_cfs_param iop
on (sop.svc_operation_cfs_param_id=iop.svc_operation_cfs_param_id AND io.instance_operation_uid=iop.instance_operation_uid)
where iop.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid# null=#!isValid("guid",arguments.instanceOperationUid)#/>)
</cfquery>
--->
<cfquery name="qSvcOperation">
select so.svc_operation_id, io.instance_uid
from instance_operation io
join instance e on (io.instance_uid=e.instance_uid)
join svc_operation so on (e.service_id=so.svc_id AND io.operation=so.operation)
where io.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid# null=#!isValid("guid",arguments.instanceOperationUid)#/>
</cfquery>
<!--- поступим проще, по engine/generate_rfs_12.cfm --->
<cfset setInstanceOperationRfsParam(arguments.instanceOperationUid, "instanceUid", qSvcOperation.instance_uid)/>
<cfset setInstanceOperationRfsParam(arguments.instanceOperationUid, "operationUid", arguments.instanceOperationUid)/>
<cfset setInstanceOperationRfsParam(arguments.instanceOperationUid, "modifierId", #arguments.usrId#)/>
<cfquery name="qWriteRfsFromCfsParams">
insert into instance_operation_param (instance_operation_uid,param,param_value)
select
iocp.instance_operation_uid
,sop.svc_operation_param
,iocp.param_value
from instance_operation_cfs_param iocp
join svc_operation_cfs_param socp on (iocp.svc_operation_cfs_param_id=socp.svc_operation_cfs_param_id)
join svc_operation_param sop on (socp.svc_operation_id=sop.svc_operation_id AND socp.svc_operation_cfs_param=sop.svc_operation_param)
where iocp.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#"/>
/*PostgreSQL specific*/
ON CONFLICT (instance_operation_uid,param)
DO UPDATE SET param_value = EXCLUDED.param_value;
</cfquery>
<!--- так яснее, но можно было все в один запрос --->
<cfquery name="qWriteRfsParamsFromDefaults">
insert into instance_operation_param (instance_operation_uid,param,param_value)
select
<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#"/>
,sop.svc_operation_param
,sop.default_value
from svc_operation_param sop
where sop.svc_operation_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#qSvcOperation.svc_operation_id#"/> AND length(sop.default_value)>0 /***null will be better*/
/*PostgreSQL specific*/
ON CONFLICT (instance_operation_uid,param)
DO NOTHING;
</cfquery>
</cffunction>
<cffunction name="submitJob">
<cfargument name="instanceOperationUid" type="string" required=true hint="type:guid"/>
<cfquery name="qInstanceOperation">
select so.url
from instance_operation o
join instance i on (o.instance_uid=i.instance_uid)
left outer join svc_operation so on (i.service_id=so.svc_id AND o.operation=so.operation)
where o.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid#/>
</cfquery>
<cfquery name="qInstanceOperationParam">
select iop.param, iop.param_value
from instance_operation_param iop
where iop.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid#/>
AND length(iop.param)>0
</cfquery>
<cfquery name="qMarkOperationStart">
update instance_operation
set dt_submit=<cfqueryparam cfsqltype="cf_sql_timestamp" value=#now()#/>
,dt_start=null, dt_finish=null, submit_result='0'
where instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid#/>
</cfquery>
<cftry>
<cfhttp method="post"
url="#qInstanceOperation.url#"
multipart=true
multipartType="form-data"
timeout="3"
charset="utf-8"
result="orchestrator"
>
<cfhttpparam type="HEADER" name="Authorization" value="#request.ORCHESTRATOR_AUTH#"/>
<cfhttpparam type="HEADER" name="Accept" value="application/json"/>
<cfhttpparam type="formfield" name="delay" value="0sec"/>
<cfloop query="qInstanceOperationParam">
<cfhttpparam type="formfield" name="#param#" value="#param_value#"/>
</cfloop>
</cfhttp>
<cfcatch type="any">
<cfthrow message="Cannot initiate connection to the orchestrator #cfcatch.message#" detail="#cfcatch.detail#"/>
<!--- <cfdump var=#qInstanceOperation#/>
<cfabort/> --->
</cfcatch>
</cftry>
<cfif len(orchestrator.errorDetail)>
<cfthrow type="missingDependency" message="Orchestrator communication error" detail="#orchestrator.errorDetail#"/>
<!--- лучше бы возвращать 503 или 424 --->
</cfif>
<cfquery name="qMarkOperationSubmit">
update instance_operation
set submit_result=<cfqueryparam cfsqltype="cf_sql_varchar" value=#orchestrator.responseHeader.status_code#/>
where instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid#/>
</cfquery>
<cfset sleep(0)/><!--- если придется подождать, можно добавить, но мы специально указываем delay=0sec --->
<cfif listFind("200,201",#orchestrator.responseHeader.status_code#)>
<cftry>
<cfset var buildURL="#orchestrator.responseHeader.Location#/api/json"/>
<cfhttp method="get"
url="#buildUrl#"
timeout="3"
charset="utf-8"
result="job"
>
<cfhttpparam type="HEADER" name="Authorization" value="#request.ORCHESTRATOR_AUTH#">
<cfhttpparam type="HEADER" name="Accept" value="application/json">
</cfhttp>
<cfset var jobData=#deserializeJson(job.filecontent)#/>
<!--- jobData: <cfdump var=#jobData#/> --->
<cfset operation_url=jobData.executable.url />
<cfquery name="qSetStatusUrl">
update instance_operation
set status_url=<cfqueryparam cfsqltype="cf_sql_varchar" value="#operation_url#api/json"/><!--- *** костыль --->
where instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationUid#/>
</cfquery>
<cfcatch type="any">
<cfrethrow/><!--- пока не придумал --->
</cfcatch>
</cftry>
</cfif>
</cffunction>
<cffunction name="setInstanceOperationRfsParam">
<cfargument name="instanceOperationUid" type="guid">
<cfargument name="param"><!--- значение не должно содержать лишних пробелов, чувствительность к регистру определяется БД --->
<cfargument name="val">
<cfquery name="qSaveRfsParam">
insert into instance_operation_param (instance_operation_uid,param,param_value)
values (
<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#"/>
,<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.param#"/>
,<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.val#"/>
)
/*PostgreSQL specific*/
ON CONFLICT (instance_operation_uid,param)
DO UPDATE SET param_value = EXCLUDED.param_value;
</cfquery>
<!--- <cfdump var=#ARGUMENTS#/> --->
</cffunction>
</cfcomponent>