-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Triggering of stored processes. Closes #378
- Loading branch information
Showing
1 changed file
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
/** | ||
@file | ||
@brief Triggers a SASjs Server STP using the /SASjsApi/stp/trigger endpoint | ||
@details Triggers the STP and returns the sessionId | ||
Example: | ||
%ms_triggerstp(/some/stored/program | ||
,debug=131 | ||
,outds=work.myresults | ||
) | ||
@param [in] pgm The full path to the Stored Program in SASjs Drive (_program | ||
parameter) | ||
@param [in] debug= (131) The value to supply to the _debug URL parameter | ||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages | ||
@param [in] inputparams=(_null_) A dataset containing name/value pairs in the | ||
following format: | ||
|name:$32|value:$10000| | ||
|---|---| | ||
|stpmacname|some value| | ||
|mustbevalidname|can be anything, oops, %abort!!| | ||
@param [in] inputfiles= (_null_) A dataset containing fileref/name/filename in | ||
the following format: | ||
|fileref:$8|name:$32|filename:$256| | ||
|---|---|--| | ||
|someref|some_name|some_filename.xls| | ||
|fref2|another_file|zyx_v2.csv| | ||
@param [in] expiresaftermins= (15) The number of minutes to retain the session | ||
folder after the session ends. | ||
@param [out] outds= (work.ms_triggerstp) Set to the name of a dataset to | ||
contain the sessionId. If this dataset already exists, and contains the | ||
sessionId, it will be appended to. | ||
Format: | ||
|sessionId:$36| | ||
|---| | ||
|20241028074744-54132-1730101664824| | ||
<h4> SAS Macros </h4> | ||
@li mf_getuniquefileref.sas | ||
@li mf_getuniquename.sas | ||
@li mp_abort.sas | ||
@li mp_dropmembers.sas | ||
@li mf_nobs.sas | ||
**/ | ||
|
||
%macro ms_triggerstp(pgm | ||
,debug=131 | ||
,inputparams=_null_ | ||
,inputfiles=_null_ | ||
,expiresAfterMins=15 | ||
,outds=work.ms_triggerstp | ||
,mdebug=0 | ||
); | ||
%local dbg mainref authref boundary triggered_sid; | ||
%let mainref=%mf_getuniquefileref(); | ||
%let authref=%mf_getuniquefileref(); | ||
%let boundary=%mf_getuniquename(); | ||
%if &inputparams=0 %then %let inputparams=_null_; | ||
|
||
%if &mdebug=1 %then %do; | ||
%put &sysmacroname entry vars:; | ||
%put _local_; | ||
%end; | ||
%else %let dbg=*; | ||
|
||
|
||
%mp_abort(iftrue=("&pgm"="") | ||
,mac=&sysmacroname | ||
,msg=%str(Program not provided) | ||
) | ||
%mp_abort(iftrue=("&outds"="") | ||
,mac=&sysmacroname | ||
,msg=%str(Output dataset not provided) | ||
) | ||
|
||
/* avoid sending bom marker to API */ | ||
%local optval; | ||
%let optval=%sysfunc(getoption(bomfile)); | ||
options nobomfile; | ||
|
||
/* Add header to the content of the http request */ | ||
data _null_; | ||
file &mainref termstr=crlf lrecl=32767; | ||
put "--&boundary"; | ||
run; | ||
|
||
/* Add params to the content */ | ||
data _null_; | ||
file &mainref termstr=crlf lrecl=32767 mod; | ||
length line $1000 name $32 value $32767; | ||
if _n_=1 then call missing(of _all_); | ||
set &inputparams; | ||
line=cats('Content-Disposition: form-data; name="',name,'"'); | ||
put line; | ||
put ; | ||
put value; | ||
run; | ||
|
||
/* parse input file list */ | ||
%local webcount; | ||
%let webcount=0; | ||
data _null_; | ||
set &inputfiles end=last; | ||
length fileref $8 name $32 filename $256; | ||
call symputx(cats('webref',_n_),fileref,'l'); | ||
call symputx(cats('webname',_n_),name,'l'); | ||
call symputx(cats('webfilename',_n_),filename,'l'); | ||
if last then do; | ||
call symputx('webcount',_n_); | ||
call missing(of _all_); | ||
end; | ||
run; | ||
|
||
/* write out the input files to the content */ | ||
%local i; | ||
%do i=1 %to &webcount; | ||
data _null_; | ||
file &mainref termstr=crlf lrecl=32767 mod; | ||
infile &&webref&i lrecl=32767; | ||
if _n_ = 1 then do; | ||
length line $32767; | ||
line=cats( | ||
'Content-Disposition: form-data; name="' | ||
,"&&webname&i" | ||
,'"; filename="' | ||
,"&&webfilename&i" | ||
,'"' | ||
); | ||
put "--&boundary"; | ||
put line; | ||
put "Content-Type: text/plain"; | ||
put ; | ||
end; | ||
input; | ||
put _infile_; /* add the actual file to be sent */ | ||
run; | ||
%end; | ||
|
||
/* Add footer to the content */ | ||
data _null_; | ||
file &mainref termstr=crlf mod; | ||
put / "--&boundary--"; | ||
run; | ||
|
||
data _null_; | ||
file &authref lrecl=1000; | ||
infile "&_sasjs_tokenfile" lrecl=1000; | ||
input; | ||
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary"; | ||
put _infile_; | ||
run; | ||
|
||
%if &mdebug=1 %then %do; | ||
data _null_; | ||
if _n_ eq 1 then putlog "NOTE: ***** authref=&authref content *****"; | ||
infile &authref; | ||
input; | ||
put _infile_; | ||
data _null_; | ||
if _n_ eq 1 then putlog "NOTE: ***** mainref=&mainref content *****"; | ||
infile &mainref; | ||
input; | ||
put _infile_; | ||
run; | ||
%end; | ||
|
||
%local resp_path outref; | ||
%let resp_path=%sysfunc(pathname(work))/%mf_getuniquename(); | ||
%let outref=%mf_getuniquefileref(); | ||
filename &outref "&resp_path" lrecl=32767; | ||
|
||
/* prepare request*/ | ||
proc http method='POST' headerin=&authref in=&mainref out=&outref | ||
url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim( | ||
)_program=&pgm%str(&)_debug=131%str(&)expiresAfterMins=&expiresaftermins"; | ||
%if &mdebug=1 %then %do; | ||
debug level=2; | ||
%end; | ||
run; | ||
|
||
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201) | ||
or &mdebug=1 | ||
%then %do; | ||
data _null_; | ||
if _n_ eq 1 then putlog "NOTE: ***** outref=&outref content *****"; | ||
infile &outref; | ||
input; | ||
putlog _infile_; | ||
run; | ||
%end; | ||
%mp_abort( | ||
iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200 | ||
and &SYS_PROCHTTP_STATUS_CODE ne 201) | ||
,mac=&sysmacroname | ||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) | ||
) | ||
|
||
/* reset options */ | ||
options &optval; | ||
|
||
libname response JSON fileref=&outref; | ||
%let triggered_sid=%mf_getuniquename(prefix=triggered_sid_); | ||
|
||
data work.&triggered_sid (keep=sessionid); | ||
set response.root; | ||
|
||
%if &mdebug=1 %then %do; | ||
putlog (_all_)(=); | ||
%end; | ||
run; | ||
|
||
%if %mf_nobs(work.&triggered_sid)>0 %then %do; | ||
proc append base=&outds data=work.&triggered_sid; | ||
run; | ||
%end; | ||
|
||
%if &mdebug=1 %then %do; | ||
%put &sysmacroname exit vars:; | ||
%put _local_; | ||
%end; | ||
%else %do; | ||
/* clear refs */ | ||
filename &authref; | ||
filename &mainref; | ||
filename &outref; | ||
/* and remove temp dataset */ | ||
%mp_dropmembers(&triggered_sid,libref=work); | ||
%end; | ||
|
||
%mend ms_triggerstp; |