コード例 #1
0
        /// <summary>
        /// Disconnects the given connection.
        /// </summary>
        /// <param name="connectionToDisconnect">The connection to disconnect.</param>
        /// <returns>The result of the operation:
        /// - ConnectionResultType.Disconnected,
        /// - ConnectionResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ConnectionResult Disconnect(Connection connectionToDisconnect)
        {
            ConnectionResult disconnectResult = new ConnectionResult()
            {
                Connection = connectionToDisconnect
            };

            foreach (Connection connection in GetConnections())
            {
                if (connectionToDisconnect.Equals(connection))
                {
                    if (RoutingDataStore.RemoveConnection(connectionToDisconnect))
                    {
                        disconnectResult.Type = ConnectionResultType.Disconnected;
                    }
                    else
                    {
                        disconnectResult.Type         = ConnectionResultType.Error;
                        disconnectResult.ErrorMessage = "Failed to remove the connection";
                    }

                    break;
                }
            }

            return(disconnectResult);
        }
コード例 #2
0
        private static List <ConnectedStations> LoadConnectedStationsFrom(string fileLocation)
        {
            var routingDataStore = new RoutingDataStore();

            routingDataStore.LoadFrom(fileLocation);
            return(routingDataStore.ConnectedStations);
        }
コード例 #3
0
        /// <summary>
        /// Adds the given connection and clears the connection request associated with the given
        /// conversation reference instance, if one exists.
        /// </summary>
        /// <param name="connectionToAdd">The connection to add.</param>
        /// <param name="requestor">The requestor.</param>
        /// <returns>The result of the operation:
        /// - ConnectionResultType.Connected,
        /// - ConnectionResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ConnectionResult ConnectAndRemoveConnectionRequest(
            Connection connectionToAdd, ConversationReference requestor)
        {
            ConnectionResult connectResult = new ConnectionResult()
            {
                Connection = connectionToAdd
            };

            connectionToAdd.TimeSinceLastActivity = GetCurrentGlobalTime();
            bool wasConnectionAdded = RoutingDataStore.AddConnection(connectionToAdd);

            if (wasConnectionAdded)
            {
                ConnectionRequest acceptedConnectionRequest = FindConnectionRequest(requestor);

                if (acceptedConnectionRequest == null)
                {
                    _logger.Log("Failed to find the connection request to remove");
                }
                else
                {
                    RemoveConnectionRequest(acceptedConnectionRequest);
                }

                connectResult.Type = ConnectionResultType.Connected;
                connectResult.ConnectionRequest = acceptedConnectionRequest;
            }
            else
            {
                connectResult.Type         = ConnectionResultType.Error;
                connectResult.ErrorMessage = $"Failed to add the connection {connectionToAdd}";
            }

            return(connectResult);
        }
コード例 #4
0
        /// <summary>
        /// Removes the connection request of the user with the given conversation reference.
        /// </summary>
        /// <param name="connectionRequestToRemove">The connection request to remove.</param>
        /// <returns>The result of the operation:
        /// - ConnectionRequestResultType.Rejected or
        /// - ConnectionRequestResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ConnectionRequestResult RemoveConnectionRequest(ConnectionRequest connectionRequestToRemove)
        {
            if (connectionRequestToRemove == null)
            {
                throw new ArgumentNullException("Connection request is null");
            }

            ConnectionRequestResult removeConnectionRequestResult = new ConnectionRequestResult
            {
                ConnectionRequest = connectionRequestToRemove
            };

            if (GetConnectionRequests().Contains(connectionRequestToRemove))
            {
                if (RoutingDataStore.RemoveConnectionRequest(connectionRequestToRemove))
                {
                    removeConnectionRequestResult.Type = ConnectionRequestResultType.Rejected;
                }
                else
                {
                    removeConnectionRequestResult.Type         = ConnectionRequestResultType.Error;
                    removeConnectionRequestResult.ErrorMessage = "Failed to remove the connection request associated with the given user";
                }
            }
            else
            {
                removeConnectionRequestResult.Type         = ConnectionRequestResultType.Error;
                removeConnectionRequestResult.ErrorMessage = "Could not find a connection request associated with the given user";
            }

            return(removeConnectionRequestResult);
        }
