/// <summary>
        /// Retrieve the result of the execution of a Command. Two alternative possibilities:
        /// 1) Give the result back to client.
        /// 2) Forward the command.
        /// </summary>
        /// <param name="iAsyncResult">Represent the object which is available after the
        /// asynchronous invocation of Execute(). It gives access to all state information.</param>
        public void ProcessResult(IAsyncResult iAsyncResult)
        {
            /** Retrieve the pair Command-Result. */
            Command command = (Command)iAsyncResult.AsyncState;
            Result  result  = command.EndExecute(iAsyncResult);

            /** Check if the Command has to be forwarded. */
            ForwardRequiredResult checkForward = result as ForwardRequiredResult;

            if (checkForward != null)   //Forward the command
            {
                string service = checkForward.Destination;
                ForwardCommand(command, service, receiver.BaseForwardAddress + receiver.NodeName);
            }
            else    //Give the result to client
            {
                if (debug)
                {
                    TimeSpan totalTime = DateTime.Now.Subtract(command.Timestamp);
                    Console.WriteLine("{0} Total time for {1}: {2}", LogTimestamp, command.GetType().Name, totalTime.TotalMilliseconds);
                }

                if (IsMobileCommand(command.CommandID))
                {
                    Console.WriteLine("\n{0} Ready to send the result back to Mobile", LogTimestamp);
                    mobile.AddMobileResult(command.CommandID, result);
                }
                else
                {
                    IDarPoolingCallback client = ExtractClient(command.CommandID);
                    ReturnResultToClient(result, client);
                }
            }
        }
        public void ProcessResultOfForwardedCommand(IAsyncResult iAsyncResult)
        {
            Command fwdCommand = (Command)iAsyncResult.AsyncState;
            Result  result     = fwdCommand.EndExecute(iAsyncResult);

            /** Check if the Command has to be forwarded. */
            ForwardRequiredResult checkForward = result as ForwardRequiredResult;

            if (checkForward != null)   //Forward the command
            {
                string rootSenderAddress = ExtractService(fwdCommand.CommandID);
                string service           = checkForward.Destination;
                ForwardCommand(fwdCommand, service, rootSenderAddress);
            }
            else
            {
                ReturnFinalResult(result, fwdCommand);
            }
        }
        public Result SearchTrip(QueryBuilder queryTrip)
        {
            // Error! Search range cannot be a negative number!
            if (queryTrip.Range < 0)
            {
                SearchTripError error = new SearchTripError();
                error.Comment = "Search range must be a non-negative number!";
                return error;
            }

            /** Check if the current node is the nearest node to the departure location. */
            string targetNode = NearestNodeToDeparture(queryTrip.DepartureName);

            if (!targetNode.Equals(NodeName))
            {
                Console.WriteLine("Decision: sending SearchTripCommand to : {0}", targetNode);
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + targetNode;

                return forwardRequest;
            }

            // The Search has no range criteria. We can perform a simple search or
            // a simple forward request.
            if (queryTrip.Range == 0)
            {
                Console.WriteLine("Testing Range 0");
                List<Trip> matchingTrip = GetTripZeroRange(queryTrip);

                SearchTripResult searchResult = new SearchTripResult(matchingTrip);
                searchResult.OriginalQueryID = queryTrip.ID;
                Console.WriteLine("{0} {1} Trip(s) were found in {2}", serviceImpl.LogTimestamp, matchingTrip.Count, NodeName);

                return searchResult;

            }
            // The client specified a range for search: we need to do a more complex search
            // and potentially a multiple forwarding.
            else
            {

                Location departureLoc = GMapsAPI.addressToLocation(queryTrip.DepartureName);
                LocationRange departureLocRange = new LocationRange(departureLoc.Latitude, departureLoc.Longitude, queryTrip.Range);

                List<Trip> matchingTrip = GetTripWithRange(queryTrip, departureLocRange);

                SearchTripResult searchResult = new SearchTripResult(matchingTrip);
                searchResult.OriginalQueryID = queryTrip.ID;
                Console.WriteLine("{0} {1} Trip(s) were found in {2}", serviceImpl.LogTimestamp, matchingTrip.Count, NodeName);

                /** Check if there are other neighbour nodes within the range of search. */
                string[] targetNeighbours = NeighbourNodesInRange(departureLocRange);
                if (targetNeighbours.Length > 0)
                {
                    foreach (string n in targetNeighbours)
                    {
                        Console.WriteLine("{0} is in range.", n);
                    }

                    return new NullResult();

                }
                else
                {
                    //Console.WriteLine("No neighbour is in range.");
                    return searchResult;

                }

            }
        }
        /// <summary>
        /// Login the DarPooling Service network using username and password.
        /// Check if the current node is responsible for holding data about the user.
        /// If so, the given credential are checked, otherwise the request is 
        /// scheduled for forwarding.
        /// </summary>
        /// <param name="username">The username provided by the client</param>
        /// <param name="pw_hash">The password provided by the client</param>
        /// <returns>
        /// a Result instance that represent the result of the Join operation; Specifically:
        ///  - a ConnectionErrorResult if the username has an invalid format
        ///  - a LoginErrorResult instance if the credentials don't match in the database
        ///  - a LoginOkResult if the credentials are valid.
        /// </returns>
        public Result Join(string username, string pw_hash)
        {
            Result joinResult;

            // Determine the name of the node where the user registered. Based to
            // the format, it MUST be the final token. Es.  user@baseaddress/NODENAME
            string registrationNode = username.Split('/').Last();

            // The username has an invalid format, i.e. it is impossible to retrieve the
            // name of the node where the user registered
            if (registrationNode.Length == 0 )
            {
                joinResult = new LoginErrorResult();
                joinResult.Comment = "Invalid username and/or password";
                return joinResult;
            }

            // The user has registered in a different node. To confirm the join, we MUST
            // forward the Join request to the appropriate node.
            if (!registrationNode.Equals(this.NodeName))
            {
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + registrationNode;
                forwardRequest.Comment = "You were not registered in this node";
                joinResult = forwardRequest;

                return joinResult;
            }

            // Obtain the Read lock to determine if the user is actually registered.
            userDatabaseLock.EnterReadLock();
            try
            {
                //Console.WriteLine("{0} thread obtain the read lock in Join()", Thread.CurrentThread.Name);

                userDatabase = XDocument.Load(userDatabasePath);

                // Determine if the username and password have a match in the database
                var registeredUserQuery = (from user in userDatabase.Descendants("User")
                                           where user.Element("UserName").Value.Equals(username) &&
                                                 user.Element("Password").Value.Equals(pw_hash)
                                           select user);

                // The provided username and password don't match in the database.
                if (registeredUserQuery.Count() == 0)
                {
                    joinResult = new LoginErrorResult();
                    joinResult.Comment = "Invalid username and/or password";
                    return joinResult;
                }
                else
                {   /** The Login is successful. */
                    LoginOkResult success = new LoginOkResult();
                    success.AuthorizedUsername = username;
                    success.Comment = "Account successfully verified. You can now access DarPooling";
                    joinResult = success;
                    return joinResult;
                }
            }
            finally
            {
                //Console.WriteLine("{0} thread releases the read lock in Join()", Thread.CurrentThread.Name);
                userDatabaseLock.ExitReadLock();
            }
        }
        public Result InsertTrip(Trip newTrip)
        {
            Result insertionResult;

            /** Check if the current node is the nearest node to the
             * departure location.
             */
            string targetNode = NearestNodeToDeparture(newTrip.DepartureName);

            if (!targetNode.Equals(NodeName))
            {
                //Console.WriteLine("Decision: sending newTripCommand to : {0}", targetNode);
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + targetNode;

                return forwardRequest;

            }
            else
            {
                Location departureLoc = GMapsAPI.addressToLocation(newTrip.DepartureName);
                Location arrivalLoc = GMapsAPI.addressToLocation(newTrip.ArrivalName);

                //Save the trip
                tripDatabaseLock.EnterWriteLock();
                try
                {
                    tripDatabase = XDocument.Load(tripDatabasePath);

                    int nextAvailableID = Convert.ToInt32(
                             (from trip in tripDatabase.Descendants("Trip")
                              orderby Convert.ToInt32(trip.Element("ID").Value) descending
                              select trip.Element("ID").Value).FirstOrDefault()) + 1;

                    newTrip.ID = nextAvailableID;

                    XElement newXmlTrip = new XElement("Trip",
                        new XElement("ID", newTrip.ID),
                        new XElement("Owner", newTrip.Owner),
                        new XElement("DepartureName", newTrip.DepartureName.ToLower()),
                        new XElement("DepartureLatitude",departureLoc.Latitude),
                        new XElement("DepartureLongitude",departureLoc.Longitude),
                        new XElement("DepartureDateTime", newTrip.DepartureDateTime),
                        new XElement("ArrivalName", newTrip.ArrivalName.ToLower()),
                        new XElement("ArrivalLatitude", arrivalLoc.Latitude),
                        new XElement("ArrivalLongitude", arrivalLoc.Longitude),
                        new XElement("ArrivalDateTime", newTrip.ArrivalDateTime),
                        new XElement("Smoke", newTrip.Smoke),
                        new XElement("Music", newTrip.Music),
                        new XElement("Cost", newTrip.Cost),
                        new XElement("FreeSits", newTrip.FreeSits),
                        new XElement("Notes", newTrip.Notes),
                        new XElement("Modifiable", newTrip.Modifiable)
                        );
                    tripDatabase.Element("Trips").Add(newXmlTrip);
                    tripDatabase.Save(tripDatabasePath);

                    Console.WriteLine("{0} Trip saved in {1}", serviceImpl.LogTimestamp, NodeName);
                    insertionResult = new InsertOkResult();
                    insertionResult.Comment = "The trip has been successfully inserted";
                    return insertionResult;
                }
                finally
                {
                    tripDatabaseLock.ExitWriteLock();

                }
            }// end else
        }
