1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-09 18:30:06 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
github-actions
d0102f7df0 chore: updating all.sas 2025-02-24 11:00:24 +00:00
a
aad1486c73 feat: triggerstp Stored Program 2025-02-24 10:59:48 +00:00
3 changed files with 291 additions and 412 deletions

307
all.sas
View File

@@ -23115,7 +23115,7 @@ run;
%mend ms_testservice; %mend ms_testservice;
/** /**
@file @file
@brief Triggers a SASjs Server STP using the /SASjsApi/stp/trigger endpoint @brief Triggers a SASjs Server STP using the /SASjsApi/code/trigger endpoint
@details Triggers the STP and returns the sessionId @details Triggers the STP and returns the sessionId
Example: Example:
@@ -23141,8 +23141,6 @@ run;
|---|---|--| |---|---|--|
|someref|some_name|some_filename.xls| |someref|some_name|some_filename.xls|
|fref2|another_file|zyx_v2.csv| |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 @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 contain the sessionId. If this dataset already exists, and contains the
@@ -23154,11 +23152,8 @@ run;
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_getuniquename.sas @li mf_getuniquename.sas
@li mp_abort.sas @li mp_abort.sas
@li mp_dropmembers.sas
@li mf_nobs.sas
**/ **/
@@ -23166,184 +23161,174 @@ run;
,debug=131 ,debug=131
,inputparams=_null_ ,inputparams=_null_
,inputfiles=_null_ ,inputfiles=_null_
,expiresAfterMins=15
,outds=work.ms_triggerstp ,outds=work.ms_triggerstp
,mdebug=0 ,mdebug=0
); );
%local dbg mainref authref boundary libref triggered_sid; %local dbg mainref authref;
%let mainref=%mf_getuniquefileref(); %let mainref=%mf_getuniquefileref();
%let authref=%mf_getuniquefileref(); %let authref=%mf_getuniquefileref();
%let boundary=%mf_getuniquename(); %if &inputparams=0 %then %let inputparams=_null_;
%if &inputparams=0 %then %let inputparams=_null_;
%if &mdebug=1 %then %do; %if &mdebug=1 %then %do;
%put &sysmacroname entry vars:; %put &sysmacroname entry vars:;
%put _local_; %put _local_;
%end; %end;
%else %let dbg=*; %else %let dbg=*;
%mp_abort(iftrue=("&pgm"="") %mp_abort(iftrue=("&pgm"="")
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(Program not provided) ,msg=%str(Program not provided)
) )
%mp_abort(iftrue=("&outds"="")
,mac=&sysmacroname
,msg=%str(Output dataset not provided)
)
/* avoid sending bom marker to API */ /* avoid sending bom marker to API */
%local optval; %local optval;
%let optval=%sysfunc(getoption(bomfile)); %let optval=%sysfunc(getoption(bomfile));
options nobomfile; options nobomfile;
/* Add params to the content */ /* add params */
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;
put "--&boundary";
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 */
%local i;
%do i=1 %to &webcount;
data _null_; data _null_;
file &mainref termstr=crlf lrecl=32767 mod; file &mainref termstr=crlf lrecl=32767 mod;
length line $1000 name $32 value $32767; infile &&webref&i lrecl=32767;
if _n_=1 then call missing(of _all_); if _n_ = 1 then do;
set &inputparams; length line $32767;
put "--&boundary"; line=cats(
line=cats('Content-Disposition: form-data; name="',name,'"'); 'Content-Disposition: form-data; name="'
put line; ,"&&webname&i"
put ; ,'"; filename="'
put value; ,"&&webfilename&i"
run; ,'"'
);
/* parse input file list */ put "--&boundary";
%local webcount; put line;
%let webcount=0; put "Content-Type: text/plain";
data _null_; put ;
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; 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; input;
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary"; put _infile_; /* add the actual file to be sent */
run;
%end;
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_;
infile &authref;
input;
put _infile_;
data _null_;
infile &mainref;
input;
put _infile_; put _infile_;
run; run;
%end;
%if &mdebug=1 %then %do; %local resp_path;
data _null_; %let resp_path=%sysfunc(pathname(work))/%mf_getuniquename();
if _n_ eq 1 then putlog "NOTE: ***** authref=&authref content *****"; filename &outref "&resp_path" lrecl=32767;
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; /* prepare request*/
%let resp_path=%sysfunc(pathname(work))/%mf_getuniquename(); proc http method='POST' headerin=&authref in=&mainref out=&outref
%let outref=%mf_getuniquefileref(); url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim(
filename &outref "&resp_path" lrecl=32767; )_program=&pgm%str(&)_debug=131";
%if &mdebug=1 %then %do;
debug level=2;
%end;
run;
/* prepare request*/ %if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
proc http method='POST' headerin=&authref in=&mainref out=&outref or &mdebug=1
url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim( %then %do;
)_program=&pgm%str(&)_debug=131%str(&)expiresAfterMins=&expiresaftermins"; data _null_;infile &outref;input;putlog _infile_;run;
%if &mdebug=1 %then %do; %end;
debug level=2; %mp_abort(
%end; iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
run; ,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201) /* reset options */
or &mdebug=1 options &optval;
%then %do;
data _null_; data work.%mf_getuniquename();
if _n_ eq 1 then putlog "NOTE: ***** outref=&outref content *****"; infile "&resp_path";
infile &outref; input
input;
putlog _infile_; %if &outlogds ne _null_ or &mdebug=1 %then %do;
run; %local matchstr chopout;
%end; %let matchstr=SASJS_LOGS_SEPARATOR_163ee17b6ff24f028928972d80a26784;
%mp_abort( %let chopout=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop);
iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200
and &SYS_PROCHTTP_STATUS_CODE ne 201) %mp_chop("&resp_path"
,mac=&sysmacroname ,matchvar=matchstr
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,keep=LAST
,matchpoint=END
,outfile="&chopout"
,mdebug=&mdebug
) )
/* reset options */ data &outlogds;
options &optval; infile "&chopout" lrecl=2000;
length line $2000;
%let libref=%mf_getuniquelibref(); line=_infile_;
libname &libref JSON fileref=&outref;
%let triggered_sid=%mf_getuniquename(prefix=triggered_sid_);
data work.&triggered_sid (keep=sessionid);
set &libref..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; %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:; putlog line=;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &authref;
filename &mainref;
filename &outref;
libname &libref clear;
/* and remove temp dataset */
%mp_dropmembers(&triggered_sid,libref=work);
%end; %end;
run;
%end;
%mend ms_triggerstp;/** %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &authref;
filename &mainref;
%end;
%mend ms_triggerstp;
/**
@file @file
@brief Send data to/from sasjs/server @brief Send data to/from sasjs/server
@details This macro should be added to the start of each web service, @details This macro should be added to the start of each web service,

View File

@@ -1,6 +1,6 @@
/** /**
@file @file
@brief Triggers a SASjs Server STP using the /SASjsApi/stp/trigger endpoint @brief Triggers a SASjs Server STP using the /SASjsApi/code/trigger endpoint
@details Triggers the STP and returns the sessionId @details Triggers the STP and returns the sessionId
Example: Example:
@@ -26,8 +26,6 @@
|---|---|--| |---|---|--|
|someref|some_name|some_filename.xls| |someref|some_name|some_filename.xls|
|fref2|another_file|zyx_v2.csv| |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 @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 contain the sessionId. If this dataset already exists, and contains the
@@ -39,11 +37,8 @@
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_getuniquename.sas @li mf_getuniquename.sas
@li mp_abort.sas @li mp_abort.sas
@li mp_dropmembers.sas
@li mf_nobs.sas
**/ **/
@@ -51,181 +46,170 @@
,debug=131 ,debug=131
,inputparams=_null_ ,inputparams=_null_
,inputfiles=_null_ ,inputfiles=_null_
,expiresAfterMins=15
,outds=work.ms_triggerstp ,outds=work.ms_triggerstp
,mdebug=0 ,mdebug=0
); );
%local dbg mainref authref boundary libref triggered_sid; %local dbg mainref authref;
%let mainref=%mf_getuniquefileref(); %let mainref=%mf_getuniquefileref();
%let authref=%mf_getuniquefileref(); %let authref=%mf_getuniquefileref();
%let boundary=%mf_getuniquename(); %if &inputparams=0 %then %let inputparams=_null_;
%if &inputparams=0 %then %let inputparams=_null_;
%if &mdebug=1 %then %do; %if &mdebug=1 %then %do;
%put &sysmacroname entry vars:; %put &sysmacroname entry vars:;
%put _local_; %put _local_;
%end; %end;
%else %let dbg=*; %else %let dbg=*;
%mp_abort(iftrue=("&pgm"="") %mp_abort(iftrue=("&pgm"="")
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(Program not provided) ,msg=%str(Program not provided)
) )
%mp_abort(iftrue=("&outds"="")
,mac=&sysmacroname
,msg=%str(Output dataset not provided)
)
/* avoid sending bom marker to API */ /* avoid sending bom marker to API */
%local optval; %local optval;
%let optval=%sysfunc(getoption(bomfile)); %let optval=%sysfunc(getoption(bomfile));
options nobomfile; options nobomfile;
/* Add params to the content */ /* add params */
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;
put "--&boundary";
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 */
%local i;
%do i=1 %to &webcount;
data _null_; data _null_;
file &mainref termstr=crlf lrecl=32767 mod; file &mainref termstr=crlf lrecl=32767 mod;
length line $1000 name $32 value $32767; infile &&webref&i lrecl=32767;
if _n_=1 then call missing(of _all_); if _n_ = 1 then do;
set &inputparams; length line $32767;
put "--&boundary"; line=cats(
line=cats('Content-Disposition: form-data; name="',name,'"'); 'Content-Disposition: form-data; name="'
put line; ,"&&webname&i"
put ; ,'"; filename="'
put value; ,"&&webfilename&i"
run; ,'"'
);
/* parse input file list */ put "--&boundary";
%local webcount; put line;
%let webcount=0; put "Content-Type: text/plain";
data _null_; put ;
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; 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; input;
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary"; put _infile_; /* add the actual file to be sent */
run;
%end;
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_;
infile &authref;
input;
put _infile_;
data _null_;
infile &mainref;
input;
put _infile_; put _infile_;
run; run;
%end;
%if &mdebug=1 %then %do; %local resp_path;
data _null_; %let resp_path=%sysfunc(pathname(work))/%mf_getuniquename();
if _n_ eq 1 then putlog "NOTE: ***** authref=&authref content *****"; filename &outref "&resp_path" lrecl=32767;
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; /* prepare request*/
%let resp_path=%sysfunc(pathname(work))/%mf_getuniquename(); proc http method='POST' headerin=&authref in=&mainref out=&outref
%let outref=%mf_getuniquefileref(); url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim(
filename &outref "&resp_path" lrecl=32767; )_program=&pgm%str(&)_debug=131";
%if &mdebug=1 %then %do;
debug level=2;
%end;
run;
/* prepare request*/ %if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
proc http method='POST' headerin=&authref in=&mainref out=&outref or &mdebug=1
url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim( %then %do;
)_program=&pgm%str(&)_debug=131%str(&)expiresAfterMins=&expiresaftermins"; data _null_;infile &outref;input;putlog _infile_;run;
%if &mdebug=1 %then %do; %end;
debug level=2; %mp_abort(
%end; iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
run; ,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201) /* reset options */
or &mdebug=1 options &optval;
%then %do;
data _null_; data work.%mf_getuniquename();
if _n_ eq 1 then putlog "NOTE: ***** outref=&outref content *****"; infile "&resp_path";
infile &outref; input
input;
putlog _infile_; %if &outlogds ne _null_ or &mdebug=1 %then %do;
run; %local matchstr chopout;
%end; %let matchstr=SASJS_LOGS_SEPARATOR_163ee17b6ff24f028928972d80a26784;
%mp_abort( %let chopout=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop);
iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200
and &SYS_PROCHTTP_STATUS_CODE ne 201) %mp_chop("&resp_path"
,mac=&sysmacroname ,matchvar=matchstr
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,keep=LAST
,matchpoint=END
,outfile="&chopout"
,mdebug=&mdebug
) )
/* reset options */ data &outlogds;
options &optval; infile "&chopout" lrecl=2000;
length line $2000;
%let libref=%mf_getuniquelibref(); line=_infile_;
libname &libref JSON fileref=&outref;
%let triggered_sid=%mf_getuniquename(prefix=triggered_sid_);
data work.&triggered_sid (keep=sessionid);
set &libref..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; %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:; putlog line=;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &authref;
filename &mainref;
filename &outref;
libname &libref clear;
/* and remove temp dataset */
%mp_dropmembers(&triggered_sid,libref=work);
%end; %end;
run;
%end;
%mend ms_triggerstp; %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &authref;
filename &mainref;
%end;
%mend ms_triggerstp;