コード例 #5
0
        public void Should_throw_exception_if_routing_data_can_not_be_found()
        {
            var routingDataStore = new RoutingDataStore();

            var exception = Assert.Throws <FileNotFoundException>(() => routingDataStore.LoadFrom("test-data.txt"));

            Assert.That(exception.Message, Is.EqualTo("Routing data file could not be found"));
        }
コード例 #6
0
        /// <summary>
        /// Updates the time since last activity property of the given connection instance.
        /// </summary>
        /// <param name="connection">The connection to update.</param>
        /// <returns>True, if the connection was updated successfully. False otherwise.</returns>
        public virtual bool UpdateTimeSinceLastActivity(Connection connection)
        {
            if (RoutingDataStore.RemoveConnection(connection))
            {
                connection.TimeSinceLastActivity = GetCurrentGlobalTime();
                return(RoutingDataStore.AddConnection(connection));
            }

            return(false);
        }
コード例 #7
0
        public void Should_throw_exception_if_routing_data_file_is_empty()
        {
            File.WriteAllText("test-data.txt", "");

            var routingDataStore = new RoutingDataStore();

            var exception = Assert.Throws <FileLoadException>(() => routingDataStore.LoadFrom("test-data.txt"));

            Assert.That(exception.Message, Is.EqualTo("Routing data file contained no data"));
        }
コード例 #8
0
        public void Should_populate_connected_stations_from_data_file()
        {
            File.WriteAllText("test-data.txt", "AB4, BC5, DC6");

            var routingDataStore = new RoutingDataStore();

            routingDataStore.LoadFrom("test-data.txt");

            var firstConnectedStation = routingDataStore.ConnectedStations.First();

            Assert.That(firstConnectedStation.StartStation, Is.EqualTo("A"));
            Assert.That(firstConnectedStation.EndStation, Is.EqualTo("B"));
            Assert.That(firstConnectedStation.Distance, Is.EqualTo(4));

            Assert.That(routingDataStore.ConnectedStations.Count(), Is.EqualTo(3));
        }
コード例 #9
0
        /// <summary>
        /// Adds the given aggregation channel.
        /// </summary>
        /// <param name="aggregationChannelToAdd">The aggregation channel to add.</param>
        /// <returns>The result of the operation with type:
        /// - ModifyRoutingDataResultType.Added,
        /// - ModifyRoutingDataResultType.AlreadyExists or
        /// - ModifyRoutingDataResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ModifyRoutingDataResult AddAggregationChannel(ConversationReference aggregationChannelToAdd)
        {
            if (aggregationChannelToAdd == null)
            {
                throw new ArgumentNullException("The given conversation reference is null");
            }

            if (GetChannelAccount(aggregationChannelToAdd) != null)
            {
                throw new ArgumentException("The conversation reference instance for an aggregation channel cannot contain a channel account");
            }

            if (string.IsNullOrWhiteSpace(aggregationChannelToAdd.ChannelId) ||
                aggregationChannelToAdd.Conversation == null ||
                string.IsNullOrWhiteSpace(aggregationChannelToAdd.Conversation.Id))
            {
                return(new ModifyRoutingDataResult()
                {
                    Type = ModifyRoutingDataResultType.Error,
                    ErrorMessage = "Aggregation channel must contain a valid channel and conversation ID"
                });
            }

            IList <ConversationReference> aggregationParties = GetAggregationChannels();

            if (Contains(aggregationParties, aggregationChannelToAdd))
            {
                return(new ModifyRoutingDataResult()
                {
                    Type = ModifyRoutingDataResultType.AlreadyExists
                });
            }

            if (RoutingDataStore.AddAggregationChannel(aggregationChannelToAdd))
            {
                return(new ModifyRoutingDataResult()
                {
                    Type = ModifyRoutingDataResultType.Added
                });
            }

            return(new ModifyRoutingDataResult()
            {
                Type = ModifyRoutingDataResultType.Error,
                ErrorMessage = "Failed to add the aggregation channel"
            });
        }