示例#6
0
        public Result SearchTrip(QueryBuilder queryTrip)
        {
            // Error! Search range cannot be a negative number!
            if (queryTrip.Range < 0)
            {
                SearchTripError error = new SearchTripError();
                error.Comment = "Search range must be a non-negative number!";
                return(error);
            }

            /** Check if the current node is the nearest node to the departure location. */
            string targetNode = NearestNodeToDeparture(queryTrip.DepartureName);

            if (!targetNode.Equals(NodeName))
            {
                Console.WriteLine("Decision: sending SearchTripCommand to : {0}", targetNode);
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID   = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + targetNode;

                return(forwardRequest);
            }

            // The Search has no range criteria. We can perform a simple search or
            // a simple forward request.
            if (queryTrip.Range == 0)
            {
                Console.WriteLine("Testing Range 0");
                List <Trip> matchingTrip = GetTripZeroRange(queryTrip);

                SearchTripResult searchResult = new SearchTripResult(matchingTrip);
                searchResult.OriginalQueryID = queryTrip.ID;
                Console.WriteLine("{0} {1} Trip(s) were found in {2}", serviceImpl.LogTimestamp, matchingTrip.Count, NodeName);

                return(searchResult);
            }
            // The client specified a range for search: we need to do a more complex search
            // and potentially a multiple forwarding.
            else
            {
                Location      departureLoc      = GMapsAPI.addressToLocation(queryTrip.DepartureName);
                LocationRange departureLocRange = new LocationRange(departureLoc.Latitude, departureLoc.Longitude, queryTrip.Range);

                List <Trip> matchingTrip = GetTripWithRange(queryTrip, departureLocRange);

                SearchTripResult searchResult = new SearchTripResult(matchingTrip);
                searchResult.OriginalQueryID = queryTrip.ID;
                Console.WriteLine("{0} {1} Trip(s) were found in {2}", serviceImpl.LogTimestamp, matchingTrip.Count, NodeName);

                /** Check if there are other neighbour nodes within the range of search. */
                string[] targetNeighbours = NeighbourNodesInRange(departureLocRange);
                if (targetNeighbours.Length > 0)
                {
                    foreach (string n in targetNeighbours)
                    {
                        Console.WriteLine("{0} is in range.", n);
                    }

                    return(new NullResult());
                }
                else
                {
                    //Console.WriteLine("No neighbour is in range.");
                    return(searchResult);
                }
            }
        }//End SearchTrip