View File

@@ -1,90 +0,0 @@
/**
@file
@brief Testing ms_triggerstp.sas macro
<h4> SAS Macros </h4>
@li mf_getuniquename.sas
@li mp_assert.sas
@li mp_assertscope.sas
@li ms_createfile.sas
@li ms_triggerstp.sas
@li mf_existds.sas
@li mp_assertdsobs.sas
@li mp_assertcols.sas
@li mf_getvartype.sas
@li ms_deletefile.sas
**/
/* first, create multiple STPs to run */
filename stpcode1 temp;
data _null_;
file stpcode1;
put '%put hello world;';
put '%put _all_;';
put 'data _null_; file _webout1; put "triggerstp test 1";run;';
run;
filename stpcode2 temp;
data _null_;
file stpcode2;
put '%put Lorem Ipsum;';
put '%put _all_;';
put 'data _null_; file _webout2; put "triggerstp test 2";run;';
run;
options mprint;
%let fname1=%mf_getuniquename();
%let fname2=%mf_getuniquename();
%ms_createfile(/sasjs/tests/&fname1..sas
,inref=stpcode1
,mdebug=1
)
%ms_createfile(/sasjs/tests/&fname2..sas
,inref=stpcode2
)
%mp_assertscope(SNAPSHOT)
%ms_triggerstp(/sasjs/tests/&fname1
,debug=131
,outds=work.mySessions
)
%ms_triggerstp(/sasjs/tests/&fname2
,outds=work.mySessions
)
%mp_assertscope(COMPARE
,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN)
%mp_assert(iftrue=%str(%mf_existds(work.mySessions)=1)
,desc=Testing output exists
,outds=work.test_results
)
%mp_assertdsobs(work.mySessions,
test=EQUALS 2,
desc=Testing observations,
outds=work.test_results
)
%mp_assertcols(work.mySessions,
cols=sessionid,
test=ALL,
desc=Testing column exists,
outds=work.test_results
)
data _null_;
retain contentCheck 1;
set work.mySessions end=last;
if missing(sessionID) then contentCheck = 0;
if last then do;
call symputx("contentCheck",contentCheck,"l");
end;
run;
%let typeCheck = %mf_getvartype(work.mySessions,sessionid);
%mp_assert(iftrue=%str(&typeCheck = C and &contentCheck = 1)
,desc=Testing type and content of output
,outds=work.test_results
)
%ms_deletefile(/sasjs/tests/&fname1..sas)
%ms_deletefile(/sasjs/tests/&fname2..sas)