/** @file mv_createfolder.sas @brief Creates a viya folder if that folder does not already exist @details Creates a viya folder by checking if each parent folder exists, and recursively creating children if needed. Usage: %mv_createfolder(path=/Public) @param [in] path= The full path of the folder to be created @param [in] access_token_var= The global macro variable to contain the access token, if using authorization_code grant type. @param [in] grant_type= (sas_services) Valid values are: @li password @li authorization_code @li sas_services @param [in] mdebug=(0) set to 1 to enable DEBUG messages @param [out] outds=(_null_) Optionally create an output dataset which will contain the uri (self_uri) of the created (and parent) folder.

SAS Macros

@li mp_abort.sas @li mf_getuniquefileref.sas @li mf_getuniquelibref.sas @li mf_isblank.sas @li mfv_getpathuri.sas @li mf_getplatform.sas @li mfv_existfolder.sas **/ %macro mv_createfolder(path= ,access_token_var=ACCESS_TOKEN ,grant_type=sas_services ,mdebug=0 ,outds=_null_ ); %local dbg; %if &mdebug=1 %then %do; %put &sysmacroname entry vars:; %put _local_; %end; %else %let dbg=*; %mp_abort( iftrue=(&syscc ne 0), msg=Cannot enter &sysmacroname with syscc=&syscc ) %if %mfv_existfolder(&path)=1 %then %do; %&dbg.put &sysmacroname: &path already exists; data &outds; self_uri="%mfv_getpathuri(&path)"; output; stop; run; %return; %end; %mp_abort(iftrue=(&syscc ne 0),msg=syscc=&syscc when folder checking) %local oauth_bearer; %if &grant_type=detect %then %do; %if %symexist(&access_token_var) %then %let grant_type=authorization_code; %else %let grant_type=sas_services; %end; %if &grant_type=sas_services %then %do; %let oauth_bearer=oauth_bearer=sas_services; %let &access_token_var=; %end; %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password and &grant_type ne sas_services ) ,mac=&sysmacroname ,msg=%str(Invalid value for grant_type: &grant_type) ) %mp_abort(iftrue=(%mf_isblank(&path)=1) ,mac=&sysmacroname ,msg=%str(path value must be provided) ) %mp_abort(iftrue=(%length(&path)=1) ,mac=&sysmacroname ,msg=%str(path value must be provided) ) options noquotelenmax; %local subfolder_cnt; /* determine the number of subfolders */ %let subfolder_cnt=%sysfunc(countw(&path,/)); %local base_uri; /* location of rest apis */ %let base_uri=%mf_getplatform(VIYARESTAPI); %local href; /* resource address (none for root) */ %let href="&base_uri/folders/folders?parentFolderUri=/folders/folders/none"; %local x newpath subfolder; %do x=1 %to &subfolder_cnt; %let subfolder=%scan(&path,&x,%str(/)); %let newpath=&newpath/&subfolder; %local fname1; %let fname1=%mf_getuniquefileref(); %put &sysmacroname checking to see if &newpath exists; proc http method='GET' out=&fname1 &oauth_bearer url="&base_uri/folders/folders/@item?path=&newpath"; %if &grant_type=authorization_code %then %do; headers "Authorization"="Bearer &&&access_token_var"; %end; run; %if &SYS_PROCHTTP_STATUS_CODE=401 %then %do; /* relates to: https://github.com/sasjs/core/issues/400 */ %put 401 thrown in &sysmacroname; %put sleeping: %sysfunc(sleep(12,1)) secs - will try again; proc http method='GET' out=&fname1 &oauth_bearer url="&base_uri/folders/folders/@item?path=&newpath"; %if &grant_type=authorization_code %then %do; headers "Authorization"="Bearer &&&access_token_var"; %end; run; %end; %local libref1; %let libref1=%mf_getuniquelibref(); libname &libref1 JSON fileref=&fname1; %mp_abort( iftrue=( &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 404 ) ,mac=mv_createfolder124 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ) %if &mdebug=1 %then %do; %put &sysmacroname following check to see if &newpath exists:; %put _local_; data _null_; infile &fname1; input; putlog _infile_; run; %end; %if &SYS_PROCHTTP_STATUS_CODE=200 %then %do; %*put &sysmacroname &newpath exists so grab the follow on link ; data _null_; set &libref1..links; if rel='createChild' then call symputx('href',quote(cats("&base_uri",href)),'l'); run; %end; %else %if &SYS_PROCHTTP_STATUS_CODE=404 %then %do; %put &sysmacroname &newpath not found - creating it now; %local fname2; %let fname2=%mf_getuniquefileref(); data _null_; length json $1000; json=cats("'" ,'{"name":' ,quote(trim(symget('subfolder'))) ,',"description":' ,quote("&subfolder, created by &sysmacroname") ,',"type":"folder"}' ,"'" ); call symputx('json',json,'l'); run; proc http method='POST' in=&json out=&fname2 &oauth_bearer url=%unquote(%superq(href)); headers %if &grant_type=authorization_code %then %do; "Authorization"="Bearer &&&access_token_var" %end; 'Content-Type'='application/vnd.sas.content.folder+json' 'Accept'='application/vnd.sas.content.folder+json'; run; %if &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do; %put &=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE; %end; %mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201) ,mac=&sysmacroname ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ) %local libref2; %let libref2=%mf_getuniquelibref(); libname &libref2 JSON fileref=&fname2; %put &sysmacroname &newpath now created. Grabbing the follow on link ; data &outds; set &libref2..links; if rel='createChild' then do; call symputx('href',quote(cats("&base_uri",href)),'l'); &dbg put (_all_)(=); end; if method='GET' and rel='self' then do; self_uri=uri; output; end; keep self_uri ; run; libname &libref2 clear; filename &fname2 clear; %end; filename &fname1 clear; libname &libref1 clear; %end; %mp_abort( iftrue=(&syscc ne 0), msg=Cannot leave &sysmacroname with syscc=&syscc ) %mend mv_createfolder;