public void Parse_NoOperationMessage_XMLString()
        {
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"xml_samples\NoOperation.xml");

            BackupCommunicationServer backupServer1
                = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer backupServer2
                = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer[] backupServers =
            {
                backupServer1, backupServer2
            };

            NoOperationMessage noOperation = new NoOperationMessage(backupServers);

            string actualXmlStr = noOperation.ToXmlString();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(path);
            string expectedXmlStr = xmlDoc.OuterXml;

            Assert.AreEqual(expectedXmlStr, actualXmlStr);
        }
        public void Parse_XMLString_NoOperationMessage()
        {
            /*********** Actual message ***********/
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"xml_samples\NoOperation.xml");

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(path);
            string xmlStr = xmlDoc.OuterXml;

            string name = Message.GetMessageName(xmlStr);
            NoOperationMessage actualMessage = null;

            if (name == NoOperationMessage.ELEMENT_NAME)
                actualMessage = NoOperationMessage.Construct(xmlStr);

            /*********** Expected message ***********/
            BackupCommunicationServer backupServer1
               = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer backupServer2
                = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer[] backupServers =
            {
                backupServer1, backupServer2
            };

            NoOperationMessage expectedMessage = new NoOperationMessage(backupServers);

            Assert.AreEqual(expectedMessage, actualMessage);
        }
        /// <summary>
        ///     Status is sent by everyone as Keep-alive message
        /// </summary>
        /// <param name="messagePackage"></param>
        private void handleStatusMessage(MessagePackage messagePackage)
        {
            StatusMessage message = (StatusMessage)messagePackage.Message;
            // check what node
            lock (clientTracker.lockObject)
            {
                NetworkNode networkNode = clientTracker.GetNodeByID(message.Id);

                networkNode.LastSeen = DateTime.Now;
                
                UpdateThreadsStatus(networkNode, message);

                // inform backup
                if (networkNode.Type != RegisterType.CommunicationServer)
                {
                    InformBackup(message);
                }

                //if status message was send by TaskManager than check if there are any tasks to divide or merge
                if (networkNode.Type == RegisterType.TaskManager)
                {
                    //Response to TaskManager statusMessage
                    ReactToTaskManagerStatusMessage(networkNode, messagePackage);
                }
                //is staty message was send by computational node than check if there are any partial problems to calculate. 
                else if (networkNode.Type == RegisterType.ComputationalNode)
                {
                    ReactToComputationalNodeStatusMessage(networkNode, messagePackage);
                }
                else
                {
                    if (Server.primaryMode) 
                    {
                        NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers);
                        server.Send(messagePackage.Socket, response);
                        SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic);
                    }
                }
            }
        }
        /// <summary>
        ///     Solutions is sent by every node to give info
        ///     about ongoing computations or final solutions
        /// </summary>
        /// <param name="messagePackage"></param>
        private void handleSolutionsMessage(MessagePackage messagePackage)
        {
            SolutionsMessage message = (SolutionsMessage)messagePackage.Message;

            InformBackup(message);

            Task task = taskTracker.GetTask((int)message.Id);
            //IT HAS TO BE CHANGED AFTER ADDING SUBTASK ID @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
            if (message.Solutions[0].Type == SolutionsSolutionType.Final)
            {
                task.Solutions = message.Solutions;
                task.Status = TaskStatus.Merged;
            }
            else
            {
                for (int i = 0; i < task.subTasks.Count; i++)
                {
                    if (task.subTasks[i].Status == TaskStatus.Solving)
                    {
                        task.subTasks[i].Status = TaskStatus.Solved;
                        task.subTasks[i].Solutions = message.Solutions;
                        break;
                    }
                }
            }

            if (Server.primaryMode)
            {
                NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers);
                server.Send(messagePackage.Socket, response);
                SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic);
            }
        }
        /// <summary>
        ///     SolveRequest is sent by Computational Client
        /// </summary>
        /// <param name="messagePackage"></param>
        private void handleSolveRequestMessage(MessagePackage messagePackage)
        {
            SolveRequestMessage message = (SolveRequestMessage)messagePackage.Message;

            InformBackup(message);

            // if the cluster can solve this problem
            if (clientTracker.CanSolveProblem(message.ProblemType))
            {
                Task task = new Task((int)systemTracker.GetNextTaskID(), message.ProblemType,
                                        message.Data);
                taskTracker.AddTask(task);

                if (Server.primaryMode)
                {

                    NoOperationMessage responseNoOp = new NoOperationMessage(clientTracker.BackupServers);
                    SolveRequestResponseMessage response = new SolveRequestResponseMessage((ulong)task.ID);

                    List<Message> messages = new List<Message>();
                    messages.Add(responseNoOp);
                    messages.Add(response);

                    server.Send(messagePackage.Socket, messages);
                    SmartConsole.PrintLine("Sent a SolveRequestResponse Message", SmartConsole.DebugLevel.Basic);
                }
                
            }
            else
            {
                //TODO RESPONSE MESSAGE

                Console.Write(" >> TM ERROR\n");
            }
        }
        /*******************************************************************/
        /************************ PRIVATE METHODS **************************/
        /*******************************************************************/

        private void handleNoOperationMessage(NoOperationMessage message)
        {
            systemTracker.Node.BackupServers = message.BackupCommunicationServers;

            SmartConsole.PrintLine("Current Backup count: " + systemTracker.Node.BackupServers.Length, SmartConsole.DebugLevel.Basic);
        }
        /// <summary>
        ///     SolvePartialProblem is sent by TM
        /// </summary>
        /// <param name="messagePackage"></param>
        private void handleSolvePartialProblemsMessage(MessagePackage messagePackage)
        {
            /* add partial tasks to subTask list in a task */
            SolvePartialProblemsMessage message = (SolvePartialProblemsMessage)messagePackage.Message;

            InformBackup(message);

            Task task = taskTracker.GetTask((int)message.Id);
            task.Status = TaskStatus.Divided;
            for (int i = 0; i < message.PartialProblems.Count(); i++)
            {
                Task subTask = new Task((int)message.Id, message.ProblemType, message.PartialProblems[i].Data);
                subTask.Status = TaskStatus.New;
                task.AddSubTask(subTask);
            }
            /***********************************************/
            if (Server.primaryMode)
            {
                NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers);
                server.Send(messagePackage.Socket, response);
                SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic);
            }
        }
        /// <summary>
        /// this function is a response to Computational Node status message
        /// </summary>
        /// <param name="networkNode"></param>
        /// <param name="messagePackage"></param>
        private void ReactToComputationalNodeStatusMessage(NetworkNode networkNode, MessagePackage messagePackage)
        {
            bool messageCheck = false;
            for (int i = 0; i < taskTracker.Tasks.Count; i++)
            {
                if (taskTracker.Tasks[i].Status == Cluster.TaskStatus.Divided && taskTracker.Tasks[i].Type == networkNode.SolvableProblems[0])
                {
                    //  REMEBER TO CHECK IF THERE IS A AVALIABLE THREAD ******************************************************************************************************
                    // check number of avaliable threads
                    int avaliableThreads = AvaliableThreadsCount(networkNode);
                    List<PartialProblem> partialList = new List<PartialProblem>();
                    for (int j = 0; j < taskTracker.Tasks[i].subTasks.Count && avaliableThreads > 0; j++)
                    {
                        if (taskTracker.Tasks[i].subTasks[j].Status == Cluster.TaskStatus.New)
                        {
                            avaliableThreads--;
                            partialList.Add(new PartialProblem((ulong)taskTracker.Tasks[i].ID, taskTracker.Tasks[i].subTasks[j].BaseData, (ulong)(0)));
                            taskTracker.Tasks[i].subTasks[j].Status = Cluster.TaskStatus.Solving;
                            // temporary solution @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                        }
                    }
                    if (partialList.Count > 0)
                    {
                        messageCheck = SendPartialProblemsMessage(i, partialList, messagePackage);
                    }
                    if (messageCheck)
                    {
                        break;
                    }

                }
            }
            if (messageCheck == false && Server.primaryMode)
            {
                NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers);
                server.Send(messagePackage.Socket, response);

                SmartConsole.PrintLine("Sent a NoOperation Message. 0 subTasks to divide or 0 apropriate computationalNodes", SmartConsole.DebugLevel.Basic);
            }
        }
        /// <summary>
        /// this function is a response to task manager status message
        /// </summary>
        /// <param name="networkNode"></param>
        /// <param name="messagePackage"></param>
        private void ReactToTaskManagerStatusMessage(NetworkNode networkNode,MessagePackage messagePackage)
        {
            //checks if divide or merge solution message has been sent. If not than send noOperation message.
            bool hasMessageBeenSent = false;
            int numberOfAvaliableThreads = AvaliableThreadsCount(networkNode);

            for (int i = 0; i < taskTracker.Tasks.Count && numberOfAvaliableThreads > 0; i++)
            {
                if (isMessageProblemDividedSent(i, networkNode, messagePackage))
                {
                    hasMessageBeenSent = true;
                    numberOfAvaliableThreads--;
                }
            }
            // If there are avaliable threads than try to send merge solution message               
            for (int i = 0; i < taskTracker.Tasks.Count && numberOfAvaliableThreads > 0; i++)
            {
                if (isMergeSolutionSent(i, networkNode, messagePackage))
                {
                    hasMessageBeenSent = true;
                    numberOfAvaliableThreads--;
                }
            }

            //if divideProblemMessage hasn't been sent than send noOperationMessage
            if (hasMessageBeenSent == false && Server.primaryMode)
            {
                NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers);
                server.Send(messagePackage.Socket, response);

                SmartConsole.PrintLine("Sent a NoOperation Message. 0 tasks to divide or 0 apropriate task managers", SmartConsole.DebugLevel.Basic);
            }
        }
 private void handleNoOperationMessage(NoOperationMessage message) 
 {
     systemTracker.Node.BackupServers = message.BackupCommunicationServers;
 }
        public static NoOperationMessage CreateNoOperationMessage()
        {
            BackupCommunicationServer backupServer1
              = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer backupServer2
                = new BackupCommunicationServer("192.168.1.0", 80);

            BackupCommunicationServer[] backupServers =
            {
                backupServer1, backupServer2
            };

            NoOperationMessage expectedMessage = new NoOperationMessage(backupServers);
            return expectedMessage;
        }
        public override bool Equals(object obj)
        {
            NoOperationMessage message = obj as NoOperationMessage;

            return(Enumerable.SequenceEqual(BackupCommunicationServers, message.BackupCommunicationServers));
        }