示例#7
0
        public Result InsertTrip(Trip newTrip)
        {
            Result insertionResult;

            /** Check if the current node is the nearest node to the
             * departure location.
             */
            string targetNode = NearestNodeToDeparture(newTrip.DepartureName);

            if (!targetNode.Equals(NodeName))
            {
                //Console.WriteLine("Decision: sending newTripCommand to : {0}", targetNode);
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID   = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + targetNode;

                return(forwardRequest);
            }
            else
            {
                Location departureLoc = GMapsAPI.addressToLocation(newTrip.DepartureName);
                Location arrivalLoc   = GMapsAPI.addressToLocation(newTrip.ArrivalName);

                //Save the trip
                tripDatabaseLock.EnterWriteLock();
                try
                {
                    tripDatabase = XDocument.Load(tripDatabasePath);

                    int nextAvailableID = Convert.ToInt32(
                        (from trip in tripDatabase.Descendants("Trip")
                         orderby Convert.ToInt32(trip.Element("ID").Value) descending
                         select trip.Element("ID").Value).FirstOrDefault()) + 1;

                    newTrip.ID = nextAvailableID;

                    XElement newXmlTrip = new XElement("Trip",
                                                       new XElement("ID", newTrip.ID),
                                                       new XElement("Owner", newTrip.Owner),
                                                       new XElement("DepartureName", newTrip.DepartureName.ToLower()),
                                                       new XElement("DepartureLatitude", departureLoc.Latitude),
                                                       new XElement("DepartureLongitude", departureLoc.Longitude),
                                                       new XElement("DepartureDateTime", newTrip.DepartureDateTime),
                                                       new XElement("ArrivalName", newTrip.ArrivalName.ToLower()),
                                                       new XElement("ArrivalLatitude", arrivalLoc.Latitude),
                                                       new XElement("ArrivalLongitude", arrivalLoc.Longitude),
                                                       new XElement("ArrivalDateTime", newTrip.ArrivalDateTime),
                                                       new XElement("Smoke", newTrip.Smoke),
                                                       new XElement("Music", newTrip.Music),
                                                       new XElement("Cost", newTrip.Cost),
                                                       new XElement("FreeSits", newTrip.FreeSits),
                                                       new XElement("Notes", newTrip.Notes),
                                                       new XElement("Modifiable", newTrip.Modifiable)
                                                       );
                    tripDatabase.Element("Trips").Add(newXmlTrip);
                    tripDatabase.Save(tripDatabasePath);

                    Console.WriteLine("{0} Trip saved in {1}", serviceImpl.LogTimestamp, NodeName);
                    insertionResult         = new InsertOkResult();
                    insertionResult.Comment = "The trip has been successfully inserted";
                    return(insertionResult);
                }
                finally
                {
                    tripDatabaseLock.ExitWriteLock();
                }
            } // end else
        }     //End savetrip
示例#8
0
        }// End RegisterUser

        /// <summary>
        /// Login the DarPooling Service network using username and password.
        /// Check if the current node is responsible for holding data about the user.
        /// If so, the given credential are checked, otherwise the request is
        /// scheduled for forwarding.
        /// </summary>
        /// <param name="username">The username provided by the client</param>
        /// <param name="pw_hash">The password provided by the client</param>
        /// <returns>
        /// a Result instance that represent the result of the Join operation; Specifically:
        ///  - a ConnectionErrorResult if the username has an invalid format
        ///  - a LoginErrorResult instance if the credentials don't match in the database
        ///  - a LoginOkResult if the credentials are valid.
        /// </returns>
        public Result Join(string username, string pw_hash)
        {
            Result joinResult;

            // Determine the name of the node where the user registered. Based to
            // the format, it MUST be the final token. Es.  user@baseaddress/NODENAME
            string registrationNode = username.Split('/').Last();

            // The username has an invalid format, i.e. it is impossible to retrieve the
            // name of the node where the user registered
            if (registrationNode.Length == 0)
            {
                joinResult         = new LoginErrorResult();
                joinResult.Comment = "Invalid username and/or password";
                return(joinResult);
            }

            // The user has registered in a different node. To confirm the join, we MUST
            // forward the Join request to the appropriate node.
            if (!registrationNode.Equals(this.NodeName))
            {
                ForwardRequiredResult forwardRequest = new ForwardRequiredResult();
                forwardRequest.RequestID   = serviceImpl.generateGUID();
                forwardRequest.Destination = baseForwardAddress + registrationNode;
                forwardRequest.Comment     = "You were not registered in this node";
                joinResult = forwardRequest;

                return(joinResult);
            }

            // Obtain the Read lock to determine if the user is actually registered.
            userDatabaseLock.EnterReadLock();
            try
            {
                //Console.WriteLine("{0} thread obtain the read lock in Join()", Thread.CurrentThread.Name);

                userDatabase = XDocument.Load(userDatabasePath);

                // Determine if the username and password have a match in the database
                var registeredUserQuery = (from user in userDatabase.Descendants("User")
                                           where user.Element("UserName").Value.Equals(username) &&
                                           user.Element("Password").Value.Equals(pw_hash)
                                           select user);

                // The provided username and password don't match in the database.
                if (registeredUserQuery.Count() == 0)
                {
                    joinResult         = new LoginErrorResult();
                    joinResult.Comment = "Invalid username and/or password";
                    return(joinResult);
                }
                else
                {   /** The Login is successful. */
                    LoginOkResult success = new LoginOkResult();
                    success.AuthorizedUsername = username;
                    success.Comment            = "Account successfully verified. You can now access DarPooling";
                    joinResult = success;
                    return(joinResult);
                }
            }
            finally
            {
                //Console.WriteLine("{0} thread releases the read lock in Join()", Thread.CurrentThread.Name);
                userDatabaseLock.ExitReadLock();
            }
        }