/// <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); }
private static List <ConnectedStations> LoadConnectedStationsFrom(string fileLocation) { var routingDataStore = new RoutingDataStore(); routingDataStore.LoadFrom(fileLocation); return(routingDataStore.ConnectedStations); }
/// <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); }
/// <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); }
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")); }
/// <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); }
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")); }
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)); }
/// <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" }); }
/// <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); }
/// <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" }); }
/// <returns>The connections.</returns> public IList <Connection> GetConnections() { return(RoutingDataStore.GetConnections()); }
/// <returns>The connection requests as a readonly list.</returns> public IList <ConnectionRequest> GetConnectionRequests() { return(RoutingDataStore.GetConnectionRequests()); }
/// <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)); }
/// <returns>The aggregation channels as a readonly list.</returns> public IList <ConversationReference> GetAggregationChannels() { return(RoutingDataStore.GetAggregationChannels()); }
/// <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); }
/// <returns>The bot instances as a readonly list.</returns> public IList <ConversationReference> GetBotInstances() { return(RoutingDataStore.GetBotInstances()); }
/// <returns>The users as a readonly list.</returns> public IList <ConversationReference> GetUsers() { return(RoutingDataStore.GetUsers()); }