Macros for SAS Application Developers
https://github.com/sasjs/core
mx_testservice.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief Will execute a SASjs web service on SAS 9, Viya or SASjs Server
4  @details Prepares the input files and retrieves the resulting datasets from
5  the response JSON.
6 
7  Note - the _webout fileref should NOT be assigned prior to running this macro.
8 
9  @param [in] program The _PROGRAM endpoint to test
10  @param [in] inputfiles=(0) A list of space seperated fileref:filename pairs as
11  follows:
12  inputfiles=inref:filename inref2:filename2
13  @param [in] inputdatasets= (0) All datasets in this space seperated list are
14  converted into SASJS-formatted CSVs (see mp_ds2csv.sas) files and added to
15  the list of `inputfiles` for ingestion. The dataset will be sent with the
16  same name (no need for a colon modifier).
17  @param [in] inputparams=(0) A dataset containing name/value pairs in the
18  following format:
19  |name:$32|value:$1000|
20  |---|---|
21  |stpmacname|some value|
22  |mustbevalidname|can be anything, oops, %abort!!|
23 
24  @param [in] debug= (log) Provide the _debug value
25  @param [in] mdebug= (0) Set to 1 to provide macro debugging
26  @param [in] viyaresult= (WEBOUT_JSON) The Viya result type to return. For
27  more info, see mv_getjobresult.sas
28  @param [in] viyacontext= (SAS Job Execution compute context) The Viya compute
29  context on which to run the service
30  @param [out] outlib= (0) Output libref to contain the final tables. Set to
31  0 if the service output is not in JSON format.
32  @param [out] outref= (0) Output fileref to create, to contain the full _webout
33  response.
34 
35  <h4> SAS Macros </h4>
36  @li mf_getplatform.sas
37  @li mf_getuniquefileref.sas
38  @li mf_getuniquename.sas
39  @li mp_abort.sas
40  @li mp_binarycopy.sas
41  @li mp_chop.sas
42  @li mp_ds2csv.sas
43  @li ms_testservice.sas
44  @li mv_getjobresult.sas
45  @li mv_jobflow.sas
46 
47  <h4> Related Programs </h4>
48  @li mx_testservice.test.sas
49 
50  @version 9.4
51  @author Allan Bowe
52 
53 **/
54 
55 %macro mx_testservice(program,
56  inputfiles=0,
57  inputdatasets=0,
58  inputparams=0,
59  debug=log,
60  mdebug=0,
61  outlib=0,
62  outref=0,
63  viyaresult=WEBOUT_JSON,
64  viyacontext=SAS Job Execution compute context
65 );
66 %local dbg pcnt fref1 fref2 webref webrefpath i webcount var platform;
67 %if &mdebug=1 %then %do;
68  %put &sysmacroname entry vars:;
69  %put _local_;
70 %end;
71 %else %let dbg=*;
72 
73 /* sanitise inputparams */
74 %let pcnt=0;
75 %if &inputparams ne 0 %then %do;
76  data _null_;
77  set &inputparams;
78  if not nvalid(name,'v7') then putlog (_all_)(=);
79  else if name in (
80  'program','inputfiles','inputparams','debug','outlib','outref'
81  ) then putlog (_all_)(=);
82  else do;
83  x+1;
84  call symputx(name,quote(cats(value)),'l');
85  call symputx(cats('pval',x),name,'l');
86  call symputx('pcnt',x,'l');
87  end;
88  run;
89  %mp_abort(iftrue= (%mf_nobs(&inputparams) ne &pcnt)
90  ,mac=&sysmacroname
91  ,msg=%str(Invalid values in &inputparams)
92  )
93 %end;
94 
95 /* convert inputdatasets to filerefs */
96 %if "&inputdatasets" ne "0" %then %do;
97  %if %quote(&inputfiles)=0 %then %let inputfiles=;
98  %do i=1 %to %sysfunc(countw(&inputdatasets,%str( )));
99  %let var=%scan(&inputdatasets,&i,%str( ));
100  %local dsref&i;
101  %let dsref&i=%mf_getuniquefileref();
102  %mp_ds2csv(&var,outref=&&dsref&i,headerformat=SASJS)
103  %let inputfiles=&inputfiles &&dsref&i:%scan(&var,-1,.);
104  %end;
105 %end;
106 
107 %let platform=%mf_getplatform();
108 %let fref1=%mf_getuniquefileref();
109 %let fref2=%mf_getuniquefileref();
110 %let webref=%mf_getuniquefileref();
111 %let webrefpath=%sysfunc(pathname(work))/%mf_getuniquename();
112 /* mp_chop requires a physical path as input */
113 filename &webref "&webrefpath";
114 
115 %if &platform=SASMETA %then %do;
116 
117  /* parse the input files */
118  %if %quote(&inputfiles) ne 0 %then %do;
119  %let webcount=%sysfunc(countw(&inputfiles));
120  %put &=webcount;
121  %do i=1 %to &webcount;
122  %let var=%scan(&inputfiles,&i,%str( ));
123  %local webfref&i webname&i;
124  %let webref&i=%scan(&var,1,%str(:));
125  %let webname&i=%scan(&var,2,%str(:));
126  %put webref&i=&&webref&i;
127  %put webname&i=&&webname&i;
128  %end;
129  %end;
130  %else %let webcount=0;
131 
132  proc stp program="&program";
133  inputparam _program="&program"
134  %do i=1 %to &webcount;
135  %if &webcount=1 %then %do;
136  _webin_fileref="&&webref&i"
137  _webin_name="&&webname&i"
138  %end;
139  %else %do;
140  _webin_fileref&i="&&webref&i"
141  _webin_name&i="&&webname&i"
142  %end;
143  %end;
144  _webin_file_count="&webcount"
145  _debug="&debug"
146  %do i=1 %to &pcnt;
147  /* resolve name only, proc stp fetches value */
148  &&pval&i=&&&&&&pval&i
149  %end;
150  ;
151  %do i=1 %to &webcount;
152  inputfile &&webref&i;
153  %end;
154  outputfile _webout=&webref;
155  run;
156 
157  data _null_;
158  infile &webref;
159  file &fref1;
160  input;
161  length line $10000;
162  if index(_infile_,'>>weboutBEGIN<<') then do;
163  line=tranwrd(_infile_,'>>weboutBEGIN<<','');
164  put line;
165  end;
166  else if index(_infile_,'>>weboutEND<<') then do;
167  line=tranwrd(_infile_,'>>weboutEND<<','');
168  put line;
169  stop;
170  end;
171  else put _infile_;
172  run;
173  data _null_;
174  infile &fref1;
175  input;
176  put _infile_;
177  run;
178  %if &outlib ne 0 %then %do;
179  libname &outlib json (&fref1);
180  %end;
181  %if &outref ne 0 %then %do;
182  filename &outref temp;
183  %mp_binarycopy(inref=&webref,outref=&outref)
184  %end;
185 
186 %end;
187 %else %if &platform=SASVIYA %then %do;
188 
189  /* prepare inputparams */
190  %local ds1;
191  %let ds1=%mf_getuniquename();
192  %if "&inputparams" ne "0" %then %do;
193  proc transpose data=&inputparams out=&ds1;
194  id name;
195  var value;
196  run;
197  %end;
198  %else %do;
199  data &ds1;run;
200  %end;
201 
202  /* parse the input files - convert to sasjs params */
203  %local webcount i var sasjs_tables;
204  %if %quote(&inputfiles) ne 0 %then %do;
205  %let webcount=%sysfunc(countw(&inputfiles));
206  %put &=webcount;
207  %do i=1 %to &webcount;
208  %let var=%scan(&inputfiles,&i,%str( ));
209  %local webfref&i webname&i sasjs&i.data;
210  %let webref&i=%scan(&var,1,%str(:));
211  %let webname&i=%scan(&var,2,%str(:));
212  %put webref&i=&&webref&i;
213  %put webname&i=&&webname&i;
214 
215  %let sasjs_tables=&sasjs_tables &&webname&i;
216  data _null_;
217  infile &&webref&i lrecl=32767;
218  input;
219  if _n_=1 then call symputx("sasjs&i.data",_infile_);
220  else call symputx(
221  "sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_)
222  );
223  putlog "&sysmacroname infile: " _infile_;
224  run;
225  data &ds1;
226  set &ds1;
227  length sasjs&i.data $32767 sasjs_tables $1000;
228  sasjs&i.data=symget("sasjs&i.data");
229  sasjs_tables=symget("sasjs_tables");
230  run;
231  %end;
232  %end;
233  %else %let webcount=0;
234 
235  data &ds1;
236  retain _program "&program";
237  retain _contextname "&viyacontext";
238  set &ds1;
239  putlog "&sysmacroname inputparams:";
240  putlog (_all_)(=);
241  run;
242 
243  %mv_jobflow(inds=&ds1
244  ,maxconcurrency=1
245  ,outds=work.results
246  ,outref=&fref1
247  ,mdebug=&mdebug
248  )
249  /* show the log */
250  data _null_;
251  infile &fref1;
252  input;
253  putlog _infile_;
254  run;
255  /* get the uri to fetch results */
256  data _null_;
257  set work.results;
258  call symputx('uri',uri);
259  putlog "&sysmacroname: fetching results for " uri;
260  run;
261  /* fetch results from webout.json */
262  %mv_getjobresult(uri=&uri,
263  result=&viyaresult,
264  outref=&outref,
265  outlib=&outlib,
266  mdebug=&mdebug
267  )
268 
269 %end;
270 %else %if &platform=SASJS %then %do;
271 
272  %ms_testservice(&program
273  ,inputfiles=&inputfiles
274  ,inputdatasets=&inputdatasets
275  ,inputparams=&inputparams
276  ,debug=&debug
277  ,mdebug=&mdebug
278  ,outlib=&outlib
279  ,outref=&outref
280  )
281 
282 %end;
283 %else %do;
284  %put %str(ERR)OR: Unrecognised platform: &platform;
285 %end;
286 
287 %if &mdebug=0 %then %do;
288  filename &fref1 clear;
289  %if &platform ne SASJS %then %do;
290  filename &fref2 clear;
291  filename &webref clear;
292  %end;
293 %end;
294 %else %do;
295  %put &sysmacroname exit vars:;
296  %put _local_;
297 %end;
298 
299 %mend mx_testservice;