1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-10 14:04:36 +00:00

fix: refreshed the testing toolkit, added debug options, updated documentation, included one new test (mv_getjobcode.sas)

This commit is contained in:
Allan Bowe
2021-05-08 23:27:55 +03:00
parent 298acc4e50
commit 4e564b5409
12 changed files with 691 additions and 248 deletions

418
all.sas
View File

@@ -6080,6 +6080,8 @@ libname &lib clear;
|mustbevalidname|can be anything, oops, %abort!!| |mustbevalidname|can be anything, oops, %abort!!|
@param [in] debug= (log) Provide the _debug value @param [in] debug= (log) Provide the _debug value
@param [in] viyaresult=(WEBOUT_JSON) The Viya result type to return. For
more info, see mv_getjobresult.sas
@param [out] outlib= (0) Output libref to contain the final tables. Set to @param [out] outlib= (0) Output libref to contain the final tables. Set to
0 if the service output is not in JSON format. 0 if the service output is not in JSON format.
@param [out] outref= (0) Output fileref to create, to contain the full _webout @param [out] outref= (0) Output fileref to create, to contain the full _webout
@@ -6104,8 +6106,16 @@ libname &lib clear;
inputparams=0, inputparams=0,
debug=log, debug=log,
outlib=0, outlib=0,
outref=0 outref=0,
viyaresult=WEBOUT_JSON
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local mdebug;
%if &debug ne 0 %then %do;
%let mdebug=1;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let mdebug=0;
/* sanitise inputparams */ /* sanitise inputparams */
%local pcnt; %local pcnt;
@@ -6130,22 +6140,6 @@ libname &lib clear;
) )
%end; %end;
/* parse the input files */
%local webcount i var;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%end;
%end;
%else %let webcount=0;
%local fref1 webref; %local fref1 webref;
%let fref1=%mf_getuniquefileref(); %let fref1=%mf_getuniquefileref();
@@ -6154,6 +6148,23 @@ libname &lib clear;
%local platform; %local platform;
%let platform=%mf_getplatform(); %let platform=%mf_getplatform();
%if &platform=SASMETA %then %do; %if &platform=SASMETA %then %do;
/* parse the input files */
%local webcount i var;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%end;
%end;
%else %let webcount=0;
proc stp program="&program"; proc stp program="&program";
inputparam _program="&program" inputparam _program="&program"
%do i=1 %to &webcount; %do i=1 %to &webcount;
@@ -6210,14 +6221,65 @@ libname &lib clear;
%end; %end;
%else %if &platform=SASVIYA %then %do; %else %if &platform=SASVIYA %then %do;
data ;
_program="&program"; /* prepare inputparams */
%local ds1;
%let ds1=%mf_getuniquename();
%if "&inputparams" ne "0" %then %do;
proc transpose data=&inputparams out=&ds1;
id name;
var value;
run;
%end;
%else %do;
data &ds1;run;
%end;
/* parse the input files - convert to sasjs params */
%local webcount i var sasjs_tables;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i sasjs&i.data;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%let sasjs_tables=&sasjs_tables &&webname&i;
data _null_;
infile &&webref&i lrecl=32767;
input;
if _n_=1 then call symputx("sasjs&i.data",_infile_);
else call symputx(
"sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_)
);
putlog "&sysmacroname infile: " _infile_;
run;
data &ds1;
set &ds1;
length sasjs&i.data $32767 sasjs_tables $1000;
sasjs&i.data=symget("sasjs&i.data");
sasjs_tables=symget("sasjs_tables");
run;
%end;
%end;
%else %let webcount=0;
data &ds1;
retain _program "&program";
set &ds1;
putlog "&sysmacroname inputparams:";
putlog (_all_)(=);
run; run;
%mv_jobflow(inds=&syslast %mv_jobflow(inds=&ds1
,maxconcurrency=1 ,maxconcurrency=1
,outds=work.results ,outds=work.results
,outref=&fref1 ,outref=&fref1
,mdebug=&mdebug
) )
/* show the log */ /* show the log */
data _null_; data _null_;
@@ -6229,12 +6291,14 @@ libname &lib clear;
data _null_; data _null_;
set work.results; set work.results;
call symputx('uri',uri); call symputx('uri',uri);
putlog "&sysmacroname: fetching results for " uri;
run; run;
/* fetch results from webout.json */ /* fetch results from webout.json */
%mv_getjobresult(uri=&uri, %mv_getjobresult(uri=&uri,
result=WEBOUT_JSON, result=&viyaresult,
outref=&outref, outref=&outref,
outlib=&outlib outlib=&outlib,
mdebug=&mdebug
) )
%end; %end;
@@ -6242,9 +6306,15 @@ libname &lib clear;
%put %str(ERR)OR: Unrecognised platform: &platform; %put %str(ERR)OR: Unrecognised platform: &platform;
%end; %end;
filename &webref clear; %if &mdebug=0 %then %do;
filename &webref clear;
%end;
%else %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%mend;/** %mend mp_testservice;/**
@file mp_testwritespeedlibrary.sas @file mp_testwritespeedlibrary.sas
@brief Tests the write speed of a new table in a SAS library @brief Tests the write speed of a new table in a SAS library
@details Will create a new table of a certain size in an @details Will create a new table of a certain size in an
@@ -12985,23 +13055,26 @@ run;
@li mf_isblank.sas @li mf_isblank.sas
@li mv_deletejes.sas @li mv_deletejes.sas
@param path= The full path (on SAS Drive) where the service will be created @param [in] path= The full path (on SAS Drive) where the service will be
@param name= The name of the service created
@param desc= The description of the service @param [in] name= The name of the service
@param precode= Space separated list of filerefs, pointing to the code that @param [in] desc= The description of the service
needs to be attached to the beginning of the service @param [in] precode= Space separated list of filerefs, pointing to the code
@param code= Fileref(s) of the actual code to be added that needs to be attached to the beginning of the service
@param access_token_var= The global macro variable to contain the access token @param [in] code= Fileref(s) of the actual code to be added
@param grant_type= valid values are "password" or "authorization_code" @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values are "password" or "authorization_code"
(unquoted). The default is authorization_code. (unquoted). The default is authorization_code.
@param replace= select NO to avoid replacing any existing service in that @param [in] replace=(YES) Select NO to avoid replacing any existing service in
location that location
@param adapter= the macro uses the sasjs adapter by default. To use another @param [in] adapter= the macro uses the sasjs adapter by default. To use
adapter, add a (different) fileref here. another adapter, add a (different) fileref here.
@param contextname= Choose a specific context on which to run the Job. Leave @param [in] contextname= Choose a specific context on which to run the Job. Leave
blank to use the default context. From Viya 3.5 it is possible to configure blank to use the default context. From Viya 3.5 it is possible to configure
a shared context - see a shared context - see
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -13017,9 +13090,17 @@ https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5p
,grant_type=sas_services ,grant_type=sas_services
,replace=YES ,replace=YES
,adapter=sasjs ,adapter=sasjs
,debug=0 ,mdebug=0
,contextname= ,contextname=
,debug=0 /* @TODO - Deprecate */
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -13072,7 +13153,7 @@ proc http method='GET' out=&fname1 &oauth_bearer
headers "Authorization"="Bearer &&&access_token_var"; headers "Authorization"="Bearer &&&access_token_var";
%end; %end;
run; run;
%if &debug %then %do; %if &mdebug=1 %then %do;
data _null_; data _null_;
infile &fname1; infile &fname1;
input; input;
@@ -13111,7 +13192,7 @@ proc http method='GET'
%end; %end;
'Accept'='application/vnd.sas.collection+json' 'Accept'='application/vnd.sas.collection+json'
'Accept-Language'='string'; 'Accept-Language'='string';
%if &debug=1 %then %do; %if &mdebug=1 %then %do;
debug level = 3; debug level = 3;
%end; %end;
run; run;
@@ -13166,9 +13247,9 @@ run;
* These put statements are auto generated - to change the macro, change the * These put statements are auto generated - to change the macro, change the
* source (mv_webout) and run `build.py` * source (mv_webout) and run `build.py`
*/ */
filename sasjs temp lrecl=3000; filename &adapter temp lrecl=3000;
data _null_; data _null_;
file sasjs; file &adapter;
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */"; put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
/* WEBOUT BEGIN */ /* WEBOUT BEGIN */
put ' '; put ' ';
@@ -13507,11 +13588,12 @@ data _null_;
run; run;
/* insert the code, escaping double quotes and carriage returns */ /* insert the code, escaping double quotes and carriage returns */
%&dbg.put &sysmacroname: Creating final input file;
%local x fref freflist; %local x fref freflist;
%let freflist= &adapter &precode &code ; %let freflist= &adapter &precode &code ;
%do x=1 %to %sysfunc(countw(&freflist)); %do x=1 %to %sysfunc(countw(&freflist));
%let fref=%scan(&freflist,&x); %let fref=%scan(&freflist,&x);
%put &sysmacroname: adding &fref; %&dbg.put &sysmacroname: adding &fref fileref;
data _null_; data _null_;
length filein 8 fileid 8; length filein 8 fileid 8;
filein = fopen("&fref","I",1,"B"); filein = fopen("&fref","I",1,"B");
@@ -13563,7 +13645,12 @@ data _null_;
put '"}'; put '"}';
run; run;
/* now we can create the job!! */ %if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
%put &sysmacroname: input about to be POSTed;
data _null_;infile &fname3;input;putlog _infile_;run;
%end;
%&dbg.put &sysmacroname: Creating the actual service!;
%local fname4; %local fname4;
%let fname4=%mf_getuniquefileref(); %let fname4=%mf_getuniquefileref();
proc http method='POST' proc http method='POST'
@@ -13576,22 +13663,18 @@ proc http method='POST'
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
"Accept"="application/vnd.sas.job.definition+json"; "Accept"="application/vnd.sas.job.definition+json";
%if &debug=1 %then %do; %if &mdebug=1 %then %do;
debug level = 3; debug level = 3;
%end; %end;
run; run;
/*data _null_;infile &fname4;input;putlog _infile_;run;*/ %if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
%put &sysmacroname: output from POSTing job definition;
data _null_;infile &fname4;input;putlog _infile_;run;
%end;
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201) %mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
filename &fname4 clear;
filename &adapter clear;
libname &libref1 clear;
/* get the url so we can give a helpful log message */ /* get the url so we can give a helpful log message */
%local url; %local url;
@@ -13606,6 +13689,19 @@ data _null_;
call symputx('url',url); call symputx('url',url);
run; run;
%if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
filename &fname4 clear;
filename &adapter clear;
libname &libref1 clear;
%end;
%put &sysmacroname: Job &name successfully created in &path; %put &sysmacroname: Job &name successfully created in &path;
%put &sysmacroname:; %put &sysmacroname:;
@@ -13615,7 +13711,7 @@ run;
%put &sysmacroname:; %put &sysmacroname:;
%put &sysmacroname:; %put &sysmacroname:;
%mend; %mend mv_createwebservice;
/** /**
@file mv_deletefoldermember.sas @file mv_deletefoldermember.sas
@brief Deletes an item in a Viya folder @brief Deletes an item in a Viya folder
@@ -14526,17 +14622,20 @@ libname &libref1 clear;
,outfile=/tmp/some_job.sas ,outfile=/tmp/some_job.sas
) )
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
* password @li password
* authorization_code @liauthorization_code
* detect - will check if access_token exists, if not will use sas_services if @li detect - will check if access_token exists, if not will use sas_services
a SASStudioV session else authorization_code. Default option. if a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services @li sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path of the job @param [in] path= The SAS Drive path of the job
@param [in] name= The name of the job @param [in] name= The name of the job
@param [out] outref= A fileref to which to write the source code @param [in] mdebug=(0) set to 1 to enable DEBUG messages
@param [out] outfile= A file to which to write the source code @param [out] outref=(0) A fileref to which to write the source code (will be
created with a TEMP engine)
@param [out] outfile=(0) A file to which to write the source code
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -14555,7 +14654,15 @@ libname &libref1 clear;
,contextName=SAS Job Execution compute context ,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -14649,21 +14756,33 @@ data _null_;
run; run;
%inc "&fpath3..lua"; %inc "&fpath3..lua";
/* export to desired destination */ /* export to desired destination */
data _null_; %if "&outref"="0" %then %do;
%if &outref=0 %then %do; data _null_;
file "&outfile" lrecl=32767; file "&outfile" lrecl=32767;
%end; %end;
%else %do; %else %do;
filename &outref temp;
data _null_;
file &outref; file &outref;
%end; %end;
infile &fname2; infile &fname2;
input; input;
put _infile_; put _infile_;
&dbg. putlog _infile_;
run; run;
filename &fname1 clear;
filename &fname2 clear; %if &mdebug=1 %then %do;
filename &fname3 clear; %put &sysmacroname exit vars:;
%mend; %put _local_;
%end;
%else %do;
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
%end;
%mend mv_getjobcode;
/** /**
@file @file
@brief Extract the log from a completed SAS Viya Job @brief Extract the log from a completed SAS Viya Job
@@ -14752,6 +14871,13 @@ filename &fname3 clear;
,grant_type=sas_services ,grant_type=sas_services
,mdebug=0 ,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -14927,9 +15053,10 @@ run;
filename &fname3 clear; filename &fname3 clear;
%end; %end;
%else %do; %else %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend; %mend mv_getjoblog;
@@ -15004,7 +15131,9 @@ run;
@param [out] result= (WEBOUT_JSON) The result type to capture. Resolves @param [out] result= (WEBOUT_JSON) The result type to capture. Resolves
to "_[column name]" from the results table when parsed with the JSON libname to "_[column name]" from the results table when parsed with the JSON libname
engine. engine. Example values:
@li WEBOUT_JSON
@li WEBOUT_TXT
@param [out] outref= (0) The output fileref to which to write the results @param [out] outref= (0) The output fileref to which to write the results
@param [out] outlib= (0) The output library to which to assign the results @param [out] outlib= (0) The output library to which to assign the results
@@ -15031,6 +15160,13 @@ run;
,outref=0 ,outref=0
,outlib=0 ,outlib=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -15096,6 +15232,13 @@ run;
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
%end; %end;
%if &mdebug=1 %then %do;
data _null_;
infile &fname1 lrecl=32767;
input;
putlog _infile_;
run;
%end;
/* extract results link */ /* extract results link */
%local lib1 resuri; %local lib1 resuri;
@@ -15104,7 +15247,7 @@ libname &lib1 JSON fileref=&fname1;
data _null_; data _null_;
set &lib1..results; set &lib1..results;
call symputx('resuri',_&result,'l'); call symputx('resuri',_&result,'l');
putlog (_all_)(=); &dbg putlog "&sysmacroname results: " (_all_)(=);
run; run;
%mp_abort(iftrue=("&resuri"=".") %mp_abort(iftrue=("&resuri"=".")
,mac=&sysmacroname ,mac=&sysmacroname
@@ -15122,6 +15265,13 @@ proc http method='GET' out=&fname2 &oauth_bearer
%end; %end;
; ;
run; run;
%if &mdebug=1 %then %do;
data _null_;
infile &fname2 lrecl=32767;
input;
putlog _infile_;
run;
%end;
%if &outref ne 0 %then %do; %if &outref ne 0 %then %do;
filename &outref temp; filename &outref temp;
@@ -15137,9 +15287,11 @@ run;
libname &lib1 clear; libname &lib1 clear;
%end; %end;
%else %do; %else %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend;
%mend mv_getjobresult;
/** /**
@file @file
@brief Extract the status from a running SAS Viya job @brief Extract the status from a running SAS Viya job
@@ -15572,24 +15724,25 @@ libname &libref1 clear;
,paramstring=%str("macvarname":"macvarvalue","answer":42) ,paramstring=%str("macvarname":"macvarvalue","answer":42)
) )
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
@li password
* password @li authorization_code
* authorization_code @li detect - will check if access_token exists, if not will use sas_services
* detect - will check if access_token exists, if not will use sas_services if if a SASStudioV session else authorization_code. Default option.
a SASStudioV session else authorization_code. Default option. @li sas_services - will use oauth_bearer=sas_services
* sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path to the job being executed @param [in] path= The SAS Drive path to the job being executed
@param [in] name= The name of the job to execute @param [in] name= The name of the job to execute
@param [in] paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"` @param [in] paramstring= A JSON fragment with name:value pairs, eg:
or "name":"value","name2":42`. This will need to be wrapped in `%str()`. `"name":"value"` or "name":"value","name2":42`. This will need to be
wrapped in `%str()`.
@param [in] contextName= Context name with which to run the job. @param [in] contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context` Default = `SAS Job Execution compute context`
@param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing links (Default=work.mv_jobexecute) @param [out] outds= (work.mv_jobexecute) The output dataset containing links
@version VIYA V.03.04 @version VIYA V.03.04
@@ -15611,7 +15764,15 @@ libname &libref1 clear;
,grant_type=sas_services ,grant_type=sas_services
,paramstring=0 ,paramstring=0
,outds=work.mv_jobexecute ,outds=work.mv_jobexecute
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -15713,12 +15874,17 @@ data &outds;
_program="&path/&name"; _program="&path/&name";
run; run;
/* clear refs */ %if &mdebug=1 %then %do;
filename &fname0 clear; %put &sysmacroname exit vars:;
filename &fname1 clear; %put _local_;
libname &libref; %end;
%else %do;
%mend;/** /* clear refs */
filename &fname0 clear;
filename &fname1 clear;
libname &libref;
%end;
%mend mv_jobexecute;/**
@file @file
@brief Execute a series of job flows @brief Execute a series of job flows
@details Very (very) simple flow manager. Jobs execute in sequential waves, @details Very (very) simple flow manager. Jobs execute in sequential waves,
@@ -15856,6 +16022,13 @@ libname &libref;
,raise_err=0 ,raise_err=0
,mdebug=0 ,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -16013,6 +16186,7 @@ data;run;%let jdswaitfor=&syslast;
,name=&jobname ,name=&jobname
,paramstring=%superq(jparams&jid) ,paramstring=%superq(jparams&jid)
,outds=&jdsapp ,outds=&jdsapp
,mdebug=&mdebug
) )
data &jdsapp; data &jdsapp;
format jobparams $32767.; format jobparams $32767.;
@@ -16033,8 +16207,13 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &jid=&jcnt %then %do; %if &jid=&jcnt %then %do;
/* we are at the end of the loop - time to see which jobs have finished */ /* we are at the end of the loop - time to see which jobs have finished */
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref %mv_jobwaitfor(ANY
,raise_err=&raise_err) ,inds=&jdsrunning
,outds=&jdswaitfor
,outref=&outref
,raise_err=&raise_err
,mdebug=&mdebug
)
%local done; %local done;
%let done=%mf_nobs(&jdswaitfor); %let done=%mf_nobs(&jdswaitfor);
%if &done>0 %then %do; %if &done>0 %then %do;
@@ -16066,13 +16245,14 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &mdebug=1 %then %do; %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend; %mend mv_jobflow;
/** /**
@file @file
@brief Takes a dataset of running jobs and waits for ANY or ALL of them to complete @brief Takes a table of running jobs and waits for ANY/ALL of them to complete
@details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL @details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL
jobs are completed. Completion is determined by reference to the returned jobs are completed. Completion is determined by reference to the returned
_state_, as per the following table: _state_, as per the following table:
@@ -16127,13 +16307,14 @@ data;run;%let jdswaitfor=&syslast;
%mv_deletejes(path=/Public/temp,name=demo) %mv_deletejes(path=/Public/temp,name=demo)
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
- password - password
- authorization_code - authorization_code
- detect - will check if access_token exists, if not will use sas_services if - detect - will check if access_token exists, if not will use sas_services
a SASStudioV session else authorization_code. Default option. if a SASStudioV session else authorization_code. Default option.
- sas_services - will use oauth_bearer=sas_services - sas_services - will use oauth_bearer=sas_services
@param [in] action=Either ALL (to wait for every job) or ANY (if one job @param [in] action=Either ALL (to wait for every job) or ANY (if one job
@@ -16144,9 +16325,11 @@ data;run;%let jdswaitfor=&syslast;
should be in a `_program` variable. should be in a `_program` variable.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete @param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully succcessfully
@param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing the list of states by job @param [out] outds= The output dataset containing the list of states by job
(default=work.mv_jobexecute) (default=work.mv_jobexecute)
@param [out] outref= A fileref to which the spawned job logs should be appended. @param [out] outref= A fileref to which the spawned job logs should be
appended.
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -16169,7 +16352,15 @@ data;run;%let jdswaitfor=&syslast;
,outds=work.mv_jobwaitfor ,outds=work.mv_jobwaitfor
,outref=0 ,outref=0
,raise_err=0 ,raise_err=0
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -16227,7 +16418,8 @@ run;
%let fname0=%mf_getuniquefileref(); %let fname0=%mf_getuniquefileref();
data &outds; data &outds;
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.; format _program uri $128. state $32. stateDetails $32. timestamp datetime19.
jobparams $32767.;
stop; stop;
run; run;
@@ -16240,8 +16432,8 @@ run;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; ; %end; ;
run; run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
%do; %then %do;
data _null_;infile &fname0;input;putlog _infile_;run; data _null_;infile &fname0;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname %mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
@@ -16277,7 +16469,7 @@ run;
%let joburi&i=0; /* do not re-check */ %let joburi&i=0; /* do not re-check */
/* fetch log */ /* fetch log */
%if %str(&outref) ne 0 %then %do; %if %str(&outref) ne 0 %then %do;
%mv_getjoblog(uri=&plainuri,outref=&outref) %mv_getjoblog(uri=&plainuri,outref=&outref,mdebug=&mdebug)
%end; %end;
%end; %end;
%else %if &status=idle or &status=pending or &status=running %then %do; %else %if &status=idle or &status=pending or &status=running %then %do;
@@ -16292,10 +16484,11 @@ run;
%end; %end;
%if (&raise_err) %then %do; %if (&raise_err) %then %do;
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do; %if (&status = canceled or &status = failed or %length(&stateDetails)>0)
%then %do;
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4; %if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
%else %let SYSCC=5; %else %let SYSCC=5;
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails; %put %str(ERR)OR: Job &&jobname&i. did not complete. &stateDetails;
%return; %return;
%end; %end;
%end; %end;
@@ -16310,10 +16503,15 @@ run;
%end; %end;
%end; %end;
/* clear refs */ %if &mdebug=1 %then %do;
filename &fname0 clear; %put &sysmacroname exit vars:;
%put _local_;
%mend;/** %end;
%else %do;
/* clear refs */
filename &fname0 clear;
%end;
%mend mv_jobwaitfor;/**
@file mv_registerclient.sas @file mv_registerclient.sas
@brief Register Client and Secret (admin task) @brief Register Client and Secret (admin task)
@details When building apps on SAS Viya, an client id and secret is required. @details When building apps on SAS Viya, an client id and secret is required.

View File

@@ -22,6 +22,8 @@
|mustbevalidname|can be anything, oops, %abort!!| |mustbevalidname|can be anything, oops, %abort!!|
@param [in] debug= (log) Provide the _debug value @param [in] debug= (log) Provide the _debug value
@param [in] viyaresult=(WEBOUT_JSON) The Viya result type to return. For
more info, see mv_getjobresult.sas
@param [out] outlib= (0) Output libref to contain the final tables. Set to @param [out] outlib= (0) Output libref to contain the final tables. Set to
0 if the service output is not in JSON format. 0 if the service output is not in JSON format.
@param [out] outref= (0) Output fileref to create, to contain the full _webout @param [out] outref= (0) Output fileref to create, to contain the full _webout
@@ -46,8 +48,16 @@
inputparams=0, inputparams=0,
debug=log, debug=log,
outlib=0, outlib=0,
outref=0 outref=0,
viyaresult=WEBOUT_JSON
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local mdebug;
%if &debug ne 0 %then %do;
%let mdebug=1;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let mdebug=0;
/* sanitise inputparams */ /* sanitise inputparams */
%local pcnt; %local pcnt;
@@ -72,22 +82,6 @@
) )
%end; %end;
/* parse the input files */
%local webcount i var;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%end;
%end;
%else %let webcount=0;
%local fref1 webref; %local fref1 webref;
%let fref1=%mf_getuniquefileref(); %let fref1=%mf_getuniquefileref();
@@ -96,6 +90,23 @@
%local platform; %local platform;
%let platform=%mf_getplatform(); %let platform=%mf_getplatform();
%if &platform=SASMETA %then %do; %if &platform=SASMETA %then %do;
/* parse the input files */
%local webcount i var;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%end;
%end;
%else %let webcount=0;
proc stp program="&program"; proc stp program="&program";
inputparam _program="&program" inputparam _program="&program"
%do i=1 %to &webcount; %do i=1 %to &webcount;
@@ -152,14 +163,65 @@
%end; %end;
%else %if &platform=SASVIYA %then %do; %else %if &platform=SASVIYA %then %do;
data ;
_program="&program"; /* prepare inputparams */
%local ds1;
%let ds1=%mf_getuniquename();
%if "&inputparams" ne "0" %then %do;
proc transpose data=&inputparams out=&ds1;
id name;
var value;
run;
%end;
%else %do;
data &ds1;run;
%end;
/* parse the input files - convert to sasjs params */
%local webcount i var sasjs_tables;
%if %quote(&inputfiles) ne 0 %then %do;
%let webcount=%sysfunc(countw(&inputfiles));
%put &=webcount;
%do i=1 %to &webcount;
%let var=%scan(&inputfiles,&i,%str( ));
%local webfref&i webname&i sasjs&i.data;
%let webref&i=%scan(&var,1,%str(:));
%let webname&i=%scan(&var,2,%str(:));
%put webref&i=&&webref&i;
%put webname&i=&&webname&i;
%let sasjs_tables=&sasjs_tables &&webname&i;
data _null_;
infile &&webref&i lrecl=32767;
input;
if _n_=1 then call symputx("sasjs&i.data",_infile_);
else call symputx(
"sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_)
);
putlog "&sysmacroname infile: " _infile_;
run;
data &ds1;
set &ds1;
length sasjs&i.data $32767 sasjs_tables $1000;
sasjs&i.data=symget("sasjs&i.data");
sasjs_tables=symget("sasjs_tables");
run;
%end;
%end;
%else %let webcount=0;
data &ds1;
retain _program "&program";
set &ds1;
putlog "&sysmacroname inputparams:";
putlog (_all_)(=);
run; run;
%mv_jobflow(inds=&syslast %mv_jobflow(inds=&ds1
,maxconcurrency=1 ,maxconcurrency=1
,outds=work.results ,outds=work.results
,outref=&fref1 ,outref=&fref1
,mdebug=&mdebug
) )
/* show the log */ /* show the log */
data _null_; data _null_;
@@ -171,12 +233,14 @@
data _null_; data _null_;
set work.results; set work.results;
call symputx('uri',uri); call symputx('uri',uri);
putlog "&sysmacroname: fetching results for " uri;
run; run;
/* fetch results from webout.json */ /* fetch results from webout.json */
%mv_getjobresult(uri=&uri, %mv_getjobresult(uri=&uri,
result=WEBOUT_JSON, result=&viyaresult,
outref=&outref, outref=&outref,
outlib=&outlib outlib=&outlib,
mdebug=&mdebug
) )
%end; %end;
@@ -184,6 +248,12 @@
%put %str(ERR)OR: Unrecognised platform: &platform; %put %str(ERR)OR: Unrecognised platform: &platform;
%end; %end;
filename &webref clear; %if &mdebug=0 %then %do;
filename &webref clear;
%end;
%else %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%mend; %mend mp_testservice;

View File

@@ -16,24 +16,6 @@
"readMe": "../../README.md" "readMe": "../../README.md"
} }
}, },
"serviceConfig": {
"initProgram": "tests/testinit.sas",
"termProgram": "tests/testterm.sas",
"serviceFolders": [
"tests/base",
"tests/viya"
],
"macroVars": {
"mcTestAppLoc": "/Public/temp/macrocore"
}
},
"testConfig": {
"initProgram": "tests/testinit.sas",
"termProgram": "tests/testterm.sas",
"macroVars": {
"mcTestAppLoc": "/Public/temp/macrocore"
}
},
"defaultTarget": "viya", "defaultTarget": "viya",
"targets": [ "targets": [
{ {
@@ -44,7 +26,23 @@
"deployConfig": { "deployConfig": {
"deployServicePack": true "deployServicePack": true
}, },
"contextName": "SAS Job Execution compute context" "macroFolders": [
"base",
"meta",
"metax",
"viya",
"lua",
"tests/base",
"tests/viya"
],
"contextName": "SAS Job Execution compute context",
"testConfig": {
"initProgram": "tests/testinit.sas",
"termProgram": "tests/testterm.sas",
"macroVars": {
"mcTestAppLoc": "/Public/temp/macrocore"
}
}
} }
] ]
} }

View File

@@ -18,20 +18,20 @@ data _null_;
file testref; file testref;
put '01'x; put '01'x;
run; run;
%put TEST1: creating web service;
%mv_createwebservice( %mv_createwebservice(
path=&mcTestAppLoc/temp/macros, path=&mcTestAppLoc/temp/macros,
code=testref, name=mv_createwebservice,
name=mv_createwebservice code=testref
) )
%put TEST1: fetching web service code;
filename compare temp;
%mv_getjobcode( %mv_getjobcode(
path=&mcTestAppLoc/temp/macros path=&mcTestAppLoc/temp/macros,
,name=mv_createwebservice name=mv_createwebservice,
,outref=compare; outref=compare
) )
%put TEST1: checking web service code;
data test_results; data work.test_results;
length test_description $256 test_result $4 test_comments $256; length test_description $256 test_result $4 test_comments $256;
infile compare end=eof; infile compare end=eof;
input; input;

View File

@@ -0,0 +1,49 @@
/**
@file
@brief Testing mv_getjobcode macro
<h4> SAS Macros </h4>
@li mp_assert.sas
@li mv_createjob.sas
@li mv_getjobcode.sas
**/
/**
* Test Case 1
*/
/* write some code to a job */
%let incode=%str(data test; set sashelp.class;run;);
filename testref temp;
data _null_;
file testref;
put "&incode";
run;
%mv_createjob(
code=testref,
path=&mcTestAppLoc/services/temp,
name=some_job
)
/* now get the code back */
%mv_getjobcode(
path=&mcTestAppLoc/services/temp,
name=some_job,
outref=mycode
)
%let diditexist=NO;
data work.test1;
infile mycode;
input;
putlog _infile_;
line=_infile_;
check=symget('incode');
if _infile_=symget('incode') then call symputx('diditexist','YES');
run;
%mp_assert(
iftrue=(&diditexist=NO),
desc=Check if the code that was sent was successfully retrieved
)

View File

@@ -39,23 +39,26 @@
@li mf_isblank.sas @li mf_isblank.sas
@li mv_deletejes.sas @li mv_deletejes.sas
@param path= The full path (on SAS Drive) where the service will be created @param [in] path= The full path (on SAS Drive) where the service will be
@param name= The name of the service created
@param desc= The description of the service @param [in] name= The name of the service
@param precode= Space separated list of filerefs, pointing to the code that @param [in] desc= The description of the service
needs to be attached to the beginning of the service @param [in] precode= Space separated list of filerefs, pointing to the code
@param code= Fileref(s) of the actual code to be added that needs to be attached to the beginning of the service
@param access_token_var= The global macro variable to contain the access token @param [in] code= Fileref(s) of the actual code to be added
@param grant_type= valid values are "password" or "authorization_code" @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values are "password" or "authorization_code"
(unquoted). The default is authorization_code. (unquoted). The default is authorization_code.
@param replace= select NO to avoid replacing any existing service in that @param [in] replace=(YES) Select NO to avoid replacing any existing service in
location that location
@param adapter= the macro uses the sasjs adapter by default. To use another @param [in] adapter= the macro uses the sasjs adapter by default. To use
adapter, add a (different) fileref here. another adapter, add a (different) fileref here.
@param contextname= Choose a specific context on which to run the Job. Leave @param [in] contextname= Choose a specific context on which to run the Job. Leave
blank to use the default context. From Viya 3.5 it is possible to configure blank to use the default context. From Viya 3.5 it is possible to configure
a shared context - see a shared context - see
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -71,9 +74,17 @@ https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5p
,grant_type=sas_services ,grant_type=sas_services
,replace=YES ,replace=YES
,adapter=sasjs ,adapter=sasjs
,debug=0 ,mdebug=0
,contextname= ,contextname=
,debug=0 /* @TODO - Deprecate */
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -126,7 +137,7 @@ proc http method='GET' out=&fname1 &oauth_bearer
headers "Authorization"="Bearer &&&access_token_var"; headers "Authorization"="Bearer &&&access_token_var";
%end; %end;
run; run;
%if &debug %then %do; %if &mdebug=1 %then %do;
data _null_; data _null_;
infile &fname1; infile &fname1;
input; input;
@@ -165,7 +176,7 @@ proc http method='GET'
%end; %end;
'Accept'='application/vnd.sas.collection+json' 'Accept'='application/vnd.sas.collection+json'
'Accept-Language'='string'; 'Accept-Language'='string';
%if &debug=1 %then %do; %if &mdebug=1 %then %do;
debug level = 3; debug level = 3;
%end; %end;
run; run;
@@ -220,9 +231,9 @@ run;
* These put statements are auto generated - to change the macro, change the * These put statements are auto generated - to change the macro, change the
* source (mv_webout) and run `build.py` * source (mv_webout) and run `build.py`
*/ */
filename sasjs temp lrecl=3000; filename &adapter temp lrecl=3000;
data _null_; data _null_;
file sasjs; file &adapter;
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */"; put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
/* WEBOUT BEGIN */ /* WEBOUT BEGIN */
put ' '; put ' ';
@@ -561,11 +572,12 @@ data _null_;
run; run;
/* insert the code, escaping double quotes and carriage returns */ /* insert the code, escaping double quotes and carriage returns */
%&dbg.put &sysmacroname: Creating final input file;
%local x fref freflist; %local x fref freflist;
%let freflist= &adapter &precode &code ; %let freflist= &adapter &precode &code ;
%do x=1 %to %sysfunc(countw(&freflist)); %do x=1 %to %sysfunc(countw(&freflist));
%let fref=%scan(&freflist,&x); %let fref=%scan(&freflist,&x);
%put &sysmacroname: adding &fref; %&dbg.put &sysmacroname: adding &fref fileref;
data _null_; data _null_;
length filein 8 fileid 8; length filein 8 fileid 8;
filein = fopen("&fref","I",1,"B"); filein = fopen("&fref","I",1,"B");
@@ -617,7 +629,12 @@ data _null_;
put '"}'; put '"}';
run; run;
/* now we can create the job!! */ %if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
%put &sysmacroname: input about to be POSTed;
data _null_;infile &fname3;input;putlog _infile_;run;
%end;
%&dbg.put &sysmacroname: Creating the actual service!;
%local fname4; %local fname4;
%let fname4=%mf_getuniquefileref(); %let fname4=%mf_getuniquefileref();
proc http method='POST' proc http method='POST'
@@ -630,22 +647,18 @@ proc http method='POST'
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
"Accept"="application/vnd.sas.job.definition+json"; "Accept"="application/vnd.sas.job.definition+json";
%if &debug=1 %then %do; %if &mdebug=1 %then %do;
debug level = 3; debug level = 3;
%end; %end;
run; run;
/*data _null_;infile &fname4;input;putlog _infile_;run;*/ %if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
%put &sysmacroname: output from POSTing job definition;
data _null_;infile &fname4;input;putlog _infile_;run;
%end;
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201) %mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
filename &fname4 clear;
filename &adapter clear;
libname &libref1 clear;
/* get the url so we can give a helpful log message */ /* get the url so we can give a helpful log message */
%local url; %local url;
@@ -660,6 +673,19 @@ data _null_;
call symputx('url',url); call symputx('url',url);
run; run;
%if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
filename &fname4 clear;
filename &adapter clear;
libname &libref1 clear;
%end;
%put &sysmacroname: Job &name successfully created in &path; %put &sysmacroname: Job &name successfully created in &path;
%put &sysmacroname:; %put &sysmacroname:;
@@ -669,4 +695,4 @@ run;
%put &sysmacroname:; %put &sysmacroname:;
%put &sysmacroname:; %put &sysmacroname:;
%mend; %mend mv_createwebservice;

View File

@@ -10,17 +10,20 @@
,outfile=/tmp/some_job.sas ,outfile=/tmp/some_job.sas
) )
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
* password @li password
* authorization_code @liauthorization_code
* detect - will check if access_token exists, if not will use sas_services if @li detect - will check if access_token exists, if not will use sas_services
a SASStudioV session else authorization_code. Default option. if a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services @li sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path of the job @param [in] path= The SAS Drive path of the job
@param [in] name= The name of the job @param [in] name= The name of the job
@param [out] outref= A fileref to which to write the source code @param [in] mdebug=(0) set to 1 to enable DEBUG messages
@param [out] outfile= A file to which to write the source code @param [out] outref=(0) A fileref to which to write the source code (will be
created with a TEMP engine)
@param [out] outfile=(0) A file to which to write the source code
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -39,7 +42,15 @@
,contextName=SAS Job Execution compute context ,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -133,18 +144,30 @@ data _null_;
run; run;
%inc "&fpath3..lua"; %inc "&fpath3..lua";
/* export to desired destination */ /* export to desired destination */
data _null_; %if "&outref"="0" %then %do;
%if &outref=0 %then %do; data _null_;
file "&outfile" lrecl=32767; file "&outfile" lrecl=32767;
%end; %end;
%else %do; %else %do;
filename &outref temp;
data _null_;
file &outref; file &outref;
%end; %end;
infile &fname2; infile &fname2;
input; input;
put _infile_; put _infile_;
&dbg. putlog _infile_;
run; run;
filename &fname1 clear;
filename &fname2 clear; %if &mdebug=1 %then %do;
filename &fname3 clear; %put &sysmacroname exit vars:;
%mend; %put _local_;
%end;
%else %do;
/* clear refs */
filename &fname1 clear;
filename &fname2 clear;
filename &fname3 clear;
%end;
%mend mv_getjobcode;

View File

@@ -86,6 +86,13 @@
,grant_type=sas_services ,grant_type=sas_services
,mdebug=0 ,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -261,9 +268,10 @@ run;
filename &fname3 clear; filename &fname3 clear;
%end; %end;
%else %do; %else %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend; %mend mv_getjoblog;

View File

@@ -69,7 +69,9 @@
@param [out] result= (WEBOUT_JSON) The result type to capture. Resolves @param [out] result= (WEBOUT_JSON) The result type to capture. Resolves
to "_[column name]" from the results table when parsed with the JSON libname to "_[column name]" from the results table when parsed with the JSON libname
engine. engine. Example values:
@li WEBOUT_JSON
@li WEBOUT_TXT
@param [out] outref= (0) The output fileref to which to write the results @param [out] outref= (0) The output fileref to which to write the results
@param [out] outlib= (0) The output library to which to assign the results @param [out] outlib= (0) The output library to which to assign the results
@@ -96,6 +98,13 @@
,outref=0 ,outref=0
,outlib=0 ,outlib=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -161,6 +170,13 @@ run;
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
%end; %end;
%if &mdebug=1 %then %do;
data _null_;
infile &fname1 lrecl=32767;
input;
putlog _infile_;
run;
%end;
/* extract results link */ /* extract results link */
%local lib1 resuri; %local lib1 resuri;
@@ -169,7 +185,7 @@ libname &lib1 JSON fileref=&fname1;
data _null_; data _null_;
set &lib1..results; set &lib1..results;
call symputx('resuri',_&result,'l'); call symputx('resuri',_&result,'l');
putlog (_all_)(=); &dbg putlog "&sysmacroname results: " (_all_)(=);
run; run;
%mp_abort(iftrue=("&resuri"=".") %mp_abort(iftrue=("&resuri"=".")
,mac=&sysmacroname ,mac=&sysmacroname
@@ -187,6 +203,13 @@ proc http method='GET' out=&fname2 &oauth_bearer
%end; %end;
; ;
run; run;
%if &mdebug=1 %then %do;
data _null_;
infile &fname2 lrecl=32767;
input;
putlog _infile_;
run;
%end;
%if &outref ne 0 %then %do; %if &outref ne 0 %then %do;
filename &outref temp; filename &outref temp;
@@ -202,6 +225,8 @@ run;
libname &lib1 clear; libname &lib1 clear;
%end; %end;
%else %do; %else %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend;
%mend mv_getjobresult;

View File

@@ -23,24 +23,25 @@
,paramstring=%str("macvarname":"macvarvalue","answer":42) ,paramstring=%str("macvarname":"macvarvalue","answer":42)
) )
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
@li password
* password @li authorization_code
* authorization_code @li detect - will check if access_token exists, if not will use sas_services
* detect - will check if access_token exists, if not will use sas_services if if a SASStudioV session else authorization_code. Default option.
a SASStudioV session else authorization_code. Default option. @li sas_services - will use oauth_bearer=sas_services
* sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path to the job being executed @param [in] path= The SAS Drive path to the job being executed
@param [in] name= The name of the job to execute @param [in] name= The name of the job to execute
@param [in] paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"` @param [in] paramstring= A JSON fragment with name:value pairs, eg:
or "name":"value","name2":42`. This will need to be wrapped in `%str()`. `"name":"value"` or "name":"value","name2":42`. This will need to be
wrapped in `%str()`.
@param [in] contextName= Context name with which to run the job. @param [in] contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context` Default = `SAS Job Execution compute context`
@param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing links (Default=work.mv_jobexecute) @param [out] outds= (work.mv_jobexecute) The output dataset containing links
@version VIYA V.03.04 @version VIYA V.03.04
@@ -62,7 +63,15 @@
,grant_type=sas_services ,grant_type=sas_services
,paramstring=0 ,paramstring=0
,outds=work.mv_jobexecute ,outds=work.mv_jobexecute
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -164,9 +173,14 @@ data &outds;
_program="&path/&name"; _program="&path/&name";
run; run;
/* clear refs */ %if &mdebug=1 %then %do;
filename &fname0 clear; %put &sysmacroname exit vars:;
filename &fname1 clear; %put _local_;
libname &libref; %end;
%else %do;
%mend; /* clear refs */
filename &fname0 clear;
filename &fname1 clear;
libname &libref;
%end;
%mend mv_jobexecute;

View File

@@ -136,6 +136,13 @@
,raise_err=0 ,raise_err=0
,mdebug=0 ,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -293,6 +300,7 @@ data;run;%let jdswaitfor=&syslast;
,name=&jobname ,name=&jobname
,paramstring=%superq(jparams&jid) ,paramstring=%superq(jparams&jid)
,outds=&jdsapp ,outds=&jdsapp
,mdebug=&mdebug
) )
data &jdsapp; data &jdsapp;
format jobparams $32767.; format jobparams $32767.;
@@ -313,8 +321,13 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &jid=&jcnt %then %do; %if &jid=&jcnt %then %do;
/* we are at the end of the loop - time to see which jobs have finished */ /* we are at the end of the loop - time to see which jobs have finished */
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref %mv_jobwaitfor(ANY
,raise_err=&raise_err) ,inds=&jdsrunning
,outds=&jdswaitfor
,outref=&outref
,raise_err=&raise_err
,mdebug=&mdebug
)
%local done; %local done;
%let done=%mf_nobs(&jdswaitfor); %let done=%mf_nobs(&jdswaitfor);
%if &done>0 %then %do; %if &done>0 %then %do;
@@ -346,7 +359,8 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &mdebug=1 %then %do; %if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_; %put _local_;
%end; %end;
%mend; %mend mv_jobflow;

View File

@@ -1,6 +1,6 @@
/** /**
@file @file
@brief Takes a dataset of running jobs and waits for ANY or ALL of them to complete @brief Takes a table of running jobs and waits for ANY/ALL of them to complete
@details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL @details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL
jobs are completed. Completion is determined by reference to the returned jobs are completed. Completion is determined by reference to the returned
_state_, as per the following table: _state_, as per the following table:
@@ -55,13 +55,14 @@
%mv_deletejes(path=/Public/temp,name=demo) %mv_deletejes(path=/Public/temp,name=demo)
@param [in] access_token_var= The global macro variable to contain the access token @param [in] access_token_var= The global macro variable to contain the access
token
@param [in] grant_type= valid values: @param [in] grant_type= valid values:
- password - password
- authorization_code - authorization_code
- detect - will check if access_token exists, if not will use sas_services if - detect - will check if access_token exists, if not will use sas_services
a SASStudioV session else authorization_code. Default option. if a SASStudioV session else authorization_code. Default option.
- sas_services - will use oauth_bearer=sas_services - sas_services - will use oauth_bearer=sas_services
@param [in] action=Either ALL (to wait for every job) or ANY (if one job @param [in] action=Either ALL (to wait for every job) or ANY (if one job
@@ -72,9 +73,11 @@
should be in a `_program` variable. should be in a `_program` variable.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete @param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully succcessfully
@param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing the list of states by job @param [out] outds= The output dataset containing the list of states by job
(default=work.mv_jobexecute) (default=work.mv_jobexecute)
@param [out] outref= A fileref to which the spawned job logs should be appended. @param [out] outref= A fileref to which the spawned job logs should be
appended.
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -97,7 +100,15 @@
,outds=work.mv_jobwaitfor ,outds=work.mv_jobwaitfor
,outref=0 ,outref=0
,raise_err=0 ,raise_err=0
,mdebug=0
); );
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code; %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
@@ -155,7 +166,8 @@ run;
%let fname0=%mf_getuniquefileref(); %let fname0=%mf_getuniquefileref();
data &outds; data &outds;
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.; format _program uri $128. state $32. stateDetails $32. timestamp datetime19.
jobparams $32767.;
stop; stop;
run; run;
@@ -168,8 +180,8 @@ run;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; ; %end; ;
run; run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
%do; %then %do;
data _null_;infile &fname0;input;putlog _infile_;run; data _null_;infile &fname0;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname %mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
@@ -205,7 +217,7 @@ run;
%let joburi&i=0; /* do not re-check */ %let joburi&i=0; /* do not re-check */
/* fetch log */ /* fetch log */
%if %str(&outref) ne 0 %then %do; %if %str(&outref) ne 0 %then %do;
%mv_getjoblog(uri=&plainuri,outref=&outref) %mv_getjoblog(uri=&plainuri,outref=&outref,mdebug=&mdebug)
%end; %end;
%end; %end;
%else %if &status=idle or &status=pending or &status=running %then %do; %else %if &status=idle or &status=pending or &status=running %then %do;
@@ -220,10 +232,11 @@ run;
%end; %end;
%if (&raise_err) %then %do; %if (&raise_err) %then %do;
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do; %if (&status = canceled or &status = failed or %length(&stateDetails)>0)
%then %do;
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4; %if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
%else %let SYSCC=5; %else %let SYSCC=5;
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails; %put %str(ERR)OR: Job &&jobname&i. did not complete. &stateDetails;
%return; %return;
%end; %end;
%end; %end;
@@ -238,7 +251,12 @@ run;
%end; %end;
%end; %end;
/* clear refs */ %if &mdebug=1 %then %do;
filename &fname0 clear; %put &sysmacroname exit vars:;
%put _local_;
%mend; %end;
%else %do;
/* clear refs */
filename &fname0 clear;
%end;
%mend mv_jobwaitfor;