コード例 #10
0
        /// <summary>
        /// Adds the given connection request.
        /// </summary>
        /// <param name="connectionRequestToAdd">The connection request to add.</param>
        /// <param name="rejectConnectionRequestIfNoAggregationChannel">
        /// If true, will reject all requests, if there is no aggregation channel.</param>
        /// <returns>The result of the operation:
        /// - ConnectionRequestResultType.Created,
        /// - ConnectionRequestResultType.AlreadyExists,
        /// - ConnectionRequestResultType.NotSetup or
        /// - ConnectionRequestResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ConnectionRequestResult AddConnectionRequest(
            ConnectionRequest connectionRequestToAdd, bool rejectConnectionRequestIfNoAggregationChannel = false)
        {
            if (connectionRequestToAdd == null)
            {
                throw new ArgumentNullException("Connection request is null");
            }

            ConnectionRequestResult addConnectionRequestResult = new ConnectionRequestResult()
            {
                ConnectionRequest = connectionRequestToAdd
            };

            if (GetConnectionRequests().Contains(connectionRequestToAdd))
            {
                addConnectionRequestResult.Type = ConnectionRequestResultType.AlreadyExists;
            }
            else
            {
                if (!GetAggregationChannels().Any() && rejectConnectionRequestIfNoAggregationChannel)
                {
                    addConnectionRequestResult.Type = ConnectionRequestResultType.NotSetup;
                }
                else
                {
                    connectionRequestToAdd.ConnectionRequestTime = GetCurrentGlobalTime();

                    if (RoutingDataStore.AddConnectionRequest(connectionRequestToAdd))
                    {
                        addConnectionRequestResult.Type = ConnectionRequestResultType.Created;
                    }
                    else
                    {
                        addConnectionRequestResult.Type         = ConnectionRequestResultType.Error;
                        addConnectionRequestResult.ErrorMessage = "Failed to add the connection request - this is likely an error caused by the storage implementation";
                    }
                }
            }

            return(addConnectionRequestResult);
        }
コード例 #11
0
        /// <summary>
        /// Adds the given ConversationReference.
        /// </summary>
        /// <param name="conversationReferenceToAdd">The new ConversationReference to add.</param>
        /// <returns>The result of the operation with type:
        /// - ModifyRoutingDataResultType.Added,
        /// - ModifyRoutingDataResultType.AlreadyExists or
        /// - ModifyRoutingDataResultType.Error (see the error message for more details).
        /// </returns>
        public virtual ModifyRoutingDataResult AddConversationReference(ConversationReference conversationReferenceToAdd)
        {
            if (conversationReferenceToAdd == null)
            {
                throw new ArgumentNullException("The given conversation reference is null");
            }

            if (conversationReferenceToAdd.Bot == null &&
                conversationReferenceToAdd.User == null)
            {
                throw new ArgumentNullException("Both channel accounts in the conversation reference cannot be null");
            }

            if (IsBot(conversationReferenceToAdd)
                    ? Contains(GetBotInstances(), conversationReferenceToAdd)
                    : Contains(GetUsers(), conversationReferenceToAdd))
            {
                return(new ModifyRoutingDataResult()
                {
                    Type = ModifyRoutingDataResultType.AlreadyExists
                });
            }

            if (RoutingDataStore.AddConversationReference(conversationReferenceToAdd))
            {
                return(new ModifyRoutingDataResult()
                {
                    Type = ModifyRoutingDataResultType.Added
                });
            }

            return(new ModifyRoutingDataResult()
            {
                Type = ModifyRoutingDataResultType.Error,
                ErrorMessage = "Failed to add the conversation reference"
            });
        }
コード例 #12
0
 /// <returns>The connections.</returns>
 public IList <Connection> GetConnections()
 {
     return(RoutingDataStore.GetConnections());
 }
