55. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 5/20/2019 8:52:19 AM 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.

55.1 Files compared

# Location File Last Modified
1 PPMS_Build_11_Sprint_3.zip\CIF B11S3\VA.PPMS.IWS\VA.PPMS.IWS\VA.PPMS.IWS.CreateResponseService CreateResponseService.cs Wed Apr 17 20:03:44 2019 UTC
2 PPMS_Build_11_Sprint_3.zip\CIF B11S3\VA.PPMS.IWS\VA.PPMS.IWS\VA.PPMS.IWS.CreateResponseService CreateResponseService.cs Thu May 16 15:22:06 2019 UTC

55.2 Comparison summary

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

55.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

55.4 Active regular expressions

No regular expressions were active.

55.5 Comparison detail

  1   using Hl7. Fhir.Model ;
  2   using Hl7. Fhir.Seria lization;
  3   using log4 net;
  4   using Micr osoft.Azur e.KeyVault ;
  5   using Micr osoft.Iden tityModel. Clients.Ac tiveDirect ory;
  6   using Micr osoft.Xrm. Sdk;
  7   using Syst em;
  8   using Syst em.Collect ions.Gener ic;
  9   using Syst em.Diagnos tics;
  10   using Syst em.IO;
  11   using Syst em.Linq;
  12   using Syst em.Net;
  13   using Syst em.Net.Htt p;
  14   using Syst em.Net.Htt p.Headers;
  15   using Syst em.Securit y.Cryptogr aphy.X509C ertificate s;
  16   using Syst em.Service Model;
  17   using Syst em.Text;
  18   using Syst em.Threadi ng.Tasks;
  19   using VA.P PMS.Contex t;
  20   using VA.P PMS.Contex t.Interfac e;
  21   using VA.P PMS.IWS.Co mmon;
  22   using VA.P PMS.IWS.Cr eateRespon seService. Interface;
  23   using VA.P PMS.IWS.Fu nctions.Co nfiguratio n.Interfac e;
  24   using VA.P PMS.IWS.Qu eueService .Interface ;
  25   using VA.P PMS.Provid erData;
  26  
  27   namespace  VA.PPMS.IW S.CreateRe sponseServ ice
  28   {
  29       public  class Cre ateRespons eService :  ICreateRe sponseServ ice
  30       {
  31           pr ivate read only ILog  _logger;
  32           pr ivate read only IIwsC onfigurati on _config uration;
  33           pr ivate read only IQueu eService _ queueServi ce;
  34           pr ivate read only IPpms Helper _pp msHelper;
  35           pr ivate read only IPpms ContextHel per _conte xtHelper;
  36  
  37           pu blic Creat eResponseS ervice(ILo g logger,  IIwsConfig uration co nfiguratio n, IQueueS ervice que ueService,  IPpmsHelp er ppmsHel per, IPpms ContextHel per contex tHelper)
  38           {
  39                _logger  = logger;
  40                _configu ration = c onfigurati on;
  41                _queueSe rvice = qu eueService ;
  42                _ppmsHel per = ppms Helper;
  43                _context Helper = c ontextHelp er;
  44           }
  45  
  46           pu blic async  Task<stri ng> Create Response(D asMessage  message)
  47           {
  48                _logger. Info($"@@@ @ INFO - S tart Creat eResponseS ervice.Cre ateRespons e @@@@");
  49  
  50                try
  51                {
  52                    var  batchId =  message.Co ntent;
  53  
  54                    // C reate XML  response f ile
  55                    var  response =  await Cre ateRespons eDocument( message);
  56  
  57                    _log ger.Info($ "@@@@ INFO  - End Mai n Create R esponse Se rvice for  BatchId: { batchId} @ @@@");
  58  
  59                    retu rn respons e;
  60                }
  61                catch (E xception e x)
  62                {
  63                    _log ger.Error( $"@@@@ ERR OR - There  was a pro blem with  the Create ResponseSe rvice. @@@ @", ex);
  64                    thro w new Ppms ServiceExc eption($"T here was a  problem w ith the Cr eateRespon seService. ", ex);
  65                }
  66           }
  67  
  68           pu blic async  Task<stri ng> Create ProviderPa yload(DasM essage mes sage)
  69           {
  70                _logger. Info($"@@@ @ INFO - S tart Creat eResponseS ervice.Cre ateProvide rPayload @ @@@");
  71  
  72                try
  73                {
  74                    // C reate XML  response f ile
  75                    var  response =  await Cre ateProvide rXmlDoc(me ssage);
  76  
  77                    _log ger.Info($ "@@@@ INFO  - End Mai n Create R esponse Se rvice for  BatchId: { Utilities. ValidateGu id(message .Content)}  @@@@");
  78  
  79                    retu rn respons e;
  80                }
  81                catch (E xception e x)
  82                {
  83                    _log ger.Error( $"@@@@ ERR OR - There  was a pro blem with  the Create ResponseSe rvice @@@@ ", ex);
  84                    thro w new Ppms ServiceExc eption($"T here was a  problem w ith the Cr eateRespon seService. ", ex);
  85                }
  86           }
  87  
  88           pu blic async  Task Noti fyOfRespon se(DasMess age messag e)
  89           {
  90                try
  91                {
  92                    // P arse base6 4 string t o extract  guid
  93                    var  shortGuid  = ShortGui d.Parse(me ssage.Cont ent);
  94                    var  batchId =  shortGuid. ToGuid().T oString();
  95  
  96                    var  batch = aw ait GetBat chById(bat chId);
  97                    if ( batch == n ull) throw  new PpmsS erviceExce ption("Una ble to fin d batch re cord.");
  98  
  99                    // R etrieve Re ceiverId f rom associ ated netwo rk
  100                    if ( batch.ppms _vaprovide rnetwork_b atch_netwo rk == null ) throw ne w PpmsServ iceExcepti on("Unable  to determ ine associ ated netwo rk.");
  101  
  102                    // S et header  values
  103                    mess age.Conver sationId =  batch.ppm s_conversa tionid;
  104                    mess age.Respon seConversa tionId = b atch.ppms_ transactio nid;
  105                    mess age.Receiv erId = bat ch.ppms_va providerne twork_batc h_network. ppms_short hand;
  106  
  107                    // G et URL pat hs from co nfiguratio n
  108                    var  baseUrl =  await _con figuration .GetPpmsRe sponseNoti ficationUr iAsync(mes sage.IsVaR eceiver);
  109                    var  requestUri  = await _ configurat ion.GetPpm sResponseP ostUriAsyn c(message. IsVaReceiv er);
  110  
  111                    _log ger.Info($ "Receiver:  {message. ReceiverId }, {messag e.Response Conversati onId}");
  112                    stri ng result  = "Success ";
  113                    if ( message.Is VaReceiver )
  114                    {
  115                         _logger.In fo($"--- I NFO: Post  to PIE");
  116                         var payloa d = await  CreateResp onseDocume nt(message );
  117                         //var ccnF ile = awai t CreatePr oviderXmlD oc(message );
  118                         //_logger. Info(ccnFi le);
  119                         //result =  await Pos tXmlToDas( message, p ayload, ba seUrl, req uestUri);
  120                    }
  121                    else
  122                    {
  123                         // Create  new guid w hen respon se to CCN/ TW
  124                         var docume ntRef = aw ait Create DocumentRe ference(ba tch.ppms_c onversatio nid);
  125                         //result =  await Pos tToDas(mes sage, docu mentRef, b aseUrl, re questUri);
  126                    }
  127  
  128                    if ( !string.Is NullOrEmpt y(result))
  129                    {
  130                         _logger.In fo($"-- No tifyOfResp onse - Upd ating batc h: {messag e.ToString ()}");
  131                         await _ppm sHelper.Up dateBatch( message, " Response n otificatio n sent.",  (int)ppms_ batch_Stat usCode.Rec eiverNotif ied);
  132                    }
  133                }
  134                catch (E xception e x)
  135                {
  136                    _log ger.Error( "CreateRes ponseServi ce.NotifyO fResponse:  Unable to  process r esponse.") ;
  137                    thro w new Ppms ServiceExc eption("Cr eateRespon seService. NotifyOfRe sponse: Un able to pr ocess resp onse.", ex );
  138                }
  139           }
  140  
  141           pr ivate asyn c Task<str ing> PostX mlToDas(Da sMessage m essage, st ring xmlCo ntent, str ing baseUr i, string  requestUri )
  142           {
  143                var clie nt = (Http WebRequest )WebReques t.Create($ "{baseUri} {requestUr i}");
  144                client.C ontentType  = "applic ation/xml" ;
  145                client.M ethod = "P OST";
  146                client.A ccept = "a pplication /xml";
  147                // Set D AS headers
  148                client.H eaders.Add ("X-Conver sationID",  message.C onversatio nId);
  149                client.H eaders.Add ("X-Routin gSenderID" , message. SenderId);
  150                client.H eaders.Add ("X-Routin gReceiverI Ds", messa ge.Receive rId);
  151                client.H eaders.Add ("X-Transa ctionID",  message.Tr ansactionI d);
  152  
  153                var useP ieSecurity  = Convert .ToBoolean (await _co nfiguratio n.GetUsePi eSecurity( ));
  154  
  155                if (useP ieSecurity )
  156                {
  157                    clie nt.PreAuth enticate =  true;
  158                    clie nt.Headers .Add("Auth orization" , "Bearer  " + await  GetToken2( ));
  159                }
  160  
  161                using (v ar streamW riter = ne w StreamWr iter(clien t.GetReque stStream() ))
  162                {
  163                    stre amWriter.W rite(xmlCo ntent);
  164                    stre amWriter.F lush();
  165                    stre amWriter.C lose();
  166                }
  167  
  168                var http Response =  (HttpWebR esponse)(a wait clien t.GetRespo nseAsync() );
  169                if (http Response ! = null) _l ogger.Info ($"Respons e: {httpRe sponse.Sta tusCode} -  {httpResp onse.Statu sDescripti on}");
  170                return " Success";
  171           }
  172  
  173           pr ivate asyn c Task<str ing> GetTo ken2()
  174           {
  175                var auth ority = aw ait _confi guration.G etAzureAdA uthority() ;
  176                var reso urce = awa it _config uration.Ge tPieAppReg Resource() ;
  177                var clie ntId = awa it _config uration.Ge tAddressVa lidationAp pId();
  178                var clie ntSecret =  await _co nfiguratio n.GetAddre ssValidati onSecret() ;
  179  
  180                var auth Context =  new Authen ticationCo ntext(auth ority);
  181                var clie ntCred = n ew ClientC redential( clientId,  clientSecr et);
  182                var resu lt = await  authConte xt.Acquire TokenAsync (resource,  clientCre d);
  183  
  184                if (resu lt == null ) throw ne w InvalidO perationEx ception("F ailed to o btain the  JWT token" );
  185  
  186                return r esult.Acce ssToken;
  187           }
  188  
  189           pr ivate asyn c Task<str ing> PostT oDas(DasMe ssage mess age, Docum entReferen ce content , string b aseUri, st ring reque stUri)
  190           {
  191                using (v ar client  = await Ge tHttpClien t())
  192                {
  193                    clie nt.BaseAdd ress = new  Uri(baseU ri);
  194                    // S et DAS hea ders
  195                    clie nt.Default RequestHea ders.Accep t.Clear();
  196                    clie nt.Default RequestHea ders.Accep t.Add(new  MediaTypeW ithQuality HeaderValu e("applica tion/json+ fhir"));
  197                    clie nt.Default RequestHea ders.Add(" X-Conversa tionID", m essage.Res ponseConve rsationId) ;
  198                    clie nt.Default RequestHea ders.Add(" X-RoutingS enderID",  message.Se nderId);
  199                    clie nt.Default RequestHea ders.Add(" X-RoutingR eceiverIDs ", message .ReceiverI d);
  200                    clie nt.Default RequestHea ders.Add(" X-Transact ionID", me ssage.Tran sactionId) ;
  201  
  202                    var  sout = new  FhirJsonS erializer( );
  203                    var  strDocRef  = sout.Ser ializeToSt ring(conte nt);
  204                    //_l ogger.Info ($"DEBUG D ocRef: {st rDocRef}") ;
  205                    var  docRef = n ew StringC ontent(str DocRef, En coding.Def ault, "app lication/j son+fhir") ;
  206  
  207                    docR ef.Headers .ContentTy pe.CharSet  = string. Empty;
  208  
  209                    var  response =  await cli ent.PostAs ync(reques tUri, docR ef);
  210  
  211                    if ( response.I sSuccessSt atusCode)  return "Su ccess";
  212  
  213                    thro w new Ppms ServiceExc eption($"E rror Posti ng Respons e Notifica tion to DA S. The err or is {res ponse.Stat usCode.ToS tring()}") ;
  214                }
  215           }
  216  
  217           pr ivate asyn c Task<Doc umentRefer ence> Crea teDocument Reference( string con versationI d)
  218           {
  219                // Const ruct call  back URL
  220                var docu mentPath =  await Get DocumentPa th(convers ationId);
  221                var cont ent = new  List<Docum entReferen ce.Content Component>
  222                {
  223                    new  DocumentRe ference.Co ntentCompo nent { Att achment =  new Attach ment { Con tentType =  "applicat ion/xml",  Url = docu mentPath }  }
  224                };
  225  
  226                // Set D ocumentRef erence pro perties
  227                var docR ef = new D ocumentRef erence
  228                {
  229                    Cust odian = ne w Resource Reference( "PPMS"),
  230                    Crea ted = Date Time.Now.T oString("s ", System. Globalizat ion.Cultur eInfo.Inva riantCultu re),
  231                    Inde xed = new  DateTimeOf fset(DateT ime.Now),
  232                    Stat us = Docum entReferen ceStatus.C urrent,
  233                    Cont ent = cont ent
  234                };
  235  
  236                return d ocRef;
  237           }
  238  
  239           pr ivate asyn c Task<str ing> GetDo cumentPath (string co nversation Id)
  240           {
  241                if (stri ng.IsNullO rEmpty(con versationI d))
  242                {
  243                    _log ger.Info($ "@@@@ INFO  - Paramet er invalid  for Conve rsationId  = {convers ationId} @ @@@");
  244                    thro w new Ppms ServiceExc eption("Un able to cr eate docum ent path,  parameter  invalid");
  245                }
  246  
  247                //{ rela tive - pat h}/ Binary  /[documen tURN] ? tr ansactionI D ={ uniqu e ID}
  248                var rela tivePathPa ttern = aw ait _confi guration.G etResponse DocumentPa thPatternA sync();
  249                return s tring.Form at(relativ ePathPatte rn, conver sationId);
  250           }
  251  
  252           pr ivate asyn c Task<ppm s_batch> G etBatchByI d(string b atchId)
  253           {
  254                var cont ext = awai t _context Helper.Get ContextAsy nc();
  255                var batc h = contex t.ppms_bat chSet.Firs tOrDefault (b => b.pp ms_batchId  == new Gu id(batchId ));
  256  
  257                LoadBatc hPropertie s(context,  batch);
  258  
  259                return b atch;
  260           }
  261  
  262           pu blic async  Task<ppms _batch> Ge tBatchByCo nversation Id(string  conversati onId, bool  loadPrope rties = tr ue)
  263           {
  264                var cont ext = awai t _context Helper.Get ContextAsy nc();
  265                var batc h = contex t.ppms_bat chSet.Firs tOrDefault (b => b.pp ms_convers ationid ==  conversat ionId);
  266  
  267                if (load Properties ) LoadBatc hPropertie s(context,  batch);
  268  
  269                return b atch;
  270           }
  271  
  272           pu blic async  Task<ppms _batch> Ge tBatchByTr ansactionI d(string t ransaction Id, bool l oadPropert ies = true )
  273           {
  274                var cont ext = awai t _context Helper.Get ContextAsy nc();
  275                var batc h = contex t.ppms_bat chSet.Firs tOrDefault (b => b.pp ms_transac tionid ==  transactio nId);
  276  
  277                LoadBatc hPropertie s(context,  batch);
  278  
  279                return b atch;
  280           }
  281  
  282           pu blic async  Task<ILis t<ppms_bat chdetailre sult>> Get BatchDetai lResultsBy Conversati onId(strin g conversa tionId)
  283           {
  284                var cont ext = awai t _context Helper.Get ContextAsy nc();
  285  
  286                var resu lts =
  287                    from  bdr in co ntext.ppms _batchdeta ilresultSe t
  288                    join  bd in con text.ppms_ batchdetai lSet
  289                         on bdr.ppm s_batchdet ail.Id equ als bd.ppm s_batchdet ailId
  290                    join  b in cont ext.ppms_b atchSet
  291                         on bd.ppms _batch.Id  equals b.I d
  292                    wher e b.ppms_c onversatio nid == con versationI d
  293                    sele ct bdr;
  294  
  295                return r esults.ToL ist();
  296           }
  297  
  298  
  299           pr ivate void  LoadBatch Properties (PpmsConte xt context , ppms_bat ch batch)
  300           {
  301                if (batc h == null)  throw new  PpmsServi ceExceptio n("Batch r ecord does  not exist ");
  302  
  303                context. LoadProper ty(batch,  new Relati onship("pp ms_batch_b atchdetail _batch"));
  304                context. LoadProper ty(batch,  new Relati onship("pp ms_vaprovi dernetwork _batch_net work"));
  305           }
  306  
  307           pu blic async  Task<stri ng> Create ResponseDo cument(Das Message qu eueMessage )
  308           {
  309                try
  310                {
  311                    if ( string.IsN ullOrEmpty (queueMess age.Conver sationId))
  312                    {
  313                         _logger.In fo($"@@@@  INFO - [Cr eateRespon seDocument ] Paramete r invalid  for item @ @@@");
  314                         return str ing.Empty;
  315                    }
  316  
  317                    var  conversati onId = que ueMessage. Conversati onId;
  318                    var  batch = aw ait GetBat chByConver sationId(c onversatio nId);
  319  
  320                    var  details =  batch.ppms _batch_bat chdetail_b atch;
  321                    IEnu merable<pp ms_batchde tail> ppms Batchdetai ls = detai ls as ppms _batchdeta il[] ?? de tails.ToAr ray();
  322                    if ( !ppmsBatch details.An y())
  323                    {
  324                         _logger.In fo($"@@@@  INFO - Det ails not f ound @@@@" );
  325                         return str ing.Empty;
  326                    }
  327  
  328                    _log ger.Info($ "@@@@ INFO  - Details  found @@@ @");
  329  
  330                    var  detailResu lts = awai t GetBatch DetailResu ltsByConve rsationId( conversati onId);
  331  
  332                    // C reate XML  doc
  333                    var  doc = new  ProviderRe sponses
  334                    {
  335                         Conversati onId = con versationI d,
  336                         ProviderRe sponse = n ew List<Pr oviderResp onse>()
  337                    };
  338  
  339                    // S et status  variables
  340                    int  i = 0;
  341                    int  chunkSize  = 500;
  342                    int  size = ppm sBatchdeta ils.Count( );
  343                    var  timer = ne w Stopwatc h();
  344                    time r.Start();
  345  
  346                    IEnu merable<pp ms_batchde tailresult > batchDet ailResults  = null;
  347                    // C apture bat ch details
  348                    fore ach (var d etail in p pmsBatchde tails)
  349                    {
  350                         i++;
  351  
  352                         // Provide r node
  353                         var provid er = new P roviderRes ponse
  354                         {
  355                             Provid erId = det ail.ppms_p roviderid,
  356                             Succes s = detail .GetAttrib uteValue<b ool>("ppms _isvalid")
  357                         };
  358  
  359                         // Set cor relation i d, if appr opriate
  360                         if (detail .ppms_prov ider != nu ll)
  361                         {
  362                             provid er.Correla tionId = d etail.ppms _provider. Id.ToStrin g();
  363                         }
  364  
  365                         // Retriev e batch de tail resul ts
  366                         if (detail Results !=  null && d etailResul ts.Any())
  367                             batchD etailResul ts = detai lResults.W here(x =>  x.ppms_bat chdetail.I d == detai l.Id);
  368                         else
  369                             batchD etailResul ts = null;
  370  
  371                         if (batchD etailResul ts != null )
  372                         {
  373                             // Cap ture batch  detail re sults
  374                             IEnume rable<ppms _batchdeta ilresult>  ppmsBatchd etailresul ts = batch DetailResu lts as ppm s_batchdet ailresult[ ] ?? batch DetailResu lts.ToArra y();
  375                             if (pp msBatchdet ailresults  != null & & ppmsBatc hdetailres ults.Any() )
  376                             {
  377                                 //  Initializ e results  list
  378                                 pr ovider.Res ults = new  Results {  Item = ne w List<Res ult>() };
  379  
  380                                 fo reach (var  detailRes ult in ppm sBatchdeta ilresults)
  381                                 {
  382                                      var resu lt = new R esult
  383                                      {
  384                                          Type  = detailR esult.ppms _entitytyp e,
  385                                          Id =  detailRes ult.ppms_n ame,
  386                                          Succ ess = deta ilResult.p pms_isvali d.HasValue  && detail Result.ppm s_isvalid. Value
  387                                      };
  388  
  389                                      if (resu lt.Type ==  "Provider Service")
  390                                      {
  391                                          resu lt.Correla tionId = d etailResul t.Id.ToStr ing();
  392                                      }
  393  
  394                                      if (!res ult.Succes s)
  395                                      {
  396                                          resu lt.Header  = detailRe sult.ppms_ result;
  397                                          resu lt.Message  = detailR esult.ppms _message;
  398                                      }
  399  
  400                                      provider .Results.I tem.Add(re sult);
  401                                 }
  402                             }
  403                         }
  404  
  405                         // Add to  list of pr oviders
  406                         doc.Provid erResponse .Add(provi der);
  407  
  408                         // Log sta tus
  409                         if (i % ch unkSize ==  0 || i ==  size)
  410                         {
  411                             _logge r.Info($"P rocessing  response:  {i} of {si ze} [{time r.Elapsed} ]");
  412                         }
  413                    }
  414  
  415                    _log ger.Info($ "Response  processing  complete.  [{timer.E lapsed}]") ;
  416                    time r.Stop();
  417  
  418                    // C reate resp onse packe t
  419                    retu rn await C onvertResp onseToXml( doc);
  420                }
  421                catch (F aultExcept ion<Organi zationServ iceFault>  ex)
  422                {
  423                    _log ger.Error( $"@@@@ Cre ateRespons eService E RROR - Fau lt: {ex} @ @@@", ex);
  424                    thro w;
  425                }
  426                catch (E xception e x)
  427                {
  428                    _log ger.Error( $"@@@@ Cre ateRespons eService E RROR - Exc eption: {e x} @@@@",  ex);
  429                    thro w;
  430                }
  431           }
  432  
  433           pu blic async  Task<stri ng> Create ProviderXm lDoc(DasMe ssage queu eMessage)
  434           {
  435                try
  436                {
  437                    if ( string.IsN ullOrEmpty (queueMess age.Conten t))
  438                    {
  439                         _logger.In fo($"@@@@  INFO - Bat ch ID not  provided.  @@@@");
  440                         return str ing.Empty;
  441                    }
  442  
  443                    var  shortGuid  = ShortGui d.Parse(qu eueMessage .Content);
  444                    var  batchId =  shortGuid. ToGuid().T oString();
  445                    var  batch = aw ait GetBat chById(bat chId);
  446  
  447                    retu rn await E xportBatch ToXml(batc h);
  448                }
  449                catch (E xception e x)
  450                {
  451                    _log ger.Info($ "!!!! ERRO R - Error  occured cr eated prov ider XML d ocument. ! !!!", ex);
  452                }
  453  
  454                return s tring.Empt y;
  455           }
  456  
  457           pr ivate asyn c Task<str ing> Conve rtResponse ToXml(Prov iderRespon ses respon se)
  458           {
  459                var pack et = await  _configur ation.GetS chemaProfi leAsync(Sc hemaOption s.SchemaPr ofiles.Res ponse);
  460  
  461                var pref ix = packe t.Prefix;
  462                var name Space = pa cket.Names pace;
  463  
  464                return U tilities.S erializeIn stance(res ponse, pre fix, nameS pace);
  465           }
  466  
  467           pr ivate asyn c Task<str ing> Expor tBatchToXm l(ppms_bat ch batch)
  468           {
  469                Context. Account ac count = nu ll;
  470  
  471                if (batc h.ppms_bat ch_batchde tail_batch  == null)  return str ing.Empty;
  472  
  473                var prov iders = ne w List<Pro vider>();
  474  
  475                foreach  (var item  in batch.p pms_batch_ batchdetai l_batch)
  476                {
  477                    acco unt = awai t GetProvi der(item.p pms_provid er.Id);
  478                    if ( account !=  null)
  479                    {
  480                         // convert  provider  to XML
  481                         providers. Add(ToProv ider(accou nt));
  482                    }
  483                }
  484  
  485                  var xml =  Utilities. SerializeI nstance(pr oviders, " p", "https :// DNS . URL /exchange/ ccn/1.0");
  486                xml = xm l.Replace( "ArrayOfPr ovider", " Providers" );
  487  
  488                return x ml;
  489           }
  490  
  491           pr ivate asyn c Task<Con text.Accou nt> GetPro vider(Guid  providerI d)
  492           {
  493                var cont ext = awai t _context Helper.Get ContextAsy nc();
  494                var enti ty = conte xt.Account Set.FirstO rDefault(b  => b.Id = = provider Id);
  495                if (enti ty == null ) throw ne w PpmsServ iceExcepti on("Batch  record doe s not exis t");
  496  
  497                LoadProv iderProper ties(entit y, context );
  498  
  499                return e ntity;
  500           }
  501  
  502           pr otected vo id LoadPro viderPrope rties(Enti ty entity,  PpmsConte xt context )
  503           {
  504                if (enti ty == null  || contex t == null)  return;
  505  
  506                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ providerid entifier_P rovider");
  507                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ providerse rvice");
  508                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ boardcerti fication") ;
  509                context. LoadProper ty(entity,  "ppms_acc ount_organ izationaut horizedoff icial");
  510                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ otherprovi deridentif ier");
  511                context. LoadProper ty(entity,  "contact_ customer_a ccounts");
  512                context. LoadProper ty(entity,  "ppms_acc ount_provi derlicensu re");
  513                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ othername" );
  514                context. LoadProper ty(entity,  "ppms_acc ount_ppms_ providerta xonomy");
  515                context. LoadProper ty(entity,  "ppms_acc ount_deasc hedulepriv ilege");
  516                context. LoadProper ty(entity,  "ppms_acc ount_provi dernetwork id");
  517           }
  518  
  519           pr ivate Prov ider ToPro vider(Cont ext.Accoun t account)
  520           {
  521                if (acco unt == nul l) return  null;
  522  
  523                var prov ider = new  Provider( );
  524  
  525                // Map p roperties
  526                provider .Email = a ccount.EMa ilAddress1 ;
  527                provider .Phone = a ccount.Tel ephone1;
  528                provider .Fax = acc ount.Fax;
  529  
  530                // Addre ss
  531                var addr ess = new  ProviderDa ta.Address ();
  532                address. Address1 =  account.A ddress1_Li ne1;
  533                address. Address2 =  account.A ddress1_Li ne2;
  534                address. Address3 =  account.A ddress1_Li ne3;
  535                address. City = acc ount.Addre ss1_City;
  536                address. State = ac count.Addr ess1_State OrProvince ;
  537                address. PostalCode  = account .Address1_ PostalCode ;
  538                address. County = a ccount.Add ress1_Coun ty;
  539  
  540                provider .Address =  address;
  541  
  542                // NPIs
  543                var npis  = new Lis t<Npi>();
  544                var npi  = new Npi( );
  545                npi.Numb er = accou nt.ppms_Pr oviderIden tifier;
  546                provider .Npis = ne w Npis() {  Item = np is };
  547  
  548                // Speci alties
  549                if (acco unt.ppms_a ccount_ppm s_provider taxonomy ! = null)
  550                {
  551                    var  specialtie s = new Li st<Taxonom y>();
  552                    fore ach (var i tem in acc ount.ppms_ account_pp ms_provide rtaxonomy)
  553                    {
  554                         specialtie s.Add(new  Taxonomy()  { CodedSp ecialty =  item.ppms_ codedspeci alty });
  555                    }
  556                    prov ider.Speci alties = n ew Special ties() { I tem = spec ialties };
  557                }
  558  
  559                // Name
  560                var indi vidual = n ew Individ ual();
  561                var name s = accoun t.Name.Spl it(',');
  562                individu al.FirstNa me = names [0].Trim() ;
  563                individu al.LastNam e = names[ 1].Trim();
  564                individu al.MiddleN ame = "";
  565  
  566                // DEA N umbers
  567                if (acco unt.ppms_a ccount_dea schedulepr ivilege !=  null)
  568                {
  569                    var  deaNumbers  = new Lis t<DeaSched ulePrivile ge>();
  570                    fore ach (var i tem in acc ount.ppms_ account_de aschedulep rivilege)
  571                    {
  572                         deaNumbers .Add(new D eaSchedule Privilege( ) { DeaNum ber = item .ppms_dean umber });
  573                    }
  574                    indi vidual.Dea Numbers =  new DeaSch edulePrivi leges() {  Item = dea Numbers };
  575                }
  576  
  577                // Set p rovider ty pe
  578                var prov iderType =  new Provi derType();
  579                provider Type.Item  = individu al;
  580  
  581                provider .Type = pr oviderType ;
  582  
  583                return p rovider;
  584           }
  585  
  586           #r egion Cert s
  587  
  588           pu blic async  Task<Http Client> Ge tHttpClien t()
  589           {
  590                await Ta sk.Run(()  => { });
  591                var clie ntHandler  = new Http ClientHand ler();
  592                clientHa ndler.Clie ntCertific ates.Add(a wait GetCe rtKeyVault ());
  593  
  594                return n ew HttpCli ent(client Handler);
  595           }
  596  
  597           pr ivate asyn c Task<X50 9Certifica te2> GetCe rtKeyVault ()
  598           {
  599                var keyV aultClient  = new Key VaultClien t(GetToken );
  600                var resu lt = await  keyVaultC lient.GetS ecretAsync (await _co nfiguratio n.GetDasCe rtUrl());
  601  
  602                if (resu lt == null ) throw ne w InvalidO perationEx ception("F ailed to o btain the  certificat e from Key  Vault");
  603  
  604                var secr et = Conve rt.FromBas e64String( result.Val ue);
  605                return n ew X509Cer tificate2( secret, (s tring)null );
  606           }
  607  
  608           pr ivate asyn c Task<str ing> GetTo ken(string  authority , string r esource, s tring scop e)
  609           {
  610                var auth Context =  new Authen ticationCo ntext(auth ority);
  611                var clie ntCred = n ew ClientC redential( await _con figuration .GetDasApp Id(), awai t _configu ration.Get DasSecret( ));
  612                var resu lt = await  authConte xt.Acquire TokenAsync (resource,  clientCre d);
  613  
  614                if (resu lt == null ) throw ne w InvalidO perationEx ception("F ailed to o btain the  token to r etrieve ce rtificate" );
  615  
  616                return r esult.Acce ssToken;
  617           }
  618  
  619           #e ndregion
  620       }
  621   }