Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
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 token
14  @param [in] grant_type= valid values:
15  * password
16  * authorization_code
17  * detect - will check if access_token exists, if not will use sas_services if
18  a SASStudioV session else authorization_code. Default option.
19  * sas_services - will use oauth_bearer=sas_services
20  @param [in] path= The SAS Drive path of the job
21  @param [in] name= The name of the job
22  @param [out] outref= A fileref to which to write the source code
23  @param [out] outfile= A file to which to write the source code
24 
25  @version VIYA V.03.04
26  @author Allan Bowe, source: https://github.com/sasjs/core
27 
28  <h4> SAS Macros </h4>
29  @li mp_abort.sas
30  @li mf_getplatform.sas
31  @li mf_getuniquefileref.sas
32  @li mv_getfoldermembers.sas
33  @li ml_json.sas
34 
35 **/
36 
37 %macro mv_getjobcode(outref=0,outfile=0
38  ,name=0,path=0
39  ,contextName=SAS Job Execution compute context
40  ,access_token_var=ACCESS_TOKEN
41  ,grant_type=sas_services
42  );
43 %local oauth_bearer;
44 %if &grant_type=detect %then %do;
45  %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
46  %else %let grant_type=sas_services;
47 %end;
48 %if &grant_type=sas_services %then %do;
49  %let oauth_bearer=oauth_bearer=sas_services;
50  %let &access_token_var=;
51 %end;
52 %put &sysmacroname: grant_type=&grant_type;
53 %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
54  and &grant_type ne sas_services
55  )
56  ,mac=&sysmacroname
57  ,msg=%str(Invalid value for grant_type: &grant_type)
58 )
59 %mp_abort(iftrue=("&path"="0")
60  ,mac=&sysmacroname
61  ,msg=%str(Job Path not provided)
62 )
63 %mp_abort(iftrue=("&name"="0")
64  ,mac=&sysmacroname
65  ,msg=%str(Job Name not provided)
66 )
67 %mp_abort(iftrue=("&outfile"="0" and "&outref"="0")
68  ,mac=&sysmacroname
69  ,msg=%str(Output destination (file or fileref) must be provided)
70 )
71 options noquotelenmax;
72 %local base_uri; /* location of rest apis */
73 %let base_uri=%mf_getplatform(VIYARESTAPI);
74 data;run;
75 %local foldermembers;
76 %let foldermembers=&syslast;
77 %mv_getfoldermembers(root=&path
78  ,access_token_var=&access_token_var
79  ,grant_type=&grant_type
80  ,outds=&foldermembers
81 )
82 %local joburi;
83 %let joburi=0;
84 data _null_;
85  set &foldermembers;
86  if name="&name" and uri=:'/jobDefinitions/definitions'
87  then call symputx('joburi',uri);
88 run;
89 %mp_abort(iftrue=("&joburi"="0")
90  ,mac=&sysmacroname
91  ,msg=%str(Job &path/&name not found)
92 )
93 
94 /* prepare request*/
95 %local fname1;
96 %let fname1=%mf_getuniquefileref();
97 proc http method='GET' out=&fname1 &oauth_bearer
98  url="&base_uri&joburi";
99  headers "Accept"="application/vnd.sas.job.definition+json"
100  %if &grant_type=authorization_code %then %do;
101  "Authorization"="Bearer &&&access_token_var"
102  %end;
103  ;
104 run;
105 %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
106 %do;
107  data _null_;infile &fname1;input;putlog _infile_;run;
108  %mp_abort(mac=&sysmacroname
109  ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
110  )
111 %end;
112 %local fname2 fname3 fpath1 fpath2 fpath3;
113 %let fname2=%mf_getuniquefileref();
114 %let fname3=%mf_getuniquefileref();
115 %let fpath1=%sysfunc(pathname(&fname1));
116 %let fpath2=%sysfunc(pathname(&fname2));
117 %let fpath3=%sysfunc(pathname(&fname2));
118 
119 /* compile the lua JSON module */
120 %ml_json()
121 /* read using LUA - this allows the code to be of any length */
122 data _null_;
123  file "&fpath3..lua";
124  put '
125  infile = io.open (sas.symget("fpath1"), "r")
126  outfile = io.open (sas.symget("fpath2"), "w")
127  io.input(infile)
128  local resp=json.decode(io.read())
129  local job=resp["code"]
130  outfile:write(job)
131  io.close(infile)
132  io.close(outfile)
133  ';
134 run;
135 %inc "&fpath3..lua";
136 /* export to desired destination */
137 data _null_;
138  %if &outref=0 %then %do;
139  file "&outfile" lrecl=32767;
140  %end;
141  %else %do;
142  file &outref;
143  %end;
144  infile &fname2;
145  input;
146  put _infile_;
147 run;
148 filename &fname1 clear;
149 filename &fname2 clear;
150 %mend;