private void listenerPeerDisconnected(object sender, EventArgs e)
 {
     List<SourceNode> SourceNodes = new List<SourceNode>();
     ListenerPeer peer = sender as ListenerPeer;
     if (peer == null) return;
     Logger.Log("(Event) Source server disconnected from: " + peer.Name);
     SourceNode sourceNode = new SourceNodeManager().GetByID(Convert.ToInt32(peer.Name));
     SourceNodes.Add(sourceNode);
     StartListener(SourceNodes);
 }
        public static void Startup()
        {
            //TO INSTANTIATE CLIENT PEER
            TransactionManager trxnManager = new TransactionManager();
            //Start up all listeners
            Logger.Log("Searching for pre-configured source servers");
            List<SourceNode> allSourceNode = new SourceNodeManager().RetrieveAll().ToList();
            Logger.Log(allSourceNode.Count + " Source server(s) found:.\t ");

            new Listener().StartListener(allSourceNode);

            //Start up all clients
            Logger.Log("Searching for pre-configured sink Clients:-->> ");
            List<SinkNode> allSinkNode = new SinkNodeManager().GetAllSinkNode().ToList();
            Logger.Log(allSinkNode.Count + " Sink Client(s) found");
            new Client().StartClient(allSinkNode);
        }
        public void DoAutoReversal()
        {
            var allLogsThatNeedsReversal = new TransactionLogManager().GetAllThatNeedsReversal();
               Iso8583Message msgFromFEP = null;
               bool needReversal = true;
               Dictionary<string, SinkNode> allSinkNodes = new SinkNodeManager().GetAllSinkNode().ToDictionary(x => x.Name);
               Dictionary<string, SourceNode> allSourceNodes = new SourceNodeManager().RetrieveAll().ToDictionary(x => x.Name);
               foreach (var log in allLogsThatNeedsReversal)
               {
               if (!log.IsReversed && log.IsReversePending)
               {
                   Iso8583Message revMsg = BuildReversalIsoMessage(log);
                   Logger.LogTransaction(revMsg);
                   if (log.SinkNode != null)
                   {
                       var sinkNode = allSinkNodes[log.SinkNode];
                       msgFromFEP = ToFEP(revMsg, sinkNode, out needReversal); //TOFEP should set needReversal to false

                       if (msgFromFEP.Fields[39].ToString() == "00")
                       {
                           Logger.LogTransaction(msgFromFEP, allSourceNodes[log.SourceNode], null, null, needReversal);
                       }
                   }

                   if (!needReversal)
                   {
                       log.IsReversePending = false;
                       log.IsReversed = true;
                       new TransactionLogManager().Update(log);
                       Logger.Log("Auto Reversal done for: " + log.OriginalDataElement);
                   }
               }
               if (log.IsReversed)
               {
                   log.IsReversePending = false;
                   log.IsReversed = true;
                   new TransactionLogManager().Update(log);
               }
               }
        }
        //Set status to inactive
        public static void Shutdown()
        {
            //TO INSTANTIATE CLIENT PEER
            TransactionManager trxnManager = new TransactionManager();

            IList<SourceNode> allSourceNode = new SourceNodeManager().RetrieveAll();

            foreach (var thisNode in allSourceNode)
            {
                thisNode.IsActive = false;
                new SourceNodeManager().Update(thisNode);
                Logger.Log(thisNode.Name + " shutting down at " + thisNode.IPAddress + " on " + thisNode.Port);
            }

            IList<SinkNode> SinkNodes = new SinkNodeManager().GetAllSinkNode();

            foreach (var sinkNode in SinkNodes)
            {
                sinkNode.IsActive = false;
                new SinkNodeManager().Update(sinkNode);
                Logger.Log(sinkNode.Name + " shutting down at " + sinkNode.IPAddress + " on " + sinkNode.Port);
                Console.WriteLine("SinkNode ShortDown" + sinkNode.IPAddress + "\t" + sinkNode.Port);
            }
        }
        public Iso8583Message ValidateMessage(Iso8583Message originalMessage, int sourceID)
        {
            Logger.Log("\n Enter Validator");
               //get source Node.
               SourceNode sourceNode = new SourceNodeManager().GetByID(sourceID);

               DateTime transmissionDate = DateTime.UtcNow;
               //format TransactionDate
               string transactionDate = string.Format("{0}{1}",
                 string.Format("{0:00}{1:00}", transmissionDate.Month, transmissionDate.Day),
                 string.Format("{0:00}{1:00}{2:00}", transmissionDate.Hour,
                 transmissionDate.Minute, transmissionDate.Second));

               //set Original Data Element
             string originalDataElement = string.Format("{0}{1}{2}", originalMessage.MessageTypeIdentifier.ToString(), originalMessage.Fields[11].ToString(), transactionDate);
               //add original data element to original message
               originalMessage.Fields.Add(90, originalDataElement);

               //Do Message Log
               Logger.LogTransaction(originalMessage, sourceNode);

               //  Check if it is reversal message and do the needful
               if (originalMessage.MessageTypeIdentifier == 421)
               {
               Logger.Log("\n This is a reversal");
               bool conReversal;
               Iso8583Message reversalIsoMsg = GetReversalMessage(originalMessage, out conReversal);
               if (!conReversal)
               {
                   Logger.LogTransaction(reversalIsoMsg);
                   return reversalIsoMsg;
               }
               originalMessage = reversalIsoMsg;
               Logger.LogTransaction(originalMessage, sourceNode);
               }

               string theCardPan = originalMessage.Fields[2].Value.ToString();
               string tranasactionTypeCode = originalMessage.Fields[3].Value.ToString().Substring(0, 2);
               double amount = Convert.ToDouble(originalMessage.Fields[4].Value);
               string orgExpiry = originalMessage.Fields[14].Value.ToString();

               string code = originalMessage.Fields[123].ToString().Substring(13, 2);

               Channel channel = new ChannelManager().GetByCode(code);
               Fee fee = null;
              // string cardPAN = theCardPan.Substring(0, 6);
               Route theRoute = new RouteManager().GetRouteByCardPan(theCardPan.Substring(0, 6));
               TransactionType transactionType = new TransactionTypeManager().GetByCode(tranasactionTypeCode);
               Iso8583Message responseMessage;

               //check if card has expired
               DateTime cardExpiryDate = ParseExpiryDate(orgExpiry);

               if(cardExpiryDate < DateTime.Now)
               {
               responseMessage = SetReponseMessage(originalMessage, "54");         //Expired card
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }

               if (amount <= 0 && tranasactionTypeCode != "31")
               {
               responseMessage = SetReponseMessage(originalMessage, "13");         //Invalid amount
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }

               if (theRoute == null)
               {
               Logger.Log("Sink node is null.");
               responseMessage = SetReponseMessage(originalMessage, "15");         //No such issuer
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }
               SinkNode sinkNode = theRoute.SinkNode;
               if (sinkNode == null)
               {
               Logger.Log("Sink node is null.");
               responseMessage = SetReponseMessage(originalMessage, "91");  //Issuer inoperative
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }

               Logger.Log("Loading SourceNode Schemes");

               var theSchemes = sourceNode.Schemes;
               Scheme scheme = null;
               try
               {
               scheme = theSchemes.Where(x => x.Route.CardPAN == theCardPan.Substring(0,6)).SingleOrDefault();
               }
               catch (Exception ex)
               {
               Logger.Log("Error: \n" + ex.Message);
               responseMessage = SetReponseMessage(originalMessage, "31"); // Lazy load error : Set correct response code later
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }

               if (scheme == null)
               {
               responseMessage = SetReponseMessage(originalMessage, "92"); // Route not allowed : Set correct response code later
               Logger.LogTransaction(responseMessage, sourceNode);
               return responseMessage;
               }

              // int panCount = sourceNode.Schemes.Count(x => x.Route == theRoute);
               Logger.Log("Scheme : " + scheme.Name + " Loaded");

               Logger.Log("Getting fee:");
               fee = GetFeeIfTransactionIsAllowed(transactionType, channel, scheme);
               if (fee == null)
               {
               responseMessage = SetReponseMessage(originalMessage, "58"); // Transaction type not allowed in this scheme
               Logger.LogTransaction(responseMessage, sourceNode, scheme);
               return responseMessage;
               }
               else
               {
               originalMessage = SetFee(originalMessage, CalculateFee(fee, amount));
               }
               bool needReversal = false;

               Iso8583Message msgFromFEP = ToFEP(originalMessage, sinkNode, out needReversal);

               Logger.LogTransaction(msgFromFEP, sourceNode, scheme, fee, needReversal);

               return msgFromFEP;
        }