35. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 6/5/2019 9:23:28 PM Eastern Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

35.1 Files compared

# Location File Last Modified
1 VSE_P2_v2_1_0_iter_11.zip\ClinSchd\Desktop\ClinSchd.Modules.VAR\Rest RestClient.cs Thu May 30 18:17:48 2019 UTC
2 VSE_P2_v2_1_0_iter_11.zip\ClinSchd\Desktop\ClinSchd.Modules.VAR\Rest RestClient.cs Tue Jun 4 19:59:12 2019 UTC

35.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 1232
Changed 1 2
Inserted 0 0
Removed 0 0

35.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

35.4 Active regular expressions

No regular expressions were active.

35.5 Comparison detail

  1   using Newt onsoft.Jso n;
  2   using Syst em;
  3   using Syst em.Collect ions.Gener ic;
  4   using Syst em.Configu ration;
  5   using Syst em.Linq;
  6   using Syst em.Net;
  7   using Syst em.Net.Htt p;
  8   using Syst em.Net.Htt p.Headers;
  9   using Syst em.Securit y.Authenti cation;
  10   using Syst em.Web;
  11   using Syst em.Threadi ng.Tasks;
  12   using Syst em.Text;
  13   using Syst em.Securit y;
  14   using Clin Schd.Infra structure;
  15  
  16   namespace  ClinSchd.M odules.VAR .Rest
  17   {
  18       public  class Res tClient :  IRestClien t
  19       {
  20           pu blic const  string SE SSION_ID_C OOKIE_NAME  = "JSESSI ONID";
  21           pu blic stati c readonly  Type[] Se rviceExcep tions = {  typeof(Htt pRequestEx ception),  typeof(Aut henticatio nException ), typeof( JsonReader Exception)  };
  22           pr ivate stat ic int RET RY_ATTEMPT S = 3;
  23  
  24           #r egion priv ate member s
  25  
  26           pr ivate stat ic readonl y HttpClie nt _httpCl ient = new  HttpClien t(
  27                new Logg ingHandler (
  28                    new  HttpClient Handler
  29                    {
  30                         AllowAutoR edirect =  false,
  31                         // 08/03/2 0018 - RHH  - Need to  manually  set the se ssion id b ecause som e calls re turn the s ession id  as secure,  so we nee d to set H ttpClient  to NOT use  Cookies.
  32                         UseCookies  = false
  33                         //CookieCo ntainer =  new Cookie Container( )
  34                    })
  35                );
  36  
  37           // FF - 10/17 /2018 - Co mmenting o ut line to  suprerss  Fortify Lo w warning  -  The fie ld _httpCl ientlock i s never us ed.
  38           // private st atic Objec t _httpCli entlock =  new object ();
  39           pr ivate stat ic OAuthTo ken _token ;
  40           pr ivate stri ng _hostNa me;
  41           pr ivate stri ng _client ResourcePa th;
  42           pr ivate stri ng _authSe rvicesPath ;
  43           pr ivate stri ng _client Id;
  44           pr ivate stri ng _redire ctUri;
  45           pr ivate stri ng _sessio nID = stri ng.Empty;
  46           // private bo ol _lastSe ssionIDRet urnedSecur e = false;
  47           #e ndregion
  48  
  49           #r egion ctor
  50  
  51           pu blic RestC lient()
  52           {
  53                //hack:  don't want  to load V AR module  at all ie  not create /bootstrap  VAR mod 
  54                //and he nce unity  not create  REST clas s
  55                if (!str ing.IsNull OrEmpty(Ho stName))
  56                {
  57                    _htt pClient.Ba seAddress  = new Uri( HostName);
  58                    _htt pClient.De faultReque stHeaders. Clear();
  59                    _htt pClient.De faultReque stHeaders. Connection Close = fa lse;
  60                    _htt pClient.De faultReque stHeaders. Accept.Add (
  61                         new MediaT ypeWithQua lityHeader Value("app lication/j son"));
  62                    Serv icePointMa nager.Find ServicePoi nt(_httpCl ient.BaseA ddress)
  63                         .Connectio nLeaseTime out = 60 *  1000; //  1 minute
  64                    Serv icePointMa nager.DnsR efreshTime out = 5 *  60 * 1000;   // 5 min utes
  65                }
  66           }
  67  
  68           #e ndregion
  69  
  70           #r egion priv ate method s
  71  
  72           pr ivate asyn c Task<Htt pResponseM essage> do AuthServic eGetAsync( string pat h)
  73           {
  74                return a wait _http Client.Get Async(Auth ServicesPa th + path) ;
  75           }
  76  
  77           pr ivate asyn c Task<Htt pResponseM essage> do AuthServic ePostAsync (string pa th, dynami c data)
  78           {
  79                return a wait _http Client.Pos tAsync(Aut hServicesP ath + path , data);
  80           }
  81  
  82           pr ivate stri ng generat eState()
  83           {
  84                return " scheduling -manager-"  + DateTim e.Now.Subt ract(new D ateTime(19 70, 1, 1,  0, 0, 0)). TotalSecon ds;
  85           }
  86  
  87           pr ivate asyn c Task<str ing> gener ateAuthURL Async()
  88           {
  89                var stat e = genera teState();
  90                var clie ntId = awa it ClientI dAsync();
  91                var redi rectUrl =  await Redi rectUriAsy nc();
  92                var auth orize_para ms = new s tring[] {
  93                    "res ponse_type =code",
  94                    "sta te=" + sta te,
  95                    "cli ent_id=" +  clientId,
  96                    "red irect_uri= " + redire ctUrl,
  97                    "sco pe=read"
  98                };
  99                return " provider/a uthorize?"  + String. Join("&",  authorize_ params);
  100           }
  101  
  102           //  RHH - 08/ 30/2018 -  Get a new  bearer tok en . . . h opefully
  103           pr ivate asyn c Task<boo l> Refresh Token()
  104           {
  105                _httpCli ent.Defaul tRequestHe aders.Auth orization  = null;
  106                var code  = await M akeAuthAtt emptAsync( );
  107                _token =  await Get TokenAsync (code);
  108                return ( _token !=  null);
  109           }
  110  
  111           //  RHH - 08/ 30/2018 -  Enum decri bing the w orkflow ba sed on the  response  status cod e
  112           pr ivate enum  responseF low { Retu rnResponse , ReturnNu ll, Retry  };
  113  
  114           //  RHH - 08/ 30/2018 -  Process th e response  code of a  httpClien t call
  115           pr ivate asyn c Task<res ponseFlow>  ProcessRe sponseCode (HttpRespo nseMessage  response)
  116           {
  117                switch ( response.S tatusCode)
  118                {
  119                    case  HttpStatu sCode.OK:
  120                    case  HttpStatu sCode.Foun d:
  121                         return res ponseFlow. ReturnResp onse;
  122                    case  HttpStatu sCode.Unau thorized:
  123                         var error  = await Pa rseJsonRes ponseAsync (response) ;
  124  
  125                         if ((error  == null)  || (error. error != " invalid_to ken"))
  126                             return  responseF low.Return Null;
  127  
  128                         var refres hed = awai t RefreshT oken();
  129  
  130                         if (!refre shed)
  131                             return  responseF low.Return Null;
  132  
  133                         return res ponseFlow. Retry;
  134                    defa ult:
  135                         return res ponseFlow. ReturnNull ;
  136                }
  137           }
  138  
  139           //  RHH - 08/ 31/2018 -  Uncomment  to test 40 1 Unauthor ized respo nse proces sing
  140           // int _getAs yncCount =  0;
  141  
  142           //  RHH - 08/ 30/2018 -  New privat e GetAsync  method to  handle re tries afte r unauthor ized \ inv alid token  response
  143           pr ivate asyn c Task<dyn amic> GetA sync(strin g requestU ri, bool s ecured = f alse)
  144           {
  145                int retr y = 0;
  146  
  147                do
  148                {
  149                    if ( secured)
  150                         _httpClien t.DefaultR equestHead ers.Author ization =  new Authen ticationHe aderValue( "Bearer",  _token.acc essToken);
  151  
  152                    // R HH - 08/31 /2018 - Co mment out  to test 40 1 Unauthor ized respo nse proces sing
  153                    Http ResponseMe ssage resp onse = awa it _httpCl ient.GetAs ync(reques tUri);
  154  
  155                    // R HH - 08/31 /2018 - Un comment to  test 401  Unauthoriz ed respons e processi ng
  156                    //Ht tpResponse Message re sponse; //  = await _ httpClient .GetAsync( requestUri );
  157  
  158                    //if  (_getAsyn cCount++ <  3)
  159                    //     response  = await _ httpClient .GetAsync( requestUri );
  160                    //el se
  161                    //{
  162                    //     response  = GetMock edUnauthor izedRespon se();
  163                    //     _getAsyn cCount = 0 ;
  164                    //}
  165  
  166                    swit ch (await  ProcessRes ponseCode( response))
  167                    {
  168                         case respo nseFlow.Re try:
  169                             break;
  170                         case respo nseFlow.Re turnNull:
  171                             return  null;
  172                         case respo nseFlow.Re turnRespon se:
  173                             return  response;
  174                    }
  175                } while  (retry++ <  RETRY_ATT EMPTS);
  176  
  177                return n ull;
  178           }
  179  
  180           //  RHH - 08/ 30/2018 -  New privat e PostAsyn c method t o handle r etries aft er unautho rized \ in valid toke n response
  181           pr ivate asyn c Task<dyn amic> Post Async(stri ng request Uri, Strin gContent c ontent)
  182           {
  183                int retr y = 0;
  184  
  185                do
  186                {
  187                    _htt pClient.De faultReque stHeaders. Authorizat ion = new  Authentica tionHeader Value("Bea rer", _tok en.accessT oken);
  188                    Http ResponseMe ssage resp onse = awa it _httpCl ient.PostA sync(reque stUri, con tent);
  189  
  190                    swit ch (await  ProcessRes ponseCode( response))
  191                    {
  192                         case respo nseFlow.Re try:
  193                             break;
  194                         case respo nseFlow.Re turnNull:
  195                             return  null;
  196                         case respo nseFlow.Re turnRespon se:
  197                             return  response;
  198                    }
  199                } while  (retry++ <  RETRY_ATT EMPTS);
  200  
  201                return n ull;
  202           }
  203  
  204           //  RHH - 08/ 30/2018 -  New privat e Internal DeleteAsyn c method t o handle r etries aft er unautho rized \ in valid toke n response
  205           pr ivate asyn c Task<dyn amic> Inte rnalDelete Async(stri ng request Uri)
  206           {
  207                int retr y = 0;
  208  
  209                do
  210                {
  211                    _htt pClient.De faultReque stHeaders. Authorizat ion = new  Authentica tionHeader Value("Bea rer", _tok en.accessT oken);
  212                    Http ResponseMe ssage resp onse = awa it _httpCl ient.Delet eAsync(req uestUri);
  213  
  214                    swit ch (await  ProcessRes ponseCode( response))
  215                    {
  216                         case respo nseFlow.Re try:
  217                             break;
  218                         case respo nseFlow.Re turnNull:
  219                             return  null;
  220                         case respo nseFlow.Re turnRespon se:
  221                             return  response;
  222                    }
  223                } while  (retry++ <  RETRY_ATT EMPTS);
  224  
  225                return n ull;
  226           }
  227  
  228           //  RHH - 08/ 30/2018 -  New privat e PutAsync  method to  handle re tries afte r unauthor ized \ inv alid token  response
  229           pr ivate asyn c Task<dyn amic> PutA sync(strin g requestU ri, String Content co ntent)
  230           {
  231                int retr y = 0;
  232  
  233                do
  234                {
  235                    _htt pClient.De faultReque stHeaders. Authorizat ion = new  Authentica tionHeader Value("Bea rer", _tok en.accessT oken);
  236                    Http ResponseMe ssage resp onse = awa it _httpCl ient.PutAs ync(reques tUri, cont ent);
  237  
  238                    swit ch (await  ProcessRes ponseCode( response))
  239                    {
  240                         case respo nseFlow.Re try:
  241                             break;
  242                         case respo nseFlow.Re turnNull:
  243                             return  null;
  244                         case respo nseFlow.Re turnRespon se:
  245                             return  response;
  246                    }
  247                } while  (retry++ <  RETRY_ATT EMPTS);
  248  
  249                return n ull;
  250           }
  251  
  252           #e ndregion
  253  
  254           #r egion IRes tClient
  255  
  256           pu blic strin g HostName
  257           {
  258                get
  259                {
  260                    if ( string.IsN ullOrEmpty (_hostName ))
  261                    {
  262                         _hostName  = Configur ationManag er.AppSett ings["vaos RestHost"] ;
  263                    }
  264                    retu rn _hostNa me;
  265                }
  266           }
  267  
  268           pu blic strin g AuthServ icesPath
  269           {
  270                get
  271                {
  272                    if ( string.IsN ullOrEmpty (_authServ icesPath))
  273                    {
  274                         _authServi cesPath =  Configurat ionManager .AppSettin gs["vaosAu thResource Path"];
  275                    }
  276                    retu rn _authSe rvicesPath ;
  277                }
  278           }
  279  
  280           pu blic strin g ClientRe sourcePath
  281           {
  282                get
  283                {
  284                    if ( string.IsN ullOrEmpty (_clientRe sourcePath ))
  285                    {
  286                         _clientRes ourcePath  = Configur ationManag er.AppSett ings["vaos Scheduling ResourcePa th"];
  287                    }
  288                    retu rn _client ResourcePa th;
  289                }
  290           }
  291  
  292           pu blic strin g AuthInfo Path
  293           {
  294                get
  295                {
  296                    retu rn "oauth/ info";
  297                }
  298           }
  299  
  300           pu blic strin g AuthToke nPath
  301           {
  302                get
  303                {
  304                    retu rn "oauth/ token";
  305                }
  306           }
  307  
  308           pu blic async  Task<stri ng> Client IdAsync()
  309           {
  310                if (stri ng.IsNullO rEmpty(_cl ientId))
  311                {
  312                    var  response =  await _ht tpClient.G etAsync(Cl ientResour cePath + A uthInfoPat h);
  313                    var  clientInfo  = await P arseJsonRe sponseAsyn c(response );
  314                    _cli entId = cl ientInfo.c lientId;
  315                    _red irectUri =  clientInf o.redirect Uri;
  316                }
  317                return _ clientId;
  318           }
  319  
  320           pu blic async  Task<stri ng> Redire ctUriAsync ()
  321           {
  322                if (stri ng.IsNullO rEmpty(_re directUri) )
  323                {
  324                    var  response =  await _ht tpClient.G etAsync(Cl ientResour cePath + A uthInfoPat h);
  325                    var  clientInfo  = await P arseJsonRe sponseAsyn c(response );
  326                    _cli entId = cl ientInfo.c lientId;
  327                    _red irectUri =  clientInf o.redirect Uri;
  328                }
  329                return _ redirectUr i;
  330           }
  331  
  332           //  01/09/201 9 - FF - R emoved dep endance on  SecureStr ing
  333           pu blic async  Task<bool > Authenti cateAsync( string acc essCode, s tring veri fyCode, st ring facil ityCode)
  334           {
  335                var logi nPassed =  await Logi nAsync(acc essCode, v erifyCode,  facilityC ode);
  336                if (logi nPassed) / /cookie ho lds login  state to a llow oAuth  handshake
  337                {
  338                    var  code = awa it MakeAut hAttemptAs ync();
  339                    _tok en = await  GetTokenA sync(code) ;
  340                    retu rn true;
  341                }
  342                return f alse;
  343           }
  344  
  345           pu blic async  Task<OAut hToken> Ge tTokenAsyn c(string c ode)
  346           {
  347                var redi rectUri =  await Redi rectUriAsy nc();
  348                var quer yParams =  "?" + "cod e=" + code  + "&redir ect_uri="  + redirect Uri;
  349                var resp onse = awa it _httpCl ient.GetAs ync(Client ResourcePa th + AuthT okenPath +  queryPara ms);
  350                HttpResp onseMessag e httpResp onseMessag e = (HttpR esponseMes sage)respo nse;
  351                var oaut hTokenDese rialize =  await Pars eJsonRespo nseAsync(r esponse);
  352                var toke n = new OA uthToken
  353                {
  354                    acce ssToken =  oauthToken Deserializ e.access_t oken,
  355                    refr eshToken =  oauthToke nDeseriali ze.refresh _token,
  356                    expi resIn = oa uthTokenDe serialize. expires_in
  357                };
  358                return t oken;
  359           }
  360  
  361           //  01/09/201 9 - FF - R emoved dep endance on  SecureStr ing
  362           pu blic async  Task<bool > LoginAsy nc(string  accessCode , string v erifyCode,  string fa cilityCode )
  363           {
  364                // RHH -  09/01/201 8 - If we  are loggin g is a sec ond time,  i.e first  login atte mpt failed , need to  get a new  session id , so remov e any prev ious sessi on id cook ie.
  365                if (_htt pClient.De faultReque stHeaders. Contains(" Cookie"))
  366                    _htt pClient.De faultReque stHeaders. Remove("Co okie");
  367  
  368                FormUrlE ncodedCont ent conten t = null;
  369                accessCo de.Decrypt SecureStri ng((ac) =>
  370                {
  371                    veri fyCode.Dec ryptSecure String((vc ) =>
  372                    {
  373                         content =  new FormUr lEncodedCo ntent(new[ ]
  374                         {
  375                             new Ke yValuePair <string, s tring>("j_ username",  ac),
  376                             new Ke yValuePair <string, s tring>("j_ password",  vc),
  377                             new Ke yValuePair <string, s tring>("fa cilityCode ", facilit yCode)
  378                         });
  379                    });
  380                });
  381  
  382                //TODO:  Failure Ch eck
  383                //always  returns a  redirect  which is 3 01 code
  384                //anythi ng other t han 301 -  bad
  385                //httpst atus = 301  and locat ion header  must not  end in ‘/d enied'  (l ocation va r)
  386                var pwSu bmitAttemp t = await  doAuthServ icePostAsy nc("provid er/securit y_check",  content);
  387                var head ers = pwSu bmitAttemp t.Headers;
  388                var loca tionHeader Enumerator  = pwSubmi tAttempt.H eaders.Get Values("Lo cation").G etEnumerat or();
  389                location HeaderEnum erator.Mov eNext();
  390                var loca tion = loc ationHeade rEnumerato r.Current;
  391                // 08/03 /2018 - RH H - This i s the firs t call tha t returns  a Session  ID, so we  want to re ad the Ses sion ID fr om the Res ponse and  add it to  the HttpCl ient Defau lt Headers .
  392                string c ookieStrin g = pwSubm itAttempt. Headers.Ge tValues("S et-Cookie" ).First(x  => x.Start sWith(SESS ION_ID_COO KIE_NAME)) ;
  393  
  394                if (!str ing.IsNull OrEmpty(co okieString ))
  395                {
  396                    _ses sionID = c ookieStrin g.Split('; ')[0].Spli t('=')[1];
  397                    _htt pClient.De faultReque stHeaders. Add("Cooki e", $"{SES SION_ID_CO OKIE_NAME} ={_session ID}");
  398                }
  399  
  400                return t rue;
  401           }
  402  
  403           pu blic async  Task<stri ng> MakeAu thAttemptA sync()
  404           {
  405                var auth Url = awai t generate AuthURLAsy nc();
  406                HttpResp onseMessag e loginAtt empt = awa it doAuthS erviceGetA sync(authU rl);
  407                var head ers = logi nAttempt.H eaders;
  408                var auth orizedLoca tionEnumer ator = log inAttempt. Headers.Ge tValues("L ocation"). GetEnumera tor();
  409                authoriz edLocation Enumerator .MoveNext( );
  410                var loca tionWithCo de = autho rizedLocat ionEnumera tor.Curren t;
  411                var quer yString =  new Uri(lo cationWith Code).Quer y;
  412                var quer yDictionar y = HttpUt ility.Pars eQueryStri ng(querySt ring);
  413                return q ueryDictio nary.Get(" code");
  414           }
  415  
  416           pu blic async  Task<dyna mic> Parse JsonRespon seAsync(Ht tpResponse Message re sponse)
  417           {
  418                if (resp onse == nu ll || resp onse.Conte nt == null )
  419                    retu rn null;
  420  
  421                var http Result = a wait respo nse.Conten t.ReadAsSt ringAsync( );
  422                return J sonConvert .Deseriali zeObject<d ynamic>(ht tpResult);
  423  
  424                // RHH -  08/30/201 8 - Moved  this to ne w async me thods to h andle unau thorized r esponse, s ee the pri vate GetAs ync method
  425                ////*zeb +switch 5/ 24/18 VSE- 530 add ha ndling of  HTTP error  condition s
  426                //switch  (response .StatusCod e)
  427                //{
  428                //    ca se HttpSta tusCode.OK :
  429                //    ca se HttpSta tusCode.Fo und:
  430                //         if (resp onse.Conte nt == null )
  431                //             retu rn null;
  432                //         else
  433                //         {
  434                //             var  httpResult  = await r esponse.Co ntent.Read AsStringAs ync();
  435                //             retu rn JsonCon vert.Deser ializeObje ct<dynamic >(httpResu lt);
  436                //         }
  437                //    ca se HttpSta tusCode.Un authorized :
  438                //         return n ull;
  439                //    de fault:
  440                //         return n ull;
  441                //    // case HttpS tatusCode. InternalSe rverError:
  442                //    // case HttpS tatusCode. Forbidden:
  443                //    // case HttpS tatusCode. BadRequest :
  444                //    // case HttpS tatusCode. BadGateway :
  445                //    // case HttpS tatusCode. NotFound:
  446                //    // case HttpS tatusCode. NoContent:
  447                //    //     return  null;
  448                //    // default:
  449                //    //     var ht tpResult =  await res ponse.Cont ent.ReadAs StringAsyn c();
  450                //    //     return  JsonConve rt.Deseria lizeObject <dynamic>( httpResult );
  451                //}
  452           }
  453  
  454           pu blic async  Task<dyna mic> GetAs ync(string  endpoint,  string qu eryParams  = "", bool  secured =  false)
  455           {
  456                // RHH -  08/30/201 8 - Moved  to the new  private G etAsync me thod
  457                //if (se cured)
  458                //{
  459                //    _h ttpClient. DefaultReq uestHeader s.Authoriz ation = ne w Authenti cationHead erValue("B earer", _t oken.acces sToken);
  460                //}
  461                if (!str ing.IsNull OrEmpty(qu eryParams) )
  462                {
  463                    quer yParams =  "?" + quer yParams;
  464                }
  465  
  466                // RHH -  08/30/201 8 - Call t he new pri vate GetAs ync method
  467                //HttpRe sponseMess age respon se = await  _httpClie nt.GetAsyn c(ClientRe sourcePath  + endpoin t + queryP arams);
  468                HttpResp onseMessag e response  = await G etAsync(Cl ientResour cePath + e ndpoint +  queryParam s, secured );
  469                return P arseJsonRe sponseAsyn c(response );
  470           }
  471  
  472           pu blic async  Task<dyna mic> PostA sync(strin g endpoint , dynamic  postData)
  473           {
  474                // RHH -  08/30/201 8 - Moved  to new pri vate PostA sync metho d
  475                //_httpC lient.Defa ultRequest Headers.Au thorizatio n = new Au thenticati onHeaderVa lue("Beare r", _token .accessTok en);
  476                StringCo ntent cont ent = null ;
  477  
  478                if (post Data != nu ll)
  479                    cont ent = new  StringCont ent(postDa ta, Encodi ng.UTF8, " applicatio n/json");
  480  
  481                // RHH -  08/31/201 8 - Replac ed with a  call to th e new priv ate PostAs ync call t o handle r etries for  unauthori zed \ inva lid token  responses
  482                //HttpRe sponseMess age respon se = await  _httpClie nt.PostAsy nc(ClientR esourcePat h + endpoi nt, conten t);
  483                HttpResp onseMessag e response  = await P ostAsync(C lientResou rcePath +  endpoint,  content);
  484                return a wait Parse JsonRespon seAsync(re sponse);
  485           }
  486  
  487           pu blic async  Task Dele teAsync(st ring endpo int)
  488           {
  489                // RHH -  08/30/201 8 - Moved  to new pri vate Inter nalDeleteA sync metho d
  490                //_httpC lient.Defa ultRequest Headers.Au thorizatio n = new Au thenticati onHeaderVa lue("Beare r", _token .accessTok en);
  491                // RHH -  08/31/201 8 - Replac ed with a  call to th e new priv ate Intern alDeleteAs ync call t o handle r etries for  unauthori zed \ inva lid token  responses
  492                //var re sponse = a wait _http Client.Del eteAsync(C lientResou rcePath +  endpoint);
  493                var resp onse = awa it Interna lDeleteAsy nc(ClientR esourcePat h + endpoi nt);
  494           }
  495  
  496           // *zeb+metho d 5/24/18  VSE-530 ad d method f or Put-typ e calls
  497           pu blic async  Task<dyna mic> PutAs ync(string  endpoint,  dynamic p utData)
  498           {
  499                // RHH -  08/30/201 8 - Moved  to new pri vate PutAs ync method
  500                //_httpC lient.Defa ultRequest Headers.Au thorizatio n = new Au thenticati onHeaderVa lue("Beare r", _token .accessTok en);
  501                var cont ent = new  StringCont ent(putDat a, Encodin g.UTF8, "a pplication /json");
  502                // RHH -  08/31/201 8 - Replac ed with a  call to th e new priv ate Intern alDeleteAs ync call t o handle r etries for  unauthori zed \ inva lid token  responses
  503                //return  await Par seJsonResp onseAsync( await _htt pClient.Pu tAsync(Cli entResourc ePath + en dpoint, co ntent));
  504                return a wait Parse JsonRespon seAsync(aw ait PutAsy nc(ClientR esourcePat h + endpoi nt, conten t));
  505           }
  506  
  507           #e ndregion
  508  
  509           #r egion mock s
  510  
  511           pr ivate Http ResponseMe ssage GetM ockedUnaut horizedRes ponse()
  512           {
  513                List<str ing> lines  = new Lis t<string>( )
  514                {
  515                    "{",
  516                    "  \ "error\":  \"invalid_ token\",",
  517                    $"   \"error_de scription\ ": \"Inval id token:  {_token.ac cessToken} \"",
  518                    "}"
  519                };
  520                HttpResp onseMessag e response  = new Htt pResponseM essage(Htt pStatusCod e.Unauthor ized)
  521                {
  522                    Reas onPhrase =  "Unauthor ized",
  523                    Vers ion = new  Version("1 .1"),
  524                    Cont ent = new  StringCont ent(string .Join("\n" , lines.To Array()))
  525                };
  526  
  527                //respon se.Headers .TransferE ncodingChu nked = tru e;
  528                
  529                //respon se.Headers .Add("Conn ection", " keep - ali ve");
  530                //respon se.Headers .Add("Cach e - Contro l", "no -  store, mus t - revali date, no -  cache, ma x - age =  0");
  531                //respon se.Headers .Add("Date ", DateTim e.Now.ToSt ring("ddd,  dd MMM yy yy HH':'mm ':'ss 'GMT '"));
  532                //respon se.Headers .Add("Serv er", "Apac he / 2.4.2 7");
  533                //respon se.Headers .Add("Serv er", "(Red  Hat)");
  534                //respon se.Headers .Add("Serv er", "Open SSL / 1.0. 2k - fips" );
  535                //respon se.Headers .Add("Prag ma", "no -  cache");
  536                //respon se.Headers .Add("Prag ma", "no -  cache");
  537                //respon se.Headers .Add("WWW  - Authenti cate", $"B earer real m = \"oaut h\", error  = \"inval id_token\" , error_de scription  = \"Invali d token: { _token.acc essToken}\ "");
  538                //respon se.Headers .Add("X -  XSS - Prot ection", " 1; mode =  block");
  539                //respon se.Headers .Add("X -  Content -  Type - Opt ions", "no sniff");
  540                //respon se.Headers .Add("X -  Powered -  By", "Serv let / 2.5  JSP / 2.1" );
  541                //respon se.Headers .Add("X -  Frame - Op tions", "D ENY");
  542                //respon se.Headers .Add("Set  - Cookie",  $"JSESSIO NID = {_se ssionID};  path =/; s ecure; Htt pOnly");
  543                  //response .Headers.A dd("Via",  "1.1  IP           ");
  544                //respon se.Content .Headers.C ontentType  = new Med iaTypeHead erValue("a pplication  / json");
  545                ////resp onse.Heade rs.Add("Co ntent - Ty pe", "appl ication /  json");
  546                //respon se.Headers .Add("Expi res", "0") ;
  547  
  548                return r esponse;
  549       }
  550  
  551           pu blic Task< dynamic> G etAsyncMoc ked(string  endpoint,  string qu eryParams  = "", bool  secured =  false)
  552           {
  553                HttpResp onseMessag e response  = null;
  554                if (endp oint.EndsW ith(@" / m essages"))
  555                {
  556                    var  parms = en dpoint.Spl it('/');
  557                    var  assigningA uthority =  parms[2];
  558                    var  patientId  = parms[3] ;
  559                    var  systemId =  parms[6];
  560                    var  requestId  = parms[6] ;
  561  
  562                    //"a ppointment -service/p atient/{as signing-au thority}/{ patient-id }/appointm ent-reques ts/system/ {system-id }/id/{appo intment-re quest-id}/ messages"
  563                    var  responseJs onContent  =
  564   @"{
  565       'size' : 1,
  566       'link' : [
  567           {
  568                'rel': ' self',
  569                'href':  'http://ms e-19886908 74.us-east -1.elb.ama zonaws.com /Schedulin gManagerSe rvice/v2/m 4/p0/rest/ appointmen t-service/ patient/#a ssiningAut hority#/#p atientId#/ appointmen t-requests /system/#s ystemId#/i d/#request Id#/messag es',
  570                'object- type': 'At omLink'
  571           }
  572       ],
  573       'objec t-type': ' SMAppointm entRequest Messages',
  574       'appoi ntmentRequ estMessage ': [
  575           {
  576                'link':  [
  577                    {
  578                         'rel': 'se lf',
  579                         'href': 'h ttp://mse- 1988690874 .us-east-1 .elb.amazo naws.com/S chedulingM anagerServ ice/v2/m4/ p0/rest/ap pointment- service/pa tient/#ass iningAutho rity#/#pat ientId#/ap pointment- requests/s ystem/#sys temId#/id/ #requestId #/messages ',
  580                         'object-ty pe': 'Atom Link'
  581                    }
  582                ],
  583                'object- type': 'SM Appointmen tRequestMe ssage',
  584                'dataIde ntifier':  {
  585                    'uni queId': '# requestId# ',
  586                    'sys temId': '# systemId#'
  587                },
  588                'patient Identifier ': {
  589                    'uni queId': '# patientId# ',
  590                    'ass igningAuth ority': '# assigningA uthority#'
  591                },
  592                'message Text': 'BA ZINGA! YOU  HAVE BEEN  TOTALLY M OCKED!',
  593                'message DateTime':  '#now#',
  594                'Appoint mentReques tId': '#re questId#',
  595                'senderI d': 'veter an1',
  596                'message Type': 've teran'
  597           },  
  598       ]
  599   }";
  600  
  601                    resp onseJsonCo ntent.Repl ace("#requ estId#", r equestId);
  602                    resp onseJsonCo ntent.Repl ace("#pati entId#", p atientId);
  603                    resp onseJsonCo ntent.Repl ace("#syst emId#", sy stemId);
  604                    resp onseJsonCo ntent.Repl ace("#assi ningAuthor ity#", ass igningAuth ority);
  605                    resp onseJsonCo ntent.Repl ace("#now# ", DateTim e.Now.ToSt ring("MM/d d/yyyy HH: mm:ss"));  //06/19/20 14 09:22:5 8
  606  
  607                    resp onse = new  HttpRespo nseMessage (HttpStatu sCode.OK)
  608                    {
  609                         Content =  new String Content(re sponseJson Content)
  610                    };
  611                }
  612                return P arseJsonRe sponseAsyn c(response );
  613           }
  614  
  615           #e ndregion m ocks
  616       }
  617   }