//@Override public bool removeAppointment(int seqNumberInt) { //call by both remote and local hosts //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(false); } Integer seqNumber = new Integer(seqNumberInt); foreach (Appointment appointment in this.appointmentsList) { if (appointment.getSequentialNumber() == seqNumber.intValue()) { this.appointmentsList.Remove(appointment); if (!this.appointmentsList.Exists(temp => temp == appointment)) //if the remove was successful? { this.setLastModified(); this.updateLocalDatabase(); return(true); } else { return(false); } } } return(true); }
//@Override public bool addMe(String newHostUrl, int port) //add a signOn host { //this function must not be static because it is needed to call by XML-RPC //this function will call by a client on another host //the client will send its own URL and port to register as a new host on this machine //and then the client will receive 'true' if the addition was successful or 'false' if the addition was failed //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(false); } try{ //check for iterated(repited) host for (int index = 0; index < hostsAddresses.Count; index++) { if (hostsAddresses[index].getHostUrl().Equals(newHostUrl) && hostsAddresses[index].getPort() == port) { return(true); //it means at the previous signoff the address of this host has not removed successfully } } HostUrl hostUrl = new HostUrl(newHostUrl, port); hostsAddresses.Add(hostUrl); return(true); //note: if the add procedure be successful, then the a true value will be send }catch (System.Exception) { //Console.WriteLine("Joining a new host has crached, maybe entered URL or port has a problem."); //Console.WriteLine(e.Message); return(false);//if the adding process fail in any cases, this false value will show this failure } }
//@Override public bool removeMe(String oldHostUrl, int port) //Remove a signOff host { //this function must not be static because it is needed to call by XML-RPC //this function will call by a client on another host //the client will send its own URL and port to unregister as a signed on host and goes to sign off //and then the client will receive 'true' if the elimination was successful or 'false' if the elimination was failed //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(false); } try{ //check to find the host in the list for (int index = 0; index < hostsAddresses.Count; index++) { if (hostsAddresses[index].getHostUrl().Equals(oldHostUrl) && hostsAddresses[index].getPort() == port) { hostsAddresses.RemoveRange(index, 1); break; } } return(true); } catch (System.Exception) { } return(false);//if the removing process fail in any cases, this false value will show this failure }
//@Override public bool modifyAppointment(int seqNumberInt, String newDateTimeString, int newSecDurationInt, String newHeader, String newComment) { //call by both remote and local hosts //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(false); } Integer seqNumber; Date newDateTime; Integer newSecDuration; try { seqNumber = new Integer(seqNumberInt); newDateTime = new Date(newDateTimeString); newSecDuration = new Integer(newSecDurationInt); } catch (System.Exception) { return(false); } if (seqNumber.intValue() < 1) { return(false); } else if (newSecDuration.intValue() < 1) { return(false); } foreach (Appointment appointment in this.appointmentsList) { if (appointment.getSequentialNumber() == seqNumber.intValue()) { try { appointment.setDateTime(newDateTime); appointment.setSecDuration(newSecDuration.intValue()); appointment.setHeader(newHeader); appointment.setComment(newComment); this.setLastModified(); this.updateLocalDatabase(); return(true); } catch (System.ArgumentOutOfRangeException) //For setDuration { return(false); } } } //if it couldn't find this appointment must add this to the list! return(addNewAppointment(seqNumberInt, newDateTimeString, newSecDurationInt, newHeader, newComment)); }
//@Override public int createNewAppointment(String dateTimeString, int secDurationInt, String header, String comment) //call by this client but throw XML-RPC { //call by the client of the current machine to make a new appointment //it must return unique sequence number of the new appointment or -1 if it fail to add //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(-1); } Date dateTime; Integer secDuration; try { dateTime = new Date(dateTimeString); secDuration = new Integer(secDurationInt); } catch (System.Exception e) { Console.WriteLine(e.Message); return(-1); } //throwing an exception has sence or meaning here //because this function will call locally if (secDuration.intValue() < 1) { throw new System.ArgumentOutOfRangeException("The seconds of duration[secDuration] must be greater than 0."); } //Create a new seqNumber and add the appointment to the array list! try { SequentialNumber sqn = new SequentialNumber(); Appointment appointment = new Appointment(sqn, dateTime, secDuration.intValue(), header, comment); this.appointmentsList.Add(appointment); Console.WriteLine("\n_______________________________"); Console.WriteLine("You have made a new appointment on this host successfully.\n" + appointment.ToString()); this.setLastModified(); this.updateLocalDatabase(); return(sqn.getSequentialNumber()); } catch (System.IndexOutOfRangeException e) //for creating sequential number { Console.WriteLine(e.Message); return(-1); } }
//@Override public bool addPemissionAccepted(String replierId, int replierLogicalClock, String replierHostUrl, int replierHostPort, String requesterId, int requesterLogicalClock) { //the clock will manage here too //The first 2 objects used for correcting the clock //The third one used for deleting the host from the tail list ! and not from the queue //The last 2 objects are used for checking true answering //this will call by other clients to send [rep<id,clock> --to--> req<id',clock'>] actually OK message! //when they want to send a OK reply to our previous request they must call this function //this function will remove RequestObjects from the tail list try{ if (!ServerStatus.getServerStatus()) { return(false); } if (currentAddRequest != null) { long requesterIdL = 0; HostUrl hostUrl = null; try { requesterIdL = Convert.ToInt64(requesterId); hostUrl = new HostUrl(replierHostUrl, replierHostPort); } catch (Exception) { return(false); } //correcting Clock ExtendedLamportClockObject ELC = new ExtendedLamportClockObject(requesterIdL, requesterLogicalClock); //for correcting logical clock after receive if (currentAddRequest.getELCO().compare(ELC) == 0) //if the replier send the reply for the current request { lock (this) { currentAddRequest.removeNode(hostUrl); } hostUrl = null; ELC = null; } return(true); } return(false); }catch (Exception) { return(false); } }
//@Override public String syncRequest(String lastModificationString) { //Called by remote hosts to get list of appointments for synchronization //At first we wanted to optimize it by last modification time but because it was not said in the assignment sheet we //decided to drop this section! //because in C# XmlRpcServer Library stopping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(null); } //Date lastModification = new Date(lastModificationString); return(this.appointmentsSerialize()); }
//@Override public String joinRequest(String newHostUrl, int port) { //Console.WriteLine("\nNew joining request from : "+newHostUrl+" port: "+port + " has been received."); //this function must not be static because it is needed to call by XML-RPC //this function will call by a client on another host //the client will send its own URL and port //and then the client will receive a list of all hosts //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(null); } try { bool flag = true; HostUrl hostUrl = new HostUrl(newHostUrl, port); //check for iterated(repited) host for (int index = 0; index < hostsAddresses.Count && flag; index++) { if (hostsAddresses[index].getHostUrl().Equals(newHostUrl) && hostsAddresses[index].getPort() == port) { flag = false; } } if (flag) { hostsAddresses.Add(hostUrl); //Add the new host that request for joining to the host list of this machine } //Console.WriteLine("\nNew host has been added : " + hostUrl.getFullUrl()); return(listAllHostsExcept(hostUrl)); //note: if the add procedure be successful, then the list of all hosts except local host will be send, //if there were no host more than local host it will return an empty String same as "" but not null } catch (System.Exception) { //because of setUrlHost & set port //Console.WriteLine("Joining a new host has crached, maybe entered URL or port has a problem."); //Console.WriteLine(e.Message); return(null);//if the joining process fail in any cases, this null value will show this failure } }
public override void controlPanel() { if (ServerStatus.getServerStatus()) //If the server is in its ready state! { Console.WriteLine("\n"); Console.WriteLine("___________________________________________"); Console.WriteLine("HPN Calendar Tools Options [Online Mode]: "); Console.WriteLine(" 1-SignOff This Host"); Console.WriteLine(" 2-List All Hosts"); Console.WriteLine(" 3-List All Appointments"); Console.WriteLine(" 4-Create An Appointment"); Console.WriteLine(" 5-Remove An Appointment"); Console.WriteLine(" 6-Modify An Appointment"); Console.WriteLine(" 7-Disply An Appointment"); Console.WriteLine(" 8-Exit"); Console.WriteLine("___________________________________________"); Console.Write(">>Input the number of intended command :> "); this.executeUserCommands(true); } else { Console.WriteLine("\n"); Console.WriteLine("_______________________________________________"); Console.WriteLine("This host is offline, sign On for more options."); Console.WriteLine("You can just see last appointments that has"); Console.WriteLine("been saved on hard disk in last connection."); Console.WriteLine(""); Console.WriteLine("HPN Calendar Tools Options[Offline Mode]: "); Console.WriteLine(" 1-SignOn/Connect To The Network"); Console.WriteLine(" 2-List All Appointments"); Console.WriteLine(" 3-Show An Appointment "); Console.WriteLine(" 4-Exit"); Console.WriteLine("___________________________________________"); Console.Write(">>Input the number of intended command :> "); this.executeUserCommands(false); } }
//@Override public bool addNewAppointment(int seqNumberInt, String dateTimeString, int secDurationInt, String header, String comment) { //call by other clients to send a new appointment //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server //is not in its online mode. if (!ServerStatus.getServerStatus()) { return(false); } Integer seqNumber; Date dateTime; Integer secDuration; try { seqNumber = new Integer(seqNumberInt); dateTime = new Date(dateTimeString); secDuration = new Integer(secDurationInt); } catch (System.Exception) { //Console.WriteLine("\nOne request for adding a new appointment to the current system has received but in converting the data in has crashed by the following exception : "); //Console.WriteLine("Exception Message : \n" + e.Message); //Console.WriteLine("Received Data : " + "\nSeqential Number : " + seqNumberInt + "\nDate : " + dateTimeString + "\nDuration " + secDurationInt + "\nHeader" + header + "\nComment" + comment); return(false); } if (seqNumber.intValue() < 1) { //because it will called by remote host throwing exception is meaning less. //throw new System.ArgumentOutOfRangeException("The sequential number[seqNumber] must be greater than 0."); //Console.WriteLine("\nOne request for adding a new appointment to the current system has received but the sequential number was invalid."); //Console.WriteLine("Received Data : " + "\nSeqential Number : " + seqNumberInt + "\nDate : " + dateTimeString + "\nDuration " + secDurationInt + "\nHeader" + header + "\nComment" + comment); return(false); } else if (secDuration.intValue() < 1) { //throw new System.ArgumentOutOfRangeException("The seconds of duration[secDuration] must be greater than 0."); //Console.WriteLine("\nOne request for adding a new appointment to the current system has received but the duration number was invalid."); //Console.WriteLine("Received Data : " + "\nSeqential Number : " + seqNumberInt + "\nDate : " + dateTimeString + "\nDuration " + secDurationInt + "\nHeader" + header + "\nComment" + comment); return(false); } //Create requested sequence number or a new sequence number and add the appointment to the array list. try { //We make the sequential number and then check for its existance //if the sequential number is exist then we make a new one and it will continue till get a unique sequential number //another strategy for here can be to return false if we have the current sequential number in this host //but we think it is better to not lose any apointment even with registering it with a wrong sequential number //but based on what said in the assignment sheet //we must not consider the conflict of the concurrency of the creation of appointments SequentialNumber sqn = new SequentialNumber(seqNumber.intValue()); bool flag; do { flag = false; foreach (Appointment tempAppointment in this.appointmentsList) //search to sure about non existence of the new sequence number in appointment list { if (tempAppointment.getSequentialNumber() == sqn.getSequentialNumber()) { sqn = new SequentialNumber(); flag = true; break; } } }while(flag); if (sqn.getSequentialNumber() != seqNumber.intValue()) { Console.WriteLine("Remote addAppointment: The sequance number [" + seqNumber.intValue() + "] that has been sent by a remote host, is exist. So a new sequance number has assigned : " + sqn.getSequentialNumber()); } Appointment appointment = new Appointment(sqn, dateTime, secDuration.intValue(), header, comment); this.appointmentsList.Add(appointment); if (this.appointmentsList.Exists(temp => temp == appointment)) //if the add was successful? { //This will show when a far host add an appointment to the list //Console.WriteLine(""); //Console.WriteLine("_______________________________"); //Console.WriteLine("One appointment has been added."); //Console.WriteLine("-------------------------------"); //Console.WriteLine(appointment.ToString()); this.setLastModified(); this.updateLocalDatabase(); return(true); } else { return(false); } } catch (System.IndexOutOfRangeException) //for creating sequential number { //Console.WriteLine(e.Message); return(false); } }
//this will call by others //@Override public String requestModifyPermission(String requesterId, int requesterLogicalClock, int requestedAppointmentSequentialNumber, String requesterHostUrl, int requesterHostPort) { //the clock will manage here too //this will call by others to send [req<id,clock>] to this host //By receiving a req message we will send a true that mean we receive your message //if we want to accept the request at time we will send a OK instead //we must implement this pseudocode // ********************************************* // if (not accessing resource and do not want to access it) // send OK // else if (currently using resource) // queue request // else if (want to access resource too) // if (timestamp of request is smaller) // send OK // else //own timestamp is smaller // queue request // ********************************************* try{ if (!ServerStatus.getServerStatus()) { return(null); } long id = Convert.ToInt64(requesterId); HostUrl hostUrl = new HostUrl(requesterHostUrl, requesterHostPort); RequestObject requestObject = new RequestObject(id, requesterLogicalClock, hostUrl); //the clock for receiving message will correct here //the clock will correct in the constructor of ExternalLampartClock class based on following rule //LC = Max(LC, LCsender) + 1 String response = null; //if not accessing resource and do not want to access it --> send OK if (currentModifyRequest == null || (currentModifyRequest != null && requestedAppointmentSeqNum != 0 && requestedAppointmentSeqNum != requestedAppointmentSequentialNumber) ) { ExtendedLamportClockObject ELC = new ExtendedLamportClockObject(); //for increasing clock before send response = "true" + "\n"; //Send 'OK' response += " ID:&@[" + ELC.getIdString() + "]#! "; response += " LC:&@[" + ELC.getLogicalClock() + "]#! "; return(response); } //if currently using resource else if (currentModifyRequest != null && !currentModifyRequest.isWaiting() && requestedAppointmentSeqNum != 0 && requestedAppointmentSeqNum == requestedAppointmentSequentialNumber ) { modifyRequestsQueue.add(requestObject); response = "false" + "\n"; //Send 'NOKEY'//means 'you have to wait for me' return(response); } //if want to access resource too else if (currentModifyRequest != null && currentModifyRequest.isWaiting() && requestedAppointmentSeqNum != 0 && requestedAppointmentSeqNum == requestedAppointmentSequentialNumber ) { if (requestObject.getELCO().compare(currentModifyRequest.getELCO()) < 0) //if timestamp of requester is smaller { ExtendedLamportClockObject ELC = new ExtendedLamportClockObject(); //for increasing clock before send response = "true" + "\n"; //Send 'OK' response += " ID:&@[" + ELC.getIdString() + "]#! "; response += " LC:&@[" + ELC.getLogicalClock() + "]#! "; return(response); } else //if own timestamp is smaller { modifyRequestsQueue.add(requestObject); response = "false" + "\n"; //Send 'OK'//means 'you have to wait for me' return(response); } } else { return(null); } }catch (Exception) { return(null); } }