コード例 #13
0
 /// <returns>The connection requests as a readonly list.</returns>
 public IList <ConnectionRequest> GetConnectionRequests()
 {
     return(RoutingDataStore.GetConnectionRequests());
 }
コード例 #14
0
 /// <summary>
 /// Removes the given aggregation channel.
 /// </summary>
 /// <param name="aggregationChannelToRemove">The aggregation channel to remove.</param>
 /// <returns>True, if removed successfully. False otherwise.</returns>
 public virtual bool RemoveAggregationChannel(ConversationReference aggregationChannelToRemove)
 {
     return(RoutingDataStore.RemoveAggregationChannel(aggregationChannelToRemove));
 }
コード例 #15
0
 /// <returns>The aggregation channels as a readonly list.</returns>
 public IList <ConversationReference> GetAggregationChannels()
 {
     return(RoutingDataStore.GetAggregationChannels());
 }
コード例 #16
0
        /// <summary>
        /// Removes the specified ConversationReference from all possible containers.
        /// </summary>
        /// <param name="conversationReferenceToRemove">The ConversationReference to remove.</param>
        /// <returns>A list of operation result(s).</returns>
        public virtual IList <AbstractMessageRouterResult> RemoveConversationReference(
            ConversationReference conversationReferenceToRemove)
        {
            if (conversationReferenceToRemove == null)
            {
                throw new ArgumentNullException("The given conversation reference is null");
            }

            List <AbstractMessageRouterResult> messageRouterResults = new List <AbstractMessageRouterResult>();
            bool wasRemoved = false;

            // Check users and bots
            IList <ConversationReference> conversationReferenceToSearch =
                IsBot(conversationReferenceToRemove) ? GetBotInstances() : GetUsers();

            IList <ConversationReference> conversationReferencesToRemove = FindConversationReferences(
                conversationReferenceToSearch, null, null,
                GetChannelAccount(conversationReferenceToRemove)?.Id);

            foreach (ConversationReference conversationReference in conversationReferencesToRemove)
            {
                if (RoutingDataStore.RemoveConversationReference(conversationReference))
                {
                    messageRouterResults.Add(new ModifyRoutingDataResult()
                    {
                        Type = ModifyRoutingDataResultType.Removed
                    });
                }
                else
                {
                    messageRouterResults.Add(new ModifyRoutingDataResult()
                    {
                        Type         = ModifyRoutingDataResultType.Error,
                        ErrorMessage = "Failed to remove conversation reference"
                    });
                }
            }

            // Check connection requests
            wasRemoved = true;

            while (wasRemoved)
            {
                wasRemoved = false;

                foreach (ConnectionRequest connectionRequest in GetConnectionRequests())
                {
                    if (Match(conversationReferenceToRemove, connectionRequest.Requestor))
                    {
                        ConnectionRequestResult removeConnectionRequestResult =
                            RemoveConnectionRequest(connectionRequest);

                        if (removeConnectionRequestResult.Type == ConnectionRequestResultType.Rejected)
                        {
                            wasRemoved = true;
                            messageRouterResults.Add(removeConnectionRequestResult);
                            break;
                        }
                    }
                }
            }

            // Check the connections
            wasRemoved = true;

            while (wasRemoved)
            {
                wasRemoved = false;

                foreach (Connection connection in GetConnections())
                {
                    if (Match(conversationReferenceToRemove, connection.ConversationReference1) ||
                        Match(conversationReferenceToRemove, connection.ConversationReference2))
                    {
                        wasRemoved = true;
                        messageRouterResults.Add(Disconnect(connection)); // TODO: Check that the disconnect was successful
                        break;
                    }
                }
            }

            return(messageRouterResults);
        }
コード例 #17
0
 /// <returns>The bot instances as a readonly list.</returns>
 public IList <ConversationReference> GetBotInstances()
 {
     return(RoutingDataStore.GetBotInstances());
 }
コード例 #18
0
 /// <returns>The users as a readonly list.</returns>
 public IList <ConversationReference> GetUsers()
 {
     return(RoutingDataStore.GetUsers());
 }