Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mv_getjobcode.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Extract the source code from a SAS Viya Job
4 @details Extracts the SAS code from a Job into a fileref or physical file.
5 Example:
6
7 %mv_getjobcode(
8 path=/Public/jobs
9 ,name=some_job
10 ,outfile=/tmp/some_job.sas
11 )
12
13 @param [in] access_token_var= The global macro variable to contain the access
14 token
15 @param [in] grant_type= valid values:
16 @li password
17 @liauthorization_code
18 @li detect - will check if access_token exists, if not will use sas_services
19 if a SASStudioV session else authorization_code. Default option.
20 @li sas_services - will use oauth_bearer=sas_services
21 @param [in] path= The SAS Drive path of the job
22 @param [in] name= The name of the job
23 @param [in] mdebug=(0) set to 1 to enable DEBUG messages
24 @param [out] outref=(0) A fileref to which to write the source code (will be
25 created with a TEMP engine)
26 @param [out] outfile=(0) A file to which to write the source code
27
28 @version VIYA V.03.04
29 @author Allan Bowe, source: https://github.com/sasjs/core
30
31 <h4> SAS Macros </h4>
32 @li mp_abort.sas
33 @li mf_getplatform.sas
34 @li mf_getuniquefileref.sas
35 @li mv_getfoldermembers.sas
36
37**/
38
39%macro mv_getjobcode(outref=0,outfile=0
40 ,name=0,path=0
41 ,contextName=SAS Job Execution compute context
42 ,access_token_var=ACCESS_TOKEN
43 ,grant_type=sas_services
44 ,mdebug=0
45 );
46%local dbg bufsize varcnt fname1 fname2 errmsg;
47%if &mdebug=1 %then %do;
48 %put &sysmacroname local entry vars:;
49 %put _local_;
50%end;
51%else %let dbg=*;
52
53%local oauth_bearer;
54%if &grant_type=detect %then %do;
55 %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
56 %else %let grant_type=sas_services;
57%end;
58%if &grant_type=sas_services %then %do;
59 %let oauth_bearer=oauth_bearer=sas_services;
60 %let &access_token_var=;
61%end;
62%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
63 and &grant_type ne sas_services
64 )
65 ,mac=&sysmacroname
66 ,msg=%str(Invalid value for grant_type: &grant_type)
67)
68%mp_abort(iftrue=("&path"="0")
69 ,mac=&sysmacroname
70 ,msg=%str(Job Path not provided)
71)
72%mp_abort(iftrue=("&name"="0")
73 ,mac=&sysmacroname
74 ,msg=%str(Job Name not provided)
75)
76%mp_abort(iftrue=("&outfile"="0" and "&outref"="0")
77 ,mac=&sysmacroname
78 ,msg=%str(Output destination (file or fileref) must be provided)
79)
80options noquotelenmax;
81%local base_uri; /* location of rest apis */
82%let base_uri=%mf_getplatform(VIYARESTAPI);
83data;run;
84%local foldermembers;
85%let foldermembers=&syslast;
86%mv_getfoldermembers(root=&path
87 ,access_token_var=&access_token_var
88 ,grant_type=&grant_type
89 ,outds=&foldermembers
90)
91%local joburi;
92%let joburi=0;
93data _null_;
94 length name uri $512;
95 call missing(name,uri);
96 set &foldermembers;
97 if name="&name" and uri=:'/jobDefinitions/definitions'
98 then call symputx('joburi',uri);
99run;
100%mp_abort(iftrue=("&joburi"="0")
101 ,mac=&sysmacroname
102 ,msg=%str(Job &path/&name not found)
103)
104
105/* prepare request*/
106%let fname1=%mf_getuniquefileref();
107proc http method='GET' out=&fname1 &oauth_bearer
108 url="&base_uri&joburi";
109 headers "Accept"="application/vnd.sas.job.definition+json"
110 %if &grant_type=authorization_code %then %do;
111 "Authorization"="Bearer &&&access_token_var"
112 %end;
113 ;
114run;
115
116%if &mdebug=1 %then %do;
117 data _null_;
118 infile &fname1;
119 input;
120 putlog _infile_;
121 run;
122%end;
123
124%mp_abort(
125 iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
126 ,mac=&sysmacroname
127 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
128)
129
130%let fname2=%mf_getuniquefileref();
131filename &fname2 temp ;
132
133/* cannot use lua IO package as not available in Viya 4 */
134/* so use data step to read the JSON until the string `"code":"` is found */
135data _null_;
136 file &fname2 recfm=n;
137 infile &fname1 lrecl=1 recfm=n;
138 input sourcechar $char1. @@;
139 format sourcechar hex2.;
140 retain startwrite 0;
141 if startwrite=0 and sourcechar='"' then do;
142 reentry:
143 input sourcechar $ 1. @@;
144 if sourcechar='c' then do;
145 reentry2:
146 input sourcechar $ 1. @@;
147 if sourcechar='o' then do;
148 input sourcechar $ 1. @@;
149 if sourcechar='d' then do;
150 input sourcechar $ 1. @@;
151 if sourcechar='e' then do;
152 input sourcechar $ 1. @@;
153 if sourcechar='"' then do;
154 input sourcechar $ 1. @@;
155 if sourcechar=':' then do;
156 input sourcechar $ 1. @@;
157 if sourcechar='"' then do;
158 putlog 'code found';
159 startwrite=1;
160 input sourcechar $ 1. @@;
161 end;
162 end;
163 else if sourcechar='c' then goto reentry2;
164 end;
165 end;
166 else if sourcechar='"' then goto reentry;
167 end;
168 else if sourcechar='"' then goto reentry;
169 end;
170 else if sourcechar='"' then goto reentry;
171 end;
172 else if sourcechar='"' then goto reentry;
173 end;
174 /* once the `"code":"` string is found, write until unescaped `"` is found */
175 if startwrite=1 then do;
176 if sourcechar='\' then do;
177 input sourcechar $ 1. @@;
178 if sourcechar in ('"','\') then put sourcechar char1.;
179 else if sourcechar='n' then put '0A'x;
180 else if sourcechar='r' then put '0D'x;
181 else if sourcechar='t' then put '09'x;
182 else if sourcechar='u' then do;
183 length uni $4;
184 input uni $ 4. @@;
185 sourcechar=unicode('\u'!!uni);
186 put sourcechar char1.;
187 end;
188 else do;
189 call symputx('errmsg',"Uncaught escape char: "!!sourcechar,'l');
190 call symputx('syscc',99);
191 stop;
192 end;
193 end;
194 else if sourcechar='"' then stop;
195 else put sourcechar char1.;
196 end;
197run;
198
199%mp_abort(iftrue=("&syscc"="99")
200 ,mac=mv_getjobcode
201 ,msg=%str(&errmsg)
202)
203
204/* export to desired destination */
205%if "&outref"="0" %then %do;
206 data _null_;
207 file "&outfile" lrecl=32767;
208%end;
209%else %do;
210 filename &outref temp;
211 data _null_;
212 file &outref;
213%end;
214 infile &fname2;
215 input;
216 put _infile_;
217 &dbg. putlog _infile_;
218run;
219
220%if &mdebug=1 %then %do;
221 %put &sysmacroname exit vars:;
222 %put _local_;
223%end;
224%else %do;
225 /* clear refs */
226 filename &fname1 clear;
227 filename &fname2 clear;
228%end;
229
230%mend mv_getjobcode;