68%macro mv_createwebservice(path=
70 ,desc=Created by the mv_createwebservice.sas macro
73 ,access_token_var=ACCESS_TOKEN
74 ,grant_type=sas_services
82%
if &mdebug=1 %then %
do;
83 %put &sysmacroname entry vars:;
89%
if &grant_type=detect %then %
do;
90 %
if %symexist(&access_token_var) %then %let grant_type=authorization_code;
91 %
else %let grant_type=sas_services;
93%
if &grant_type=sas_services %then %
do;
94 %let oauth_bearer=oauth_bearer=sas_services;
95 %let &access_token_var=;
99%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
100 and &grant_type ne sas_services
103 ,msg=%str(Invalid value
for grant_type: &grant_type)
105%mp_abort(iftrue=(%mf_isblank(&path)=1)
107 ,msg=%str(path value must be provided)
109%mp_abort(iftrue=(%length(&path)=1)
111 ,msg=%str(path value must be provided)
113%mp_abort(iftrue=(%mf_isblank(&name)=1)
115 ,msg=%str(name value must be provided)
118options noquotelenmax;
120*
remove any trailing slash ;
121%
if "%substr(&path,%length(&path),1)" =
"/" %then
122 %let path=%substr(&path,1,%length(&path)-1);
125%&dbg.put &sysmacroname: Path &path being checked / created;
126%mv_createfolder(path=&path)
129%let base_uri=%mf_getplatform(VIYARESTAPI);
133%let fname1=%mf_getuniquefileref();
134proc http method=
'GET' out=&fname1 &oauth_bearer
135 url=
"&base_uri/folders/folders/@item?path=&path";
136%
if &grant_type=authorization_code %then %
do;
137 headers
"Authorization"=
"Bearer &&&access_token_var";
140%
if &mdebug=1 %then %
do;
147%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200)
149 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
154%let libref1=%mf_getuniquelibref();
155libname &libref1 JSON fileref=&fname1;
159 if rel=
'members' then
160 call symputx(
'membercheck',quote(
"&base_uri"!!trim(href)),
'l');
161 else if rel=
'self' then call symputx(
'parentFolderUri',href,
'l');
165 call symputx(
'folderid',
id,
'l');
168%let fname2=%mf_getuniquefileref();
169proc http method=
'GET'
172 url=%unquote(%superq(membercheck));
174 %
if &grant_type=authorization_code %then %
do;
175 "Authorization"=
"Bearer &&&access_token_var"
177 'Accept'=
'application/vnd.sas.collection+json'
178 'Accept-Language'=
'string';
179%
if &mdebug=1 %then %
do;
184%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200)
186 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
189%
if %upcase(&replace)=YES %then %
do;
190 %mv_deletejes(path=&path, name=&name)
195 %let libref2=%mf_getuniquelibref();
196 libname &libref2 JSON fileref=&fname2;
197 %local exists; %let exists=0;
200 if contenttype=
'jobDefinition' and upcase(name)=
"%upcase(&name)" then
201 call symputx(
'exists',1,
'l');
203 %mp_abort(iftrue=(&exists=1)
205 ,msg=%str(Job &name already exists in &path)
207 libname &libref2 clear;
212%let fname3=%mf_getuniquefileref();
214 file &fname3 TERMSTR=
' ';
215 length
string $32767;
216 string=cats(
'{"version": 0,"name":"'
218 ,
'","type":"Compute","parameters":[{"name":"_addjesbeginendmacros"'
219 ,
',"type":"CHARACTER","defaultValue":"false"}');
220 context=quote(cats(symget(
'contextname')));
221 if context ne
'""' then
do;
222 string=cats(
string,
',{"version": 1,"name": "_contextName","defaultValue":'
223 ,context,
',"type":"CHARACTER","label":"Context Name","required": false}');
225 string=cats(
string,
'],"code":"');
234filename &adapter temp lrecl=3000;
237 put
"/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
239 put
'%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
240 put
' ,engine=DATASTEP ';
241 put
' ,missing=NULL ';
244 put
')/*/STORE SOURCE*/; ';
245 put
'%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval ';
246 put
' tmpds1 tmpds2 tmpds3 tmpds4; ';
247 put
'%let numcols=0; ';
248 put
'%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
250 put
'%if &action=OPEN %then %do; ';
251 put
' options nobomfile; ';
252 put
' data _null_;file &jref encoding=''utf-8'' lrecl=200; ';
253 put
' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
256 put
'%else %if (&action=ARR or &action=OBJ) %then %do; ';
257 put
' /* force variable names to always be uppercase in the JSON */ ';
258 put
' options validvarname=upcase; ';
259 put
' /* To avoid issues with _webout on EBI - such as encoding diffs and truncation ';
260 put
' (https://support.sas.com/kb/49/325.html) we use temporary files */ ';
261 put
' filename _sjs1 temp lrecl=200 ; ';
262 put
' data _null_; file _sjs1 encoding=''utf-8''; ';
263 put
' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
265 put
' /* now write to _webout 1 char at a time */ ';
266 put
' data _null_; ';
267 put
' infile _sjs1 lrecl=1 recfm=n; ';
268 put
' file &jref mod lrecl=1 recfm=n; ';
269 put
' input sourcechar $char1. @@; ';
270 put
' format sourcechar hex2.; ';
271 put
' put sourcechar char1. @@; ';
273 put
' filename _sjs1 clear; ';
275 put
' /* grab col defs */ ';
276 put
' proc contents noprint data=&ds ';
277 put
' out=_data_(keep=name type length format formatl formatd varnum label); ';
279 put
' %let colinfo=%scan(&syslast,2,.); ';
280 put
' proc sort data=&colinfo; ';
283 put
' /* move meta to mac vars */ ';
284 put
' data &colinfo; ';
285 put
' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
286 put
' set &colinfo end=last nobs=nobs; ';
287 put
' name=upcase(name); ';
288 put
' /* fix formats */ ';
289 put
' if type=2 or type=6 then do; ';
290 put
' typelong=''char''; ';
291 put
' length fmt $49.; ';
292 put
' if format='''' then fmt=cats(
''$
'',length,
''.
'');
';
293 put ' else if formatl=0 then fmt=cats(format,
''.
'');
';
294 put ' else fmt=cats(format,formatl,
''.
'');
';
297 put ' typelong=
''num
'';
';
298 put ' if format=
'''' then fmt=''best.''; ';
299 put
' else if formatl=0 then fmt=cats(format,''.''); ';
300 put
' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
301 put
' else fmt=cats(format,formatl,''.'',formatd); ';
303 put
' /* 32 char unique name */ ';
304 put
' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
306 put
' call symputx(cats(''name'',_n_),name,''l''); ';
307 put
' call symputx(cats(''newname'',_n_),newname,''l''); ';
308 put
' call symputx(cats(''length'',_n_),length,''l''); ';
309 put
' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
310 put
' call symputx(cats(''type'',_n_),type,''l''); ';
311 put
' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
312 put
' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
313 put
' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
314 put
' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
315 put
' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
318 put
' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
320 put
' select count(*) into: lastobs from &ds; ';
321 put
' %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs)); ';
323 put
' %if &engine=PROCJSON %then %do; ';
324 put
' %if &missing=STRING %then %do; ';
325 put
' %put &sysmacroname: Special Missings not supported in proc json.; ';
326 put
' %put &sysmacroname: Switching to DATASTEP engine; ';
327 put
' %goto datastep; ';
329 put
' data &tempds; ';
332 put
' %if &fmt=N %then format _numeric_ best32.;; ';
333 put
' /* PRETTY is necessary to avoid line truncation in large files */ ';
334 put
' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
335 put
' proc json out=_sjs2 pretty ';
336 put
' %if &action=ARR %then nokeys ; ';
337 put
' ;export &tempds / nosastags fmtnumeric; ';
339 put
' /* send back to webout */ ';
340 put
' data _null_; ';
341 put
' infile _sjs2 lrecl=1 recfm=n; ';
342 put
' file &jref mod lrecl=1 recfm=n; ';
343 put
' input sourcechar $char1. @@; ';
344 put
' format sourcechar hex2.; ';
345 put
' put sourcechar char1. @@; ';
347 put
' filename _sjs2 clear; ';
349 put
' %else %if &engine=DATASTEP %then %do; ';
351 put
' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 ';
353 put
' %put &sysmacroname: &ds NOT FOUND!!!; ';
357 put
' %if &fmt=Y %then %do; ';
359 put
' * Extract format definitions ';
360 put
' * First, by getting library locations from dictionary.formats ';
361 put
' * Then, by exporting the width using proc format ';
362 put
' * Cannot use maxw from sashelp.vformat as not always populated ';
363 put
' * Cannot use fmtinfo() as not supported in all flavours ';
365 put
' %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
366 put
' %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
367 put
' %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
368 put
' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
369 put
' proc sql noprint; ';
370 put
' create table &tmpds1 as ';
371 put
' select cats(libname,''.'',memname) as FMTCAT, ';
373 put
' from dictionary.formats ';
374 put
' where fmttype=''F'' and libname is not null ';
375 put
' and fmtname in (select format from &colinfo where format is not null) ';
377 put
' create table &tmpds2( ';
378 put
' FMTNAME char(32), ';
381 put
' %local catlist cat fmtlist i; ';
382 put
' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
383 put
' %do i=1 %to %sysfunc(countw(&catlist,%str( ))); ';
384 put
' %let cat=%scan(&catlist,&i,%str( )); ';
386 put
' select distinct fmtname into: fmtlist separated by '' '' ';
387 put
' from &tmpds1 where fmtcat="&cat"; ';
388 put
' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
389 put
' select &fmtlist; ';
392 put
' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
396 put
' create table &tmpds4 as ';
397 put
' select a.*, b.length as MAXW ';
398 put
' from &colinfo a ';
399 put
' left join &tmpds2 b ';
400 put
' on cats(a.format)=cats(upcase(b.fmtname)) ';
401 put
' order by a.varnum; ';
402 put
' data _null_; ';
403 put
' set &tmpds4; ';
404 put
' if not missing(maxw); ';
405 put
' call symputx( ';
406 put
' cats(''fmtlen'',_n_), ';
407 put
' /* vars need extra padding due to JSON escaping of special chars */ ';
408 put
' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
413 put
' /* configure varlenchk - as we are explicitly shortening the variables */ ';
414 put
' %let optval=%sysfunc(getoption(varlenchk)); ';
415 put
' options varlenchk=NOWARN; ';
416 put
' data _data_(compress=char); ';
417 put
' /* shorten the new vars */ ';
419 put
' %do i=1 %to &numcols; ';
420 put
' &&name&i $&&fmtlen&i ';
423 put
' /* rename on entry */ ';
424 put
' set &ds(rename=( ';
425 put
' %do i=1 %to &numcols; ';
426 put
' &&name&i=&&newname&i ';
432 put
' %do i=1 %to &numcols; ';
436 put
' %do i=1 %to &numcols; ';
437 put
' %if &&typelong&i=num %then %do; ';
438 put
' &&name&i=cats(put(&&newname&i,&&fmt&i)); ';
441 put
' &&name&i=put(&&newname&i,&&fmt&i); ';
444 put
' if _error_ then do; ';
445 put
' call symputx(''syscc'',1012); ';
449 put
' %let fmtds=&syslast; ';
450 put
' options varlenchk=&optval; ';
453 put
' proc format; /* credit yabwon for special null removal */ ';
454 put
' value bart (default=40) ';
455 put
' %if &missing=NULL %then %do; ';
456 put
' ._ - .z = null ';
459 put
' ._ = [quote()] ';
461 put
' .a - .z = [quote()] ';
463 put
' other = [best.]; ';
465 put
' data &tempds; ';
466 put
' attrib _all_ label='''';
';
467 put ' %
do i=1 %to &numcols;
';
468 put ' %
if &&typelong&i=
char or &fmt=Y %then %
do;
';
469 put ' length &&name&i $&&fmtlen&i...;
';
470 put ' format &&name&i $&&fmtlen&i...;
';
473 put ' %
if &fmt=Y %then %
do;
';
480 put ' format _numeric_ bart.;
';
481 put ' %
do i=1 %to &numcols;
';
482 put ' %
if &&typelong&i=
char or &fmt=Y %then %
do;
';
483 put ' if findc(&&name&i,
''"\''!!''0A0D09000E0F010210111A''x) then do; ';
484 put ' &&name&i=''"''!!trim(
';
485 put ' prxchange(
''s/
"/\\"/
'',-1,
';
486 put ' prxchange(
''s/\x0A/\n/
'',-1,
';
487 put ' prxchange(
''s/\x0D/\r/
'',-1,
';
488 put ' prxchange(
''s/\x09/\\t/
'',-1,
';
489 put ' prxchange(
''s/\x00/\\u0000/
'',-1,
';
490 put ' prxchange(
''s/\x0E/\\u000E/
'',-1,
';
491 put ' prxchange(
''s/\x0F/\\u000F/
'',-1,
';
492 put ' prxchange(
''s/\x01/\\u0001/
'',-1,
';
493 put ' prxchange(
''s/\x02/\\u0002/
'',-1,
';
494 put ' prxchange(
''s/\x10/\\u0010/
'',-1,
';
495 put ' prxchange(
''s/\x11/\\u0011/
'',-1,
';
496 put ' prxchange(
''s/\x1A/\\u001A/
'',-1,
';
497 put ' prxchange(
''s/\\/\\\\/
'',-1,&&name&i)
';
498 put ' )))))))))))))!!
''"''; ';
500 put ' else &&name&i=quote(cats(&&name&i)); ';
505 put ' filename _sjs3 temp lrecl=131068 ; ';
506 put ' data _null_; ';
507 put ' file _sjs3 encoding=''utf-8''; ';
508 put ' if _n_=1 then put "[
"; ';
509 put ' set &tempds; ';
510 put ' if _n_>1 then put ",
" @; put ';
511 put ' %if &action=ARR %then "[
" ; %else "{
" ; ';
512 put ' %do i=1 %to &numcols; ';
513 put ' %if &i>1 %then ",
" ; ';
514 put ' %if &action=OBJ %then """&&name&i
"":
" ; ';
515 put ' "&&name&i
"n /* name literal for reserved variable names */ ';
517 put ' %if &action=ARR %then "]
" ; %else "}
" ; ; ';
519 put ' /* close out the table */ ';
520 put ' data _null_; ';
521 put ' file _sjs3 mod encoding=''utf-8''; ';
524 put ' data _null_; ';
525 put ' infile _sjs3 lrecl=1 recfm=n; ';
526 put ' file &jref mod lrecl=1 recfm=n; ';
527 put ' input sourcechar $char1. @@; ';
528 put ' format sourcechar hex2.; ';
529 put ' put sourcechar char1. @@; ';
531 put ' filename _sjs3 clear; ';
535 put ' drop table &colinfo, &tempds; ';
537 put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
538 put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
539 put ' data _null_; ';
541 put ' length label $350; ';
542 put ' put ",
""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))
"":{
""vars
"":{
"; ';
543 put ' do i=1 to &numcols; ';
544 put ' name=quote(trim(symget(cats(''name'',i)))); ';
545 put ' format=quote(trim(symget(cats(''fmt'',i)))); ';
546 put ' label=quote(prxchange(''s/\\/\\\\/'',-1,trim(symget(cats(''label'',i))))); ';
547 put ' length=quote(trim(symget(cats(''length'',i)))); ';
548 put ' type=quote(trim(symget(cats(''typelong'',i)))); ';
549 put ' if i>1 then put ",
" @@; ';
550 put ' put name '':{"format
":'' format '',"label
":'' label ';
551 put ' '',"length
":'' length '',"type
":'' type ''}''; ';
555 put ' /* send back to webout */ ';
556 put ' data _null_; ';
557 put ' infile _sjs4 lrecl=1 recfm=n; ';
558 put ' file &jref mod lrecl=1 recfm=n; ';
559 put ' input sourcechar $char1. @@; ';
560 put ' format sourcechar hex2.; ';
561 put ' put sourcechar char1. @@; ';
563 put ' filename _sjs4 clear; ';
567 put '%else %if &action=CLOSE %then %do; ';
568 put ' data _null_; file &jref encoding=''utf-8'' mod ; ';
572 put '%mend mp_jsonout; ';
574 put '%macro mf_getuser( ';
575 put ')/*/STORE SOURCE*/; ';
576 put ' %local user; ';
578 put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
579 put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
580 put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
582 put ' %else %if %symexist(_metaperson) %then %do; ';
583 put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
584 put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
585 put ' /* but be sure to quote in case of usernames with commas */ ';
586 put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
588 put ' %else %let user=&sysuserid; ';
590 put ' %quote(&user) ';
592 put '%mend mf_getuser; ';
593 put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
594 put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
596 put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
597 put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
598 put '%if %index("&_debug
",log) %then %let _debug=128; ';
600 put '%local i tempds table; ';
601 put '%let action=%upcase(&action); ';
603 put '%if &action=FETCH %then %do; ';
604 put ' %if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 128 %then %do; ';
605 put ' options mprint notes mprintnest; ';
608 put ' %if not %symexist(_webin_fileuri1) %then %do; ';
609 put ' %let _webin_file_count=%eval(&_webin_file_count+0); ';
610 put ' %let _webin_fileuri1=&_webin_fileuri; ';
611 put ' %let _webin_name1=&_webin_name; ';
612 put ' %if &_EXECUTIONTASKS=true %then %do; ';
613 put ' /* TODO - remove this once SAS Track CS0409737 is resolved */ ';
614 put ' /* links: https://github.com/sasjs/adapter/issues/884 */ ';
615 put ' %if %upcase(&_webin_name)=_SASJS_NOOP %then %let _webin_file_count=0; ';
619 put ' /* if the sasjs_tables param is passed, we expect param based upload */ ';
620 put ' %if %length(&sasjs_tables.X)>1 %then %do; ';
622 put ' /* convert data from macro variables to datasets */ ';
623 put ' %do i=1 %to %sysfunc(countw(&sasjs_tables)); ';
624 put ' %let table=%scan(&sasjs_tables,&i,%str( )); ';
625 put ' %if %symexist(sasjs&i.data0)=0 %then %let sasjs&i.data0=1; ';
626 put ' data _null_; ';
627 put ' file "%sysfunc(pathname(work))/&table..csv
" recfm=n; ';
628 put ' retain nrflg 0; ';
629 put ' length line $32767; ';
630 put ' do i=1 to &&sasjs&i.data0; ';
631 put ' if &&sasjs&i.data0=1 then line=symget("sasjs&i.data
"); ';
632 put ' else line=symget(cats("sasjs&i.data
",i)); ';
633 put ' if i=1 and substr(line,1,7)=''%nrstr('' then do; ';
635 put ' line=substr(line,8); ';
637 put ' if i=&&sasjs&i.data0 and nrflg=1 then do; ';
638 put ' line=substr(line,1,length(line)-1); ';
640 put ' put line +(-1) @; ';
643 put ' data _null_; ';
644 put ' infile "%sysfunc(pathname(work))/&table..csv
" termstr=crlf ; ';
646 put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
648 put ' data work.&table; ';
649 put ' infile "%sysfunc(pathname(work))/&table..csv
" firstobs=2 dsd ';
650 put ' termstr=crlf; ';
651 put ' input &input_statement; ';
655 put ' %else %do i=1 %to &_webin_file_count; ';
656 put ' /* read in any files that are sent */ ';
657 put ' %if &_EXECUTIONTASKS=true %then %do; ';
658 put ' filename indata "%sysfunc(pathname(&&_webin_fileref&i))
" lrecl=999999; ';
661 put ' filename indata filesrvc "&&_webin_fileuri&i
" lrecl=999999; ';
663 put ' data _null_; ';
664 put ' infile indata termstr=crlf lrecl=32767; ';
666 put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
667 put ' %if %str(&_debug) ge 128 %then %do; ';
668 put ' if _n_<20 then putlog _infile_; ';
675 put ' data &&_webin_name&i; ';
676 put ' infile indata firstobs=2 dsd termstr=crlf ; ';
677 put ' input &input_statement; ';
679 put ' %let sasjs_tables=&sasjs_tables &&_webin_name&i; ';
682 put '%else %if &action=OPEN %then %do; ';
683 put ' /* setup webout */ ';
684 put ' OPTIONS NOBOMFILE; ';
685 put ' %if "X&SYS_JES_JOB_URI.X
"="XX
" %then %do; ';
686 put ' filename _webout temp lrecl=999999 mod; ';
689 put ' filename _webout filesrvc parenturi="&SYS_JES_JOB_URI
" ';
690 put ' name="_webout.json
" lrecl=999999 mod; ';
693 put ' /* setup temp ref */ ';
694 put ' %if %upcase(&fref) ne _WEBOUT %then %do; ';
695 put ' filename &fref temp lrecl=999999 permission=''A::u::rwx,A::g::rw-,A::o::---''; ';
698 put ' /* setup json */ ';
699 put ' data _null_;file &fref; ';
700 put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
701 put ' put ''>>weboutBEGIN<<''; ';
703 put ' put ''{"SYSDATE
" : "'' "&SYSDATE" ''"''; ';
704 put ' put '',"SYSTIME
" : "'' "&SYSTIME" ''"''; ';
707 put '%else %if &action=ARR or &action=OBJ %then %do; ';
708 put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
709 put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs ';
712 put '%else %if &action=CLOSE %then %do; ';
713 put ' %if %str(&workobs) > 0 %then %do; ';
714 put ' /* send back first XX records of each work table for debugging */ ';
715 put ' data;run;%let tempds=%scan(&syslast,2,.); ';
716 put ' ods output Members=&tempds; ';
717 put ' proc datasets library=WORK memtype=data; ';
718 put ' %local wtcnt;%let wtcnt=0; ';
719 put ' data _null_; ';
720 put ' set &tempds; ';
721 put ' if not (upcase(name) =:"DATA
"); /* ignore temp datasets */ ';
723 put ' call symputx(cats(''wt'',i),name,''l''); ';
724 put ' call symputx(''wtcnt'',i,''l''); ';
725 put ' data _null_; file &fref mod; put ",
""WORK
"":{
"; ';
726 put ' %do i=1 %to &wtcnt; ';
727 put ' %let wt=&&wt&i; ';
728 put ' data _null_; file &fref mod; ';
729 put ' dsid=open("WORK.&wt
",''is''); ';
730 put ' nlobs=attrn(dsid,''NLOBS''); ';
731 put ' nvars=attrn(dsid,''NVARS''); ';
732 put ' rc=close(dsid); ';
733 put ' if &i>1 then put '',''@; ';
734 put ' put " ""&wt
"" : {
"; ';
735 put ' put ''"nlobs
":'' nlobs; ';
736 put ' put '',"nvars
":'' nvars; ';
737 put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y ';
738 put ' ,maxobs=&workobs ';
740 put ' data _null_; file &fref mod;put "}
"; ';
742 put ' data _null_; file &fref mod;put "}
";run; ';
745 put ' /* close off json */ ';
746 put ' data _null_;file &fref mod; ';
747 put ' length SYSPROCESSNAME syserrortext syswarningtext autoexec $512; ';
748 put ' put ",
""_DEBUG
"" :
""&_debug
"" "; ';
749 put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
750 put ' put '',"_PROGRAM
" : '' _PROGRAM ; ';
751 put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
752 put ' put '',"AUTOEXEC
" : '' autoexec; ';
753 put ' put ",
""MF_GETUSER
"" :
""%mf_getuser()
"" "; ';
754 put ' SYS_JES_JOB_URI=quote(trim(resolve(symget(''SYS_JES_JOB_URI'')))); ';
755 put ' put '',"SYS_JES_JOB_URI
" : '' SYS_JES_JOB_URI ; ';
756 put ' put ",
""SYSJOBID
"" :
""&sysjobid
"" "; ';
757 put ' put ",
""SYSCC
"" :
""&syscc
"" "; ';
758 put ' syserrortext=cats(symget(''syserrortext'')); ';
759 put ' if findc(syserrortext,''"\
''!!
''0A0D09000E0F010210111A
''x) then
do;
';
760 put ' syserrortext=
''"''!!trim( ';
761 put ' prxchange(''s/"/\\
"/'',-1, /* double quote */ ';
762 put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
763 put ' prxchange(''s/\x0D/\r/'',-1, /* carriage return */ ';
764 put ' prxchange(''s/\x09/\\t/'',-1, /* tab */ ';
765 put ' prxchange(''s/\x00/\\u0000/'',-1, /* NUL */ ';
766 put ' prxchange(''s/\x0E/\\u000E/'',-1, /* SS */ ';
767 put ' prxchange(''s/\x0F/\\u000F/'',-1, /* SF */ ';
768 put ' prxchange(''s/\x01/\\u0001/'',-1, /* SOH */ ';
769 put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
770 put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
771 put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
772 put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
773 put ' prxchange(''s/\\/\\\\/'',-1,syserrortext) ';
774 put ' )))))))))))))!!''"'';
';
776 put ' else syserrortext=cats(
''"'',syserrortext,''"'');
';
777 put ' put
'',
"SYSERRORTEXT" :
'' syserrortext;
';
778 put ' put
",""SYSHOSTNAME"" : ""&syshostname"" ";
';
779 put ' put
",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
';
780 put ' put
",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
';
781 put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
';
782 put ' put
",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
';
783 put ' put
",""SYSJOBID"" : ""&sysjobid"" ";
';
784 put ' put
",""SYSSCPL"" : ""&sysscpl"" ";
';
785 put ' put
",""SYSSITE"" : ""&syssite"" ";
';
786 put ' put
",""SYSUSERID"" : ""&sysuserid"" ";
';
787 put ' sysvlong=quote(trim(symget(
''sysvlong
'')));
';
788 put ' put
'',
"SYSVLONG" :
'' sysvlong;
';
789 put ' syswarningtext=cats(symget(
''syswarningtext
''));
';
790 put ' if findc(syswarningtext,
''"\''!!''0A0D09000E0F010210111A''x) then do; ';
791 put ' syswarningtext=''"''!!trim(
';
792 put ' prxchange(
''s/
"/\\"/
'',-1,
';
793 put ' prxchange(
''s/\x0A/\n/
'',-1,
';
794 put ' prxchange(
''s/\x0D/\r/
'',-1,
';
795 put ' prxchange(
''s/\x09/\\t/
'',-1,
';
796 put ' prxchange(
''s/\x00/\\u0000/
'',-1,
';
797 put ' prxchange(
''s/\x0E/\\u000E/
'',-1,
';
798 put ' prxchange(
''s/\x0F/\\u000F/
'',-1,
';
799 put ' prxchange(
''s/\x01/\\u0001/
'',-1,
';
800 put ' prxchange(
''s/\x02/\\u0002/
'',-1,
';
801 put ' prxchange(
''s/\x10/\\u0010/
'',-1,
';
802 put ' prxchange(
''s/\x11/\\u0011/
'',-1,
';
803 put ' prxchange(
''s/\x1A/\\u001A/
'',-1,
';
804 put ' prxchange(
''s/\\/\\\\/
'',-1,syswarningtext)
';
805 put ' )))))))))))))!!
''"''; ';
807 put ' else syswarningtext=cats(''"'',syswarningtext,
''"''); ';
808 put ' put '',"SYSWARNINGTEXT
" : '' syswarningtext; ';
809 put ' put '',"END_DTTM
" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
810 put ' length memsize $32; ';
811 put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)
"; ';
812 put ' memsize=quote(cats(memsize)); ';
813 put ' put '',"MEMSIZE
" : '' memsize; ';
815 put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
816 put ' put ''>>weboutEND<<''; ';
818 put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
819 put ' data _null_; rc=fcopy("&fref
","_webout
");run; ';
824 put '%mend mv_webout; ';
826 put '/* if calling viya service with _job param, _program will conflict */';
827 put '/* so it is provided by SASjs instead as __program */';
828 put '%global __program _program;';
829 put '%let _program=%sysfunc(coalescec(&__program,&_program));';
831 put '%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO';
834 put ' %mv_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing';
835 put ' ,showmeta=&showmeta,maxobs=&maxobs';
840/* insert the code, escaping double quotes and carriage returns */
841%&dbg.put &sysmacroname: Creating final input file;
842%local x fref freflist;
843%let freflist= &adapter &precode &code ;
844%do x=1 %to %sysfunc(countw(&freflist));
845 %let fref=%scan(&freflist,&x);
846 %&dbg.put &sysmacroname: adding &fref fileref;
848 length filein 8 fileid 8;
849 filein = fopen("&fref
","I
",1,"B
");
850 fileid = fopen("&fname3
","A
",1,"B
");
852 do while(fread(filein)=0);
853 rc = fget(filein,rec,1);
854 if rec='"' then do; /* DOUBLE QUOTE */
855 rc =fput(fileid,'\
');rc =fwrite(fileid);
856 rc =fput(fileid,'"');rc =fwrite(fileid);
858 else if rec='0A'x then do; /* LF */
859 rc =fput(fileid,'\');rc =fwrite(fileid);
860 rc =fput(fileid,'n');rc =fwrite(fileid);
862 else if rec='0D'x then do; /* CR */
863 rc =fput(fileid,'\');rc =fwrite(fileid);
864 rc =fput(fileid,'r');rc =fwrite(fileid);
866 else if rec='09'x then do; /* TAB */
867 rc =fput(fileid,'\');rc =fwrite(fileid);
868 rc =fput(fileid,'t');rc =fwrite(fileid);
870 else if rec='5C'x then do; /* BACKSLASH */
871 rc =fput(fileid,'\');rc =fwrite(fileid);
872 rc =fput(fileid,'\');rc =fwrite(fileid);
874 else if rec='01'x then do; /* Unprintable */
875 rc =fput(fileid,'\');rc =fwrite(fileid);
876 rc =fput(fileid,'u');rc =fwrite(fileid);
877 rc =fput(fileid,'0');rc =fwrite(fileid);
878 rc =fput(fileid,'0');rc =fwrite(fileid);
879 rc =fput(fileid,'0');rc =fwrite(fileid);
880 rc =fput(fileid,'1');rc =fwrite(fileid);
882 else if rec='07'x then do; /* Bell Char */
883 rc =fput(fileid,'\');rc =fwrite(fileid);
884 rc =fput(fileid,'u');rc =fwrite(fileid);
885 rc =fput(fileid,'0');rc =fwrite(fileid);
886 rc =fput(fileid,'0');rc =fwrite(fileid);
887 rc =fput(fileid,'0');rc =fwrite(fileid);
888 rc =fput(fileid,'7');rc =fwrite(fileid);
890 else if rec='1B'x then do; /* escape char */
891 rc =fput(fileid,'\');rc =fwrite(fileid);
892 rc =fput(fileid,'u');rc =fwrite(fileid);
893 rc =fput(fileid,'0');rc =fwrite(fileid);
894 rc =fput(fileid,'0');rc =fwrite(fileid);
895 rc =fput(fileid,'1');rc =fwrite(fileid);
896 rc =fput(fileid,'B');rc =fwrite(fileid);
899 rc =fput(fileid,rec);
908/* finish off the body of the code file loaded to JES */
910 file &fname3 mod TERMSTR=' ';
914%if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
915 %put &sysmacroname: input about to be POSTed;
916 data _null_;infile &fname3;input;putlog _infile_;run;
919%&dbg.put &sysmacroname: Creating the actual service!;
921%let fname4=%mf_getuniquefileref();
922proc http method='POST
'
926 url="&base_uri/jobDefinitions/definitions?parentFolderUri=&parentFolderUri";
927 headers 'Content-Type
'='application/vnd.sas.job.definition+json
'
928 %if &grant_type=authorization_code %then %do;
929 "Authorization"="Bearer &&&access_token_var"
931 "Accept"="application/vnd.sas.job.definition+json";
932%if &mdebug=1 %then %do;
936%if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
937 %put &sysmacroname: output from POSTing job definition;
938 data _null_;infile &fname4;input;putlog _infile_;run;
940%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
942 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
945/* get the url so we can give a helpful log message */
948 if symexist('_baseurl
') then do;
949 url=symget('_baseurl
');
950 if subpad(url,length(url)-9,9)='SASStudio
'
951 then url=substr(url,1,length(url)-11);
952 else url="&systcpiphostname";
954 else url="&systcpiphostname";
955 call symputx('url
',url);
958%if &mdebug=1 %then %do;
959 %put &sysmacroname exit vars:;
964 filename &fname1 clear;
965 filename &fname2 clear;
966 filename &fname3 clear;
967 filename &fname4 clear;
968 filename &adapter clear;
969 libname &libref1 clear;
972%put &sysmacroname: Job &name created! Check it out:;
973%put &url/SASJobExecution?_PROGRAM=&path/&name;
975%mend mv_createwebservice;