PageRenderTime 43ms CodeModel.GetById 3ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 1ms

/EntLib/CE.WebServiceClient.DRHub/DRHubClient.cs

https://bitbucket.org/jeffmccommas/acex
C# | 947 lines | 720 code | 136 blank | 91 comment | 55 complexity | cef5466f1b324ba15bb97f7376975088 MD5 | raw file
  1using CE.ContentModel;
  2using CE.ContentModel.ContentCache;
  3using CE.NotificationManager.Entities;
  4using Newtonsoft.Json.Linq;
  5using System;
  6using System.Collections.Generic;
  7using System.Configuration;
  8using System.Data;
  9using System.Data.SqlClient;
 10using System.IO;
 11using System.Linq;
 12using System.Net;
 13using System.Net.Http;
 14using System.Net.Http.Headers;
 15using System.Text;
 16using System.Threading;
 17using System.Threading.Tasks;
 18using System.Xml;
 19using System.Xml.Linq;
 20using System.Xml.Serialization;
 21
 22namespace CE.WebServiceClient.DRHub
 23{
 24    public class DRHubClient : IDRHub
 25    {
 26        #region "private variables"
 27        private DRHubConfig _config;
 28        private readonly NLogger.ASyncLogger _logger;
 29        private string _environment;
 30        private readonly int _clientId;
 31        private bool _configSetUp;
 32        private string _tokenId;
 33        private string _cookieName;
 34        //private bool _simulation;
 35        //private int _simulationInterval;
 36        #endregion
 37
 38        #region "private const"
 39        private const string PjmNoticationEvent = "PJM Notification Event";
 40        private const string SeverityHigh = "High";
 41        private const string SeverityMedium = "Medium";
 42        private const string SeverityLow = "Low";
 43        private const string CatagoryPoll = "Poll";
 44        private const string CatagoryPingPoll = "Ping Poll";
 45        private const string CatagoryAck = "Acknowledge";
 46        private const string EventBegin = "Begins";
 47        private const string EventEnd = "Ends";
 48        private const string MsgPollEvents = "PJM Poll Event";
 49        private const string MsgAckEvents = "Acknowledge Event";
 50        private const string MsgProcessResponse = "Process PJM Response";
 51        private const string MsgSimulateEvents = "PJM Event Simulation";
 52        private const string MsgProcessEvents = "Process PJM Events";
 53        private const string MsgEventsReceived = "Event Received";
 54        private const string MsgRequest = "Request";
 55        private const string MsgResponse = "Response";
 56        private const string MsgPingEvents = "Ping Poll Event";
 57        private const string MsgNoEvent = "No Event";
 58        private const string MsgNoTeamNameMapping = "No Team Name Mapping for Registration ID";
 59        private const string HeaderVerbGet = "get";
 60        private const string HeaderVerbChange = "change";
 61        private const string HeaderNounEvent = "event";
 62        private const string HeaderRevision = "1.0";
 63        private const string HeaderSource = "OECSP";
 64        private const string RequestOptionUnAck = "unack";
 65        private const string RequestOptionAck = "ack";
 66        private const string PayloadFormat = "XML";
 67        private const string ReplyCodeOkay = "ok";
 68        private const string ReplyCodeWarning = "warning";
 69        private const string ReplyCodeFatal = "fatal";
 70        private const string ErrorCode = "4005";
 71        private const int DefaultMaxRetry = 5;
 72        private const string MsgLeadTimeWarning = "Invalid Lead Time, default to Quick_30";
 73
 74        
 75        #endregion
 76
 77        public DRHubClient(int clientId)
 78        {
 79            //_environment = environment;
 80            _clientId = clientId;
 81            Console.WriteLine("Initiate Logger" );
 82            _logger = new NLogger.ASyncLogger(clientId, _environment);            
 83             GetDRHubConfig(clientId);
 84        }
 85
 86        #region "public methods"
 87        /// <summary>
 88        /// call the api to poll events
 89        /// </summary>
 90        /// <returns></returns>
 91        public EventsCollection PollEvents()
 92        {
 93            EventsCollection eventsCol = null;
 94//#if DEBUG
 95//            _config.Simulation = true;
 96//#endif
 97            if (_configSetUp)
 98            {
 99                if (_config.Simulation)
100                {
101                    var simulate = false;
102
103                    var currentTime = DateTime.Now;
104                    switch (_config.SimulationInterval)
105                    {
106                        case 5:
107                            if (currentTime.Minute % 5 == 0)
108                                simulate = true;
109                            break;
110                        case 15:
111                            if (currentTime.Minute % 15 == 0)
112                                simulate = true;
113                            break;
114                        case 30:
115                            if (currentTime.Minute % 30 == 0)
116                                simulate = true;
117                            break;
118                        case 60:
119                            if (currentTime.Minute % 60 == 0)
120                                simulate = true;
121                            break;
122                        case 1440:
123                            if (currentTime.TimeOfDay.Ticks == 0)
124                                simulate = true;
125                            break;
126                    }
127                    // simulate poll pjm events
128                    eventsCol = Simulate(simulate ? GetEventsResponseString() : GetNoEventResponseString());
129                }
130                else
131                {
132                    // poll pjm events
133                    eventsCol = Poll(0);
134                }
135            }
136            return eventsCol;
137        }
138        /// <summary>
139        /// call api to acknowledge events
140        /// </summary>
141        /// <param name="events"></param>
142        /// <param name="retry"></param>
143        public void AcknowledgeEvents(EventsCollection events, int retry)
144        {
145            if (_configSetUp)
146            {
147                
148                
149                string ackEventUri = _config.ServiceUrl + _config.AcknowledgeEventsAction;
150                HttpClient client = new HttpClient();
151                //var authCTS = new CancellationTokenSource();
152                //Task task = Task.Run(async () =>
153                //{
154                    client = GetAuthDRHubClient(ackEventUri, CatagoryAck);
155                //}, authCTS.Token);
156                //authCTS.CancelAfter(3000);
157                //await task; 
158                try
159                {
160                    Console.WriteLine("{0} {1}", MsgAckEvents, EventBegin);
161                    _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgAckEvents, EventBegin));
162
163
164                    // create payload events and convert into xml doc
165                    var acknowledgementPayloadStr = events.Xml;
166                    
167                    var xmlDoc = new XmlDocument();
168                    xmlDoc.LoadXml(acknowledgementPayloadStr);
169
170
171
172                    var httpContent = new StringContent(acknowledgementPayloadStr, Encoding.UTF8, "application/xml");
173
174
175
176
177
178
179                    // log the request info  TODO: Is this the right thing to log?
180                    _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, acknowledgementPayloadStr, string.Empty, MsgRequest);
181
182                    // TODO: #DRHUB change call to get response from REST
183                    Console.WriteLine("Send Request");
184                    HttpResponseMessage responseFromPost = new HttpResponseMessage();
185                    string responseContent = string.Empty;
186                    //var cts = new CancellationTokenSource();
187                    //Task responseTask = Task.Run(async () =>
188                    //{
189                        responseFromPost = client.PutAsync(new Uri(ackEventUri), httpContent).Result;
190                        //responseFromPost.EnsureSuccessStatusCode();
191                        responseContent = responseFromPost.Content.ReadAsStringAsync().Result;
192                    //}, cts.Token);
193                    //cts.CancelAfter(3000);
194                    //await responseTask;
195
196                    
197                    Console.WriteLine("Response Received");
198
199
200                    if (!responseFromPost.IsSuccessStatusCode)
201                    {
202                        string errorMsg = responseFromPost.StatusCode.ToString() + "  " + responseFromPost.ReasonPhrase;
203                        _logger.Error(CatagoryAck, SeverityHigh, PjmNoticationEvent, acknowledgementPayloadStr, responseContent, string.Format("Response fatal - {0}", errorMsg));
204                        throw new Exception(string.Format("Response fatal - {0}", errorMsg));
205                    }
206                    else
207                    {
208                        //log the response info
209                        Console.WriteLine(responseContent);
210                        _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, string.Empty, responseContent, MsgResponse);
211                    }
212                    _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgAckEvents, EventEnd));
213                    Console.WriteLine("{0} {1}", MsgAckEvents, EventEnd);
214
215                }
216                catch (Exception ex)
217                {
218                    _logger.ErrorException(CatagoryAck, SeverityHigh, PjmNoticationEvent, ex);
219                    if (retry < _config.MaxRetry)
220                    {
221                        retry++;
222                        _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgAckEvents, EventEnd));
223#if DEBUG
224                        Console.WriteLine("{0} {1}", MsgAckEvents, EventEnd);
225#endif
226                        Task.Delay(_config.RetryWaitDuration);
227                        _logger.Info(CatagoryAck, SeverityMedium, PjmNoticationEvent, string.Format("Retry Attempt: {0}", retry));
228#if DEBUG
229                        Console.WriteLine("Retry Attempt: {0}", retry);
230#endif
231                        AcknowledgeEvents(events, retry);
232                    }
233                    else
234                    {
235                        _logger.Info(CatagoryAck, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgAckEvents, EventEnd));
236                        Console.WriteLine("{0} {1}", MsgAckEvents, EventEnd);
237                        _logger.EmailErrorException(CatagoryAck, SeverityHigh, PjmNoticationEvent, ex);
238                        throw;
239                    }
240
241
242                    //_logger.Error(catagoryAck, string.Empty, string.Empty, ex.Message);
243                }
244                finally
245                {
246                    client.Dispose();
247                }
248                return;
249            }
250        }
251        
252        /// <summary>
253        /// for standalone DRHUB REST service pinging
254        /// </summary>
255        public void Ping(int retry)
256        {
257            string getEventUri = _config.ServiceUrl + _config.GetEventsAction;
258            HttpClient client = new HttpClient();
259            //var authCTS = new CancellationTokenSource();
260            //Task task = Task.Run(async () =>
261            //{
262                client = GetAuthDRHubClient(getEventUri, CatagoryPingPoll);
263            //}, authCTS.Token);
264            //authCTS.CancelAfter(3000);
265            //await task;
266
267           
268            try
269            {
270                Console.WriteLine("{0} {1}", MsgPingEvents, EventBegin);
271                _logger.Info(CatagoryPingPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPingEvents, EventBegin));
272#if DEBUG
273                Console.WriteLine("Send Request");
274#endif
275                HttpResponseMessage restResponse = client.GetAsync(getEventUri).Result;
276#if DEBUG
277                Console.WriteLine("Response Received");
278#endif
279                _logger.Info(CatagoryPingPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} Succeeded", MsgPingEvents));
280                Console.WriteLine("{0} Succeeded", MsgPingEvents);
281
282                _logger.Info(CatagoryPingPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPingEvents, EventEnd));
283                Console.WriteLine("{0} {1}", MsgPingEvents, EventEnd);
284            }
285            catch (Exception ex)
286            {
287                _logger.ErrorException(CatagoryPingPoll, SeverityMedium, PjmNoticationEvent, ex);
288                if (retry < _config.MaxRetry)
289                {
290                    retry++;
291                    _logger.Info(CatagoryPingPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPingEvents, EventEnd));
292#if DEBUG
293                    Console.WriteLine("{0} {1}", MsgPingEvents, EventEnd);
294#endif
295                    Task.Delay(_config.RetryWaitDuration);
296                    _logger.Info(CatagoryPingPoll, SeverityMedium, PjmNoticationEvent, string.Format("Retry Attempt: {0}", retry));
297                    Console.WriteLine("Retry Attempt: {0}", retry);
298                    Ping(retry);
299                }
300                else
301                {
302                    _logger.Info(CatagoryPingPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPingEvents, EventEnd));
303                    Console.WriteLine("{0} {1}", MsgPingEvents, EventEnd);
304                    _logger.EmailErrorException(CatagoryPingPoll, SeverityMedium, PjmNoticationEvent, ex);
305                    throw;
306                }
307            }
308            finally
309            {
310                client.Dispose();
311            }
312        }
313        #endregion
314
315        #region "private methods"
316        private EventsCollection Poll(int retry)
317        {
318            string getEventUri = _config.ServiceUrl + _config.GetEventsAction;
319            //var authCTS = new CancellationTokenSource();
320            HttpClient client = new HttpClient();
321            //Task task = Task.Run(async () =>
322            //{
323                client = GetAuthDRHubClient(getEventUri, CatagoryPoll);
324            //}, authCTS.Token);
325            //authCTS.CancelAfter(3000);
326            //await task;
327
328            EventsCollection events = new EventsCollection();
329            try
330            {
331                Console.WriteLine("{0} {1}", MsgPollEvents, EventBegin);
332                _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPollEvents, EventBegin));
333
334                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
335                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
336                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
337                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
338                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
339                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("sdch"));
340                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
341
342                var cts = new CancellationTokenSource();
343                HttpResponseMessage restResponse = new HttpResponseMessage();
344                //Task responseTask = Task.Run(async () =>
345                //{
346                    restResponse = client.GetAsync(getEventUri).Result;
347                    restResponse.EnsureSuccessStatusCode();
348
349
350                    events = ProcessResponse(restResponse);
351                //}, cts.Token);
352                //cts.CancelAfter(3000);
353                //await responseTask;
354
355               
356                
357            }
358            catch (Exception ex)
359            {
360
361                if (retry < _config.MaxRetry)
362                {
363                    retry++;
364                    Console.WriteLine("{0} {1}", MsgPollEvents, EventEnd);
365                    _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPollEvents, EventEnd));
366                    Task.Delay(_config.RetryWaitDuration);
367#if DEBUG
368                    Console.WriteLine("Retry Attempt: {0}", retry);
369#endif
370            _logger.Info(CatagoryPoll, SeverityMedium, PjmNoticationEvent, string.Format("Retry Attempt: {0}", retry));
371                    events = Poll(retry);
372
373                }
374                else
375                {
376                    var currentTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, "Eastern Standard Time");
377
378                    if (currentTime.TimeOfDay >= Convert.ToDateTime("10:00").TimeOfDay && currentTime.TimeOfDay <= Convert.ToDateTime("20:30").TimeOfDay)
379                    {
380                        _logger.ErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
381                        _logger.EmailErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
382                    }
383                    else
384                    {
385                        _logger.ErrorException(CatagoryPoll, SeverityLow, PjmNoticationEvent, ex);
386                        _logger.EmailErrorException(CatagoryPoll, SeverityLow, PjmNoticationEvent, ex);
387                    }
388
389                    //_logger.Error(catagoryPoll, string.Empty, string.Empty, ex.Message);
390                    _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgPollEvents, EventEnd));
391                    Console.WriteLine("{0} {1}", MsgPollEvents, EventEnd);
392                    throw;
393                }
394
395
396            }
397            finally
398            {
399                client.Dispose();
400            }
401
402            return events;
403        }
404
405        private void GetDRHubConfig(int clientId)
406        {
407            var cacheKey = string.Empty;
408            Console.WriteLine("Initiate content model factory contentful");
409            var cf = new ContentModelFactoryContentful();
410            Console.WriteLine("Create ContentCacheProvider");
411            var contentCashProvider = ContentCacheProviderFactory.CreateContentCacheProvider();
412
413            try
414            {
415                Console.WriteLine("Create/Retrieve DRHub Config Begins");
416                var contentRepository = cf.CreateContentRepository(clientId);
417                Console.WriteLine("Get Content Eviornment");
418                _environment = contentRepository.GetContentEnvironment();
419                _logger.Envirnoment = _environment;
420                Console.WriteLine("Create cache Key");
421                // TODO: HOW DO WE CHANGE THE CACHE KEY HERE TO REMOVE THE ELRS reference?
422                cacheKey = string.Format("ElrsConfig_{0}_{1}", clientId, _environment);
423                Console.WriteLine("Get cached config");
424                _config = (DRHubConfig)contentCashProvider.Get(cacheKey);
425                
426            }
427            catch
428            {
429                _config = null;
430            }
431            if (_config != null)
432            {
433                _configSetUp = true;
434                Console.WriteLine("Create/Retrieve DRHub Config Ends");
435                return;
436            }
437
438            try
439            {
440                Console.WriteLine("No cache, create new config");
441                _config = new DRHubConfig();
442                Console.WriteLine("Create ContentProvider");
443                var cp = cf.CreateContentProvider(clientId);
444                var configurationList = cp.GetContentConfiguration(ContentCategory.Notification.ToString().ToLower(), string.Empty);
445                if (configurationList.Any())
446                {
447                    //_config.WebServiceEndPoint = configurationList.Find(item => item.Key == "webserviceclient.elrs.endpoint").Value;
448                    _config.Username = configurationList.Find(item => item.Key == "webserviceclient.drhub.username").Value;
449                    _config.Password = configurationList.Find(item => item.Key == "webserviceclient.drhub.password").Value;
450                    _config.EventTypes = configurationList.Find(item => item.Key == "webserviceclient.drhub.eventtypes").Value
451                            .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
452                    _config.ServiceUrl = configurationList.Find(item => item.Key == "webserviceclient.drhub.serviceurl").Value;
453                    _config.GetEventsAction = configurationList.Find(item => item.Key == "webserviceclient.drhub.geteventsaction").Value;
454                    _config.AcknowledgeEventsAction = configurationList.Find(item => item.Key == "webserviceclient.drhub.ackeventsaction").Value;
455                    _config.AuthUrl = configurationList.Find(item => item.Key == "webserviceclient.drhub.authurl").Value;
456                    _config.MaxRetry = Convert.ToInt32(configurationList.Find(item => item.Key == "webserviceclient.global.maxretry").Value);
457                    if (_config.MaxRetry > DefaultMaxRetry) _config.MaxRetry = DefaultMaxRetry;
458                    _config.RetryWaitDuration = Convert.ToInt32(configurationList.Find(item => item.Key == "webserviceclient.global.retrywaitduration").Value);
459                    _config.Simulation = Convert.ToBoolean(configurationList.Find(item => item.Key == "webserviceclient.drhub.enablesimulation").Value);
460                    _config.SimulationInterval = Convert.ToInt32(configurationList.Find(item => item.Key == "webserviceclient.drhub.simulationeventinterval").Value);
461                    _config.CookieName = configurationList.Find(item => item.Key == "webserviceclient.drhub.cookiename").Value;
462                }
463
464                _configSetUp = true;
465
466                contentCashProvider.Set(cacheKey, _config, DateTime.Now.AddMinutes(30));
467                Console.WriteLine("Create/Retrieve DRHub Config Ends");
468            }
469            catch (Exception ex)
470            {
471                _logger.ErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
472                _logger.EmailErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
473                throw;
474            }
475
476
477        }
478
479
480        private EventsCollection ProcessResponse(HttpResponseMessage response)
481        {
482            // responseData should contain events in xml format.  
483
484            EventsCollection eventsCol = null;
485
486            string reqString = _config.ServiceUrl + _config.GetEventsAction;
487            string respString = string.Empty;
488
489            Console.WriteLine("{0} {1}", MsgProcessResponse, EventBegin);
490            _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgProcessResponse, EventBegin));
491
492            if (response.IsSuccessStatusCode)//if (response.ReasonPhrase.ToLower() == ReplyCodeOkay) 
493            {
494                respString = response.Content.ReadAsStringAsync().Result;
495                if (!respString.Contains("</ns2:events>")) // closing tag that will only be present if events are sent
496                {
497                    // no events sent
498                    Console.WriteLine(MsgNoEvent);
499                    _logger.Info(CatagoryPoll, SeverityMedium, PjmNoticationEvent, reqString.ToString(), respString.ToString(), MsgNoEvent);
500
501                } else
502                {
503                    // there are events. process them.
504                    _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, reqString.ToString(), respString.ToString(), string.Empty);
505                    eventsCol = ProcessEvents(respString);
506                }
507            }
508            else // fatal error 
509            {
510                _logger.EmailError(CatagoryPoll, SeverityHigh, PjmNoticationEvent, reqString.ToString(), respString.ToString(), "some really bad error"); //response.Reply.Error[0]);
511                _logger.Error(CatagoryPoll, SeverityHigh, PjmNoticationEvent, reqString.ToString(), respString.ToString(), "some really bad error");// response.Reply.Error[0]);
512
513            }
514
515            _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgProcessResponse, EventEnd));
516
517            Console.WriteLine("{0} {1}", MsgProcessResponse, EventEnd);
518            return eventsCol;
519        }
520           
521
522
523        
524
525       
526
527        private EventsCollection Simulate(string serializedResponse)
528        {
529            try
530            {
531                //Console.WriteLine("{0} {1}", MsgSimulateEvents, EventBegin);
532                _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgSimulateEvents, EventBegin));
533               
534                var reader = new StringReader(serializedResponse);            
535
536                _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgSimulateEvents, EventEnd));
537                Console.WriteLine("{0} {1}", MsgSimulateEvents, EventEnd);
538                
539                EventsCollection events = ProcessEvents(serializedResponse);
540                events.Xml = serializedResponse;
541               
542                return events;
543            }
544            catch (Exception ex)
545            {
546                _logger.ErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
547                _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgSimulateEvents, EventEnd));
548                _logger.EmailErrorException(CatagoryPoll, SeverityHigh, PjmNoticationEvent, ex);
549                throw;
550            }
551        }
552
553
554        private EventsCollection ProcessEvents(string responseData)
555        {
556            Console.WriteLine("{0} {1}", MsgProcessEvents, EventBegin);
557            _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, string.Format("{0} {1}", MsgProcessEvents, EventBegin));
558
559            // pull the team name mapping list from configuration
560            var teamNames = GetTeamNameMappingList();
561
562            var response = new EventsCollection {Xml = responseData};
563            string eventId = string.Empty;
564
565            string type = String.Empty;
566
567            string target = string.Empty; // CURRENTLY NOT CAPTURED. MODEL CHANGED IN XML.
568            string status = string.Empty;
569            string regLeadTime = string.Empty;
570            var startTime = DateTime.MinValue;
571            var notifyTime = DateTime.MinValue;
572            var endTime = DateTime.MinValue;
573            var startUtcTime = DateTime.MinValue;
574            var notifyUtcTime = DateTime.MinValue;
575            var endUtcTime = DateTime.MinValue;
576            var sleadTime = string.Empty;
577            var zone = string.Empty;
578
579
580            XmlDocument doc = new XmlDocument();
581            doc.LoadXml(responseData);
582            var nsmgr = new XmlNamespaceManager(doc.NameTable);
583            nsmgr.AddNamespace("ns2", "http://drhub.pjm.com/");
584            XmlNode eventsNode = doc.SelectSingleNode("//ns2:events", nsmgr);
585
586            foreach (XmlNode eventSummary in eventsNode)
587            {
588                XmlNode idNode = eventSummary.SelectSingleNode("id");
589                eventId = idNode.InnerText;
590                XmlNode infoNode = eventSummary.SelectSingleNode("eventSummaryInfo");
591                status = infoNode["status"].InnerText;
592                regLeadTime = infoNode["regLeadTime"].InnerText;
593                notifyTime = Convert.ToDateTime(infoNode["notifyTime"].InnerText);
594                notifyUtcTime = Convert.ToDateTime(infoNode["notifyTime"].InnerText).ToUniversalTime();
595                startTime = Convert.ToDateTime(infoNode["startTime"].InnerText);
596                startUtcTime = Convert.ToDateTime(infoNode["startTime"].InnerText).ToUniversalTime();
597                zone = infoNode["zone"].InnerText;
598                if (infoNode["endTime"] != null)
599                {
600                    endTime = Convert.ToDateTime(infoNode["endTime"].InnerText);
601                    endUtcTime = Convert.ToDateTime(infoNode["endTime"].InnerText).ToUniversalTime();
602                }
603                zone = infoNode["zone"].InnerText;
604                var eventStatus = EventStatus.None;
605                switch (status.ToLower())
606                {
607                    case "scheduled":
608                        eventStatus = EventStatus.Scheduled;
609                        break;
610                    case "active":
611                        eventStatus = EventStatus.Active;
612                        break;
613                    case "completed":
614                        eventStatus = EventStatus.Completed;
615                        break;
616                    case "canceled":
617                    case "cancelled":
618                        eventStatus = EventStatus.Canceled;
619                        break;
620                }
621                var eventType = EventType.LoadManagement;
622                switch (type.ToLower())
623                {
624                    case "load management":
625                        eventType = EventType.LoadManagement;
626                        break;
627                    case "real-time dispatch":
628                        eventType = EventType.RealTimeDispatch;
629                        break;
630                    case "synchronized reserved":
631                        eventType = EventType.SynchronizedReserved;
632                        break;
633                    case "zonal test":
634                        eventType = EventType.ZonalTest;
635                        break;
636                    case "zonal retest":
637                        eventType = EventType.ZonalRetest;
638                        break;
639                }
640                var leadTime = LeadTimeType.Quick30;
641                switch (regLeadTime.ToLower())
642                {
643                    case "long_120":
644                        leadTime = LeadTimeType.Long120;
645                        break;
646                    case "short_60":
647                        leadTime = LeadTimeType.Short60;
648                        break;
649                    case "quick_30":
650                        leadTime = LeadTimeType.Quick30;
651                        break;
652                    default:
653                        leadTime = LeadTimeType.Quick30;
654                        //_logger.Error(CatagoryPoll, SeverityMedium, PjmNoticationEvent, MsgLeadTimeWarning);
655                        break;
656                }
657                var regInfoList = new List<RegistrationInfo>();
658                XmlNode detailNode = eventSummary.SelectSingleNode("eventDetail");
659
660                foreach (XmlNode evt in detailNode)
661                {
662                    string regId = evt.SelectSingleNode("eventRegistration").SelectSingleNode("registrationId").InnerText;
663                    regInfoList.Add(new RegistrationInfo { RegistrationId = regId, Zone = zone, Target=target }); // TODO: CHECK ADDITION OF TARGET TO REGINFO.
664                }
665                var regIds = string.Empty;
666                regInfoList.ForEach(r =>
667                {
668                    if (regIds != string.Empty)
669                        regIds += ",";
670                    regIds += r.RegistrationId;
671                });
672
673                _logger.Info(CatagoryPoll, SeverityLow, PjmNoticationEvent, MsgEventsReceived, eventSummary.OuterXml);
674                Console.WriteLine(eventSummary.OuterXml);
675
676                GetTeamName(regInfoList, teamNames);
677
678                response.Events.Add(new EventInfo
679                {
680                    EndTime = endTime,
681                    EndUtcTime = endUtcTime,
682                    EventId = eventId,
683                    EventType = eventType,
684                    LeadTime = leadTime,
685                    NotifyTime = notifyTime,
686                    NotifyUtcTime = notifyUtcTime,
687                    RegistrationInfoList = regInfoList,
688                    StartTime = startTime,
689                    StartUtcTime = startUtcTime,
690                    Status = eventStatus,
691                    Target = target,
692                    EventXml = eventSummary.InnerXml
693                });
694            }
695
696            
697            return response;
698        }
699
700        /// <summary>
701        ///  get team name based on registration id
702        /// </summary>
703        /// <param name="regInfoList"></param>
704        /// <param name="teamNames"></param>
705        /// <returns></returns>
706        private void GetTeamName(List<RegistrationInfo> regInfoList, List<TeamNameMapping> teamNames)
707        {
708            regInfoList.ForEach(r =>
709            {
710                var team = teamNames.Find(t => t.RegistrationId == r.RegistrationId);
711
712                if (team != null)
713                {
714                    r.TeamName = team.TeamName;
715                    r.IsHoneywellDlc = team.IsHoneywellDlc;
716                }
717                else
718                {
719                    _logger.Error(CatagoryPoll, SeverityHigh, PjmNoticationEvent, string.Format("{0} {1}", MsgNoTeamNameMapping, r.RegistrationId));
720                    _logger.EmailError(CatagoryPoll, SeverityHigh, PjmNoticationEvent, string.Format("{0} {1}", MsgNoTeamNameMapping, r.RegistrationId));
721                }
722            });
723        }
724
725        private void SetPJMTokenId(int retry, string catagory)
726        {
727            
728            CookieContainer cookies = new CookieContainer();
729            HttpClientHandler handler = new HttpClientHandler();
730            handler.CookieContainer = cookies;
731
732            HttpClient client = new HttpClient(handler);
733            HttpRequestMessage msg = new HttpRequestMessage()
734            {
735                RequestUri = new Uri(_config.AuthUrl),
736                Method = HttpMethod.Post
737            };
738            // TODO: get username and password from config
739            string username = _config.Username;
740            string password = _config.Password; 
741            msg.Headers.Add("X-OpenAM-Username", username);
742            msg.Headers.Add("X-OpenAM-Password", password);
743
744            HttpResponseMessage response = new HttpResponseMessage();
745            string responseBody = string.Empty;
746            //var authCTS = new CancellationTokenSource();
747            //Task task = Task.Run(async () =>
748            //{
749                response = client.SendAsync(msg).Result;
750            //}, authCTS.Token);
751            //authCTS.CancelAfter(3000);
752            //await task;
753            responseBody = response.Content.ReadAsStringAsync().Result;
754            _tokenId = GetTokenId(responseBody);
755            
756            // retry - max 5 times; otherwise throw exception
757            if (string.IsNullOrEmpty(_tokenId))
758            {
759                if (retry < _config.MaxRetry)
760                {
761                    retry++;
762                   
763                    _logger.Info(catagory, SeverityMedium, PjmNoticationEvent, string.Format("Set PJM Token Id Retry Attempt: {0}", retry));
764#if DEBUG
765                    Console.WriteLine("Set PJM Token Id Retry Attempt: {0}", retry);
766#endif
767                    SetPJMTokenId(retry, catagory);
768                }
769                else
770                {
771                    var exception = new Exception("Unable to set PJM Token Id");
772                    _logger.EmailErrorException(catagory, SeverityHigh, PjmNoticationEvent, exception);
773                    throw exception;
774                }
775
776            }
777        }
778
779        private HttpClient GetAuthDRHubClient(string requestUri, string catagory)
780        {
781            if (string.IsNullOrEmpty(_tokenId))
782            {
783                SetPJMTokenId(0, catagory);
784                
785            }
786
787            // SET AUTH COOKIE
788            HttpClientHandler dataClientHandler = new HttpClientHandler();
789            dataClientHandler.CookieContainer = new CookieContainer();
790            dataClientHandler.CookieContainer.Add(new Uri(requestUri), new Cookie(_config.CookieName, _tokenId));
791
792            //  Create client
793            HttpClient dataClient = new HttpClient(dataClientHandler);
794            return dataClient;
795        }
796
797
798        private List<TeamNameMapping> GetTeamNameMappingList()
799        {
800            var teamNames = new List<TeamNameMapping>();
801
802            var mappingStr = GetTeamNameMappingXml();
803            var teamNameDoc = XDocument.Load(new StringReader(mappingStr));
804
805            var teamNameMapping = teamNameDoc.Descendants("TeamNameMapping").Select(x => x).ToList();
806
807            teamNameMapping.ForEach(tm =>
808            {
809                tm.Descendants("MapInfo").Select(m => m).ToList().ForEach(t =>
810                {
811                    var honeywellDlc = false;
812                    if (t.Attribute("HoneywellDLC") != null)
813                    {
814                        honeywellDlc = Convert.ToBoolean(t.Attribute("HoneywellDLC").Value);
815                    }
816                    teamNames.Add(new TeamNameMapping
817                    {
818                        RegistrationId = t.Attribute("key").Value,
819                        IsHoneywellDlc = honeywellDlc,
820                        TeamName = t.Value.Replace("&amp;", "&")
821                    });
822                });
823            });
824
825            return teamNames;
826        }
827
828        /// <summary>
829        /// retreive team name mapping xml from database
830        /// </summary>
831        /// <returns></returns>
832        private string GetTeamNameMappingXml()
833        {
834            string mappingStr;
835            var connectionStr = ConfigurationManager.ConnectionStrings["InsightsMetaDataConn"].ConnectionString;
836
837            using (var sqlConnection = new SqlConnection(connectionStr))
838            {
839                var cmd = new SqlCommand
840                {
841                    CommandText = "[dbo].[GetComponentXmlConfiguration]",
842                    CommandType = CommandType.StoredProcedure,
843                    Connection = sqlConnection
844                };
845
846
847                cmd.Parameters.Add(new SqlParameter("@ClientId", SqlDbType.Int) { Value = _clientId });
848                cmd.Parameters.Add(new SqlParameter("@ComponentName", SqlDbType.Text) { Value = "notification" });
849                var param = cmd.CreateParameter();
850                param.ParameterName = "@XmlConfiguration";
851                param.Direction = ParameterDirection.Output;
852                param.DbType = DbType.Xml;
853                cmd.Parameters.Add(param);
854
855                sqlConnection.Open();
856
857                cmd.ExecuteNonQuery();
858
859                mappingStr = param.Value.ToString();
860            }
861
862            return mappingStr;
863
864        }
865
866
867        // TODO: I DON'T THINK THIS IS NECESSARY OR WORKS. JUST SEND BACK XML FOR ACKNOWLEDGEMENT.
868        /// <summary>
869        /// set up the acknowledgement pay load
870        /// </summary>
871        /// <param name="events"></param>
872        /// <returns></returns>
873        private string GetAcknowledgementPayloadString(List<EventInfo> events)
874        {
875            var acknowledgementPayloadStr = @"<Events xmlns='http://www.pjm.com/schema/drbiznet/2009/model'>";
876
877            foreach (var e in events)
878            {
879                acknowledgementPayloadStr += "<Event><id>" + e.EventId + "</id>";
880                double amount;
881                if (double.TryParse(e.Target, out amount))
882                    acknowledgementPayloadStr += "<summaryInfo><ackAmount>" + e.Target + "</ackAmount></summaryInfo>";
883
884                acknowledgementPayloadStr += "</Event>";
885            }
886
887            acknowledgementPayloadStr += @"</Events>";
888
889            return acknowledgementPayloadStr;
890        }
891
892
893        private string GetNoEventResponseString()
894        {
895            var xmlDoc = new XmlDocument();
896            xmlDoc.Load("Samples\\SimulateNoEvent.xml");
897            var objectStr = xmlDoc.InnerXml;
898            return objectStr;
899        }
900
901        // TODO: REPLACE THIS XML STUFF
902        private string GetEventsResponseString()
903        {
904            var xmlDoc = new XmlDocument();
905            xmlDoc.Load("Samples\\SimulateEvent.xml");
906            var objectStr = xmlDoc.InnerXml;
907
908            return objectStr;
909        }
910        public string GetTokenId(string jsonString)
911        {
912            var jObj = JObject.Parse(jsonString);
913            var token = jObj.SelectToken("tokenId");
914            return token.Value<string>();
915        }
916        #endregion
917    }
918
919    [Serializable]
920    public class DRHubConfig
921    {
922        public string Username { get; set; }
923        public string Password { get; set; }
924
925        public string WebServiceEndPoint { get; set; }
926
927        public string GetEventsAction { get; set; }
928        public string AcknowledgeEventsAction { get; set; }
929        public string ServiceUrl { get; set; }
930
931        public string AuthUrl { get; set; }
932        public List<string> EventTypes { get; set; }
933        public int MaxRetry { get; set; }
934        public int RetryWaitDuration { get; set; }
935        public bool Simulation { get; set; }
936        public int SimulationInterval { get; set; }
937        public string CookieName { get; set; }
938    }
939
940    [Serializable]
941    public class TeamNameMapping
942    {
943        public string RegistrationId { get; set; }
944        public string TeamName { get; set; }
945        public bool IsHoneywellDlc { get; set; }
946    }
947}