Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
mv_getjobstate.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief Extract the status from a running SAS Viya job
4  @details Extracts the status from a running job and appends it to an output
5  dataset with the following structure:
6 
7  | uri | state | timestamp |
8  |---------------------------------------------------------------|---------|--------------------|
9  | /jobExecution/jobs/5cebd840-2063-42c1-be0c-421ec3e1c175/state | running | 15JAN2021:12:35:08 |
10 
11  To query the running job, you need the URI. Sample code for achieving this
12  is provided below.
13 
14  ## Example
15 
16  First, compile the macros:
17 
18  filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
19  %inc mc;
20 
21  Next, create a long running job (in this case, a web service):
22 
23  filename ft15f001 temp;
24  parmcards4;
25  data ;
26  rand=ranuni(0)*1000;
27  do x=1 to rand;
28  y=rand*4;
29  output;
30  end;
31  run;
32  data _null_;
33  call sleep(5,1);
34  run;
35  ;;;;
36  %mv_createwebservice(path=/Public/temp,name=demo)
37 
38  Execute it, grab the uri, and finally, check the job status:
39 
40  %mv_jobexecute(path=/Public/temp
41  ,name=demo
42  ,outds=work.info
43  )
44 
45  data _null_;
46  set work.info;
47  if method='GET' and rel='state';
48  call symputx('uri',uri);
49  run;
50 
51  %mv_getjobstate(uri=&uri,outds=results)
52 
53  You can run this macro as part of a loop to await the final 'completed' status.
54  The full list of status values is:
55 
56  @li idle
57  @li pending
58  @li running
59  @li canceled
60  @li completed
61  @li failed
62 
63  If you have one or more jobs that you'd like to wait for completion you can
64  also use the [mv_jobwaitfor](/mv__jobwaitfor_8sas.html) macro.
65 
66  @param [in] access_token_var= The global macro variable to contain the access token
67  @param [in] grant_type= valid values:
68  @li password
69  @li authorization_code
70  @li detect - will check if access_token exists, if not will use sas_services if
71  a SASStudioV session else authorization_code. Default option.
72  @li sas_services - will use oauth_bearer=sas_services.
73  @param [in] uri= The uri of the running job for which to fetch the status,
74  in the format `/jobExecution/jobs/$UUID/state` (unquoted).
75  @param [out] outds= The output dataset in which to APPEND the status. Three
76  fields are appended: `CHECK_TM`, `URI` and `STATE`. If the dataset does not
77  exist, it is created.
78 
79 
80  @version VIYA V.03.04
81  @author Allan Bowe, source: https://github.com/sasjs/core
82 
83  <h4> SAS Macros </h4>
84  @li mp_abort.sas
85  @li mf_getplatform.sas
86  @li mf_getuniquefileref.sas
87 
88 **/
89 
90 %macro mv_getjobstate(uri=0,outds=work.mv_getjobstate
91  ,contextName=SAS Job Execution compute context
92  ,access_token_var=ACCESS_TOKEN
93  ,grant_type=sas_services
94  );
95 %local oauth_bearer;
96 %if &grant_type=detect %then %do;
97  %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
98  %else %let grant_type=sas_services;
99 %end;
100 %if &grant_type=sas_services %then %do;
101  %let oauth_bearer=oauth_bearer=sas_services;
102  %let &access_token_var=;
103 %end;
104 
105 %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
106  and &grant_type ne sas_services
107  )
108  ,mac=&sysmacroname
109  ,msg=%str(Invalid value for grant_type: &grant_type)
110 )
111 
112 /* validation in datastep for better character safety */
113 %local errmsg errflg;
114 data _null_;
115  uri=symget('uri');
116  if length(uri)<12 then do;
117  call symputx('errflg',1);
118  call symputx('errmsg',"URI is invalid (too short) - '&uri'",'l');
119  end;
120  if scan(uri,-1) ne 'state' or scan(uri,1) ne 'jobExecution' then do;
121 
122  call symputx('errflg',1);
123  call symputx('errmsg',
124  "URI should be in format /jobExecution/jobs/$$$$UUID$$$$/state"
125  !!" but is actually like: &uri",'l');
126  end;
127 run;
128 
129 %mp_abort(iftrue=(&errflg=1)
130  ,mac=&sysmacroname
131  ,msg=%str(&errmsg)
132 )
133 
134 options noquotelenmax;
135 %local base_uri; /* location of rest apis */
136 %let base_uri=%mf_getplatform(VIYARESTAPI);
137 
138 %local fname0;
139 %let fname0=%mf_getuniquefileref();
140 
141 proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&uri";
142  headers "Accept"="text/plain"
143  %if &grant_type=authorization_code %then %do;
144  "Authorization"="Bearer &&&access_token_var"
145  %end; ;
146 run;
147 %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
148 %do;
149  data _null_;infile &fname0;input;putlog _infile_;run;
150  %mp_abort(mac=&sysmacroname
151  ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
152  )
153 %end;
154 
155 data;
156  format uri $128. state $32. timestamp datetime19.;
157  infile &fname0;
158  uri="&uri";
159  timestamp=datetime();
160  input;
161  state=_infile_;
162 run;
163 
164 proc append base=&outds data=&syslast;
165 run;
166 
167 filename &fname0 clear;
168 
169 %mend;