ClientWebSocket CreateConnectedClient(ServiceEndPoint endPoint) { if (!endPoint.IsWebSocketEndpoint) { throw new Exception("Only wss:// endpoints are supported"); } var connectionId = Guid.NewGuid().ToString(); var client = new ClientWebSocket(); client.Options.ClientCertificates = new X509Certificate2Collection(new X509Certificate2Collection(clientCertificate)); client.Options.AddSubProtocol("Octopus"); client.Options.SetRequestHeader(ServerCertificateInterceptor.Header, connectionId); if (endPoint.Proxy != null) { client.Options.Proxy = new WebSocketProxy(endPoint.Proxy); } try { ServerCertificateInterceptor.Expect(connectionId); using (var cts = new CancellationTokenSource(endPoint.TcpClientConnectTimeout)) client.ConnectAsync(endPoint.BaseUri, cts.Token) .ConfigureAwait(false).GetAwaiter().GetResult(); ServerCertificateInterceptor.Validate(connectionId, endPoint); } finally { ServerCertificateInterceptor.Remove(connectionId); } return(client); }
public SecureClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionPool<ServiceEndPoint, SecureConnection> pool) { this.serviceEndpoint = serviceEndpoint; this.clientCertificate = clientCertificate; this.log = log; this.pool = pool; }
public HalibutProxy(Func<RequestMessage, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint) : base(contractType) { this.messageRouter = messageRouter; this.contractType = contractType; this.endPoint = endPoint; }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { int index = random.Next(0, endPoints.Length); endPoint = endPoints[index]; return(true); }
public HalibutProxy(Func <RequestMessage, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint) : base(contractType) { this.messageRouter = messageRouter; this.contractType = contractType; this.endPoint = endPoint; }
public void DiscoveringNonExistantEndpointThrows() { var client = new DiscoveryClient(); var fakeEndpoint = new ServiceEndPoint("https://fake-tentacle.example", ""); Assert.Throws <HalibutClientException>(() => client.Discover(fakeEndpoint), "No such host is known"); }
public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint) { try { using (var client = CreateConnectedTcpClient(serviceEndpoint)) { using (var stream = client.GetStream()) { using (var ssl = new SslStream(stream, false, ValidateCertificate)) { ssl.AuthenticateAsClientAsync(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false) .GetAwaiter() .GetResult(); ssl.Write(HelloLine, 0, HelloLine.Length); ssl.Flush(); if (ssl.RemoteCertificate == null) { throw new Exception("The server did not provide an SSL certificate"); } return(new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint)); } } } } catch (Exception ex) { throw new HalibutClientException(ex.Message, ex); } }
private static IServiceTopology ParseMapServiceTopology(string endPointsText) { var pairStrings = endPointsText.Split(Comma, StringSplitOptions.RemoveEmptyEntries); ServiceEndPoint?nullEndPoint = null; var pairs = new List <KeyValuePair <string, ServiceEndPoint> >(pairStrings.Length); foreach (var pairString in pairStrings) { var match = MapElementRegex.Match(pairString.Trim()); if (!match.Success) { throw new InvalidDataException(string.Format("'{0}' is not a valid map service topology element", pairString.Trim())); } var key = match.Groups[1].Value; var endPoint = ServiceEndPoint.Parse(match.Groups[2].Value); if (key == "@null") { nullEndPoint = endPoint; } else { pairs.Add(new KeyValuePair <string, ServiceEndPoint>(key, endPoint)); } } return(new MapServiceTopology(nullEndPoint, pairs)); }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { endPoint = scope == null ? endPoints[0] : endPoints[(uint)scope.GetHashCode() % endPoints.Length]; return(true); }
public UnexpectedCertificateException(X509Certificate2 providedCert, ServiceEndPoint endPoint) : base(string.Format(Text, endPoint.BaseUri, endPoint.RemoteThumbprint, providedCert.Thumbprint, providedCert.Subject)) { ServerUrl = endPoint.BaseUri; ProvidedCert = providedCert; ExpectedThumbprint = endPoint.RemoteThumbprint; }
public SecureWebSocketClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionManager connectionManager) { this.serviceEndpoint = serviceEndpoint; this.clientCertificate = clientCertificate; this.log = log; this.connectionManager = connectionManager; }
public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint, CancellationToken cancellationToken) { try { var log = logs.ForEndpoint(serviceEndpoint.BaseUri); using (var client = TcpConnectionFactory.CreateConnectedTcpClient(serviceEndpoint, log, cancellationToken)) { using (var stream = client.GetStream()) { using (var ssl = new SslStream(stream, false, ValidateCertificate)) { ssl.AuthenticateAsClient(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false); ssl.Write(HelloLine, 0, HelloLine.Length); ssl.Flush(); if (ssl.RemoteCertificate == null) { throw new Exception("The server did not provide an SSL certificate"); } #pragma warning disable PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS return(new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint)); #pragma warning restore PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS } } } } catch (Exception ex) { throw new HalibutClientException(ex.Message, ex); } }
public SecureClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionPool <ServiceEndPoint, IConnection> pool) { this.serviceEndpoint = serviceEndpoint; this.clientCertificate = clientCertificate; this.log = log; this.pool = pool; }
public void ClearPooledConnections(ServiceEndPoint serviceEndPoint, ILog log) { lock (activeConnections) { pool.Clear(serviceEndPoint, log); } }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { endPoint = scope == null ? endPoints[0] : endPoints[scope.GetHashCode() % endPoints.Length]; return true; }
public IConnection AcquireConnection(IConnectionFactory connectionFactory, ServiceEndPoint serviceEndpoint, ILog log, CancellationToken cancellationToken) { var openableConnection = GetConnection(connectionFactory, serviceEndpoint, log, cancellationToken); openableConnection.Item2(); // Since this involves IO, this should never be done inside a lock return(openableConnection.Item1); }
public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint) { try { using (var client = CreateConnectedTcpClient(serviceEndpoint)) { using (var stream = client.GetStream()) { using (var ssl = new SslStream(stream, false, ValidateCertificate)) { ssl.AuthenticateAsClientAsync(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false) .GetAwaiter() .GetResult(); ssl.Write(HelloLine, 0, HelloLine.Length); ssl.Flush(); if (ssl.RemoteCertificate == null) throw new Exception("The server did not provide an SSL certificate"); return new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint); } } } } catch (Exception ex) { throw new HalibutClientException(ex.Message, ex); } }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { endPoint = scope == null ? endPoints[0] : endPoints[(uint)GetStableHashCode(scope) % endPoints.Length]; return true; }
public override bool Equals(object obj) { if (obj == null) { return(false); } return(ServiceEndPoint.Equals(((PeerInfo)obj).ServiceEndPoint)); }
public bool Equals(PeerInfo other) { if (other == null) { return(false); } return(ServiceEndPoint.Equals(other.ServiceEndPoint)); }
public HalibutProxy(Func <RequestMessage, CancellationToken, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint, CancellationToken cancellationToken) : base(contractType) { this.messageRouter = messageRouter; this.contractType = contractType; this.endPoint = endPoint; this.cancellationToken = cancellationToken; }
private EventsPublishedByService(ServiceEndPoint serviceEndPoint, IEnumerable <EventSchema> publishedEventTypes, bool isReachable) { ServiceEndPoint = serviceEndPoint; PublishedEventTypes = publishedEventTypes; IsReachable = isReachable; }
public void EndPoint() { ServiceEndPoint endPoint; Assert.That(ServiceEndPoint.TryParse(@"http://some-host.com:12345", out endPoint), Is.True); Assert.That(endPoint.Protocol, Is.EqualTo("http")); Assert.That(endPoint.Host, Is.EqualTo("some-host.com")); Assert.That(endPoint.Port, Is.EqualTo(12345)); }
public IConnection AcquireConnection(IConnectionFactory connectionFactory, ServiceEndPoint serviceEndpoint, ILog log) { lock (activeConnections) { var connection = pool.Take(serviceEndpoint) ?? CreateConnection(connectionFactory, serviceEndpoint, log); AddConnectionToActiveConnections(serviceEndpoint, connection); return(connection); } }
public void SetUp() { var services = new DelegateServiceFactory(); services.Register<IEchoService>(() => new EchoService()); tentacle = new HalibutRuntime(services, Certificates.TentacleListening); var tentaclePort = tentacle.Listen(); tentacle.Trust(Certificates.OctopusPublicThumbprint); endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint); log = new InMemoryConnectionLog(endpoint.ToString()); HalibutLimits.ConnectionErrorRetryTimeout = TimeSpan.MaxValue; }
public void ReleaseConnection(ServiceEndPoint serviceEndpoint, IConnection connection) { lock (activeConnections) { pool.Return(serviceEndpoint, connection); if (activeConnections.TryGetValue(serviceEndpoint, out var connections)) { connections.Remove(connection); } } }
public IReadOnlyCollection <IConnection> GetActiveConnections(ServiceEndPoint serviceEndPoint) { lock (activeConnections) { if (activeConnections.TryGetValue(serviceEndPoint, out var value)) { return(value.ToArray()); } } return(NoConnections); }
public void DisconnectDisposesActiveConnections() { var serviceEndpoint = new ServiceEndPoint("https://localhost:42", Certificates.TentacleListeningPublicThumbprint); var connectionManager = new ConnectionManager(); var activeConnection = connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString())); connectionManager.GetActiveConnections(serviceEndpoint).Should().OnlyContain(c => c == activeConnection); connectionManager.Disconnect(serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString())); connectionManager.GetActiveConnections(serviceEndpoint).Should().BeNullOrEmpty(); }
public void DisposedConnectionsAreRemovedFromActive_WhenMultipleConnectionsAreActive() { var serviceEndpoint = new ServiceEndPoint("https://localhost:42", Certificates.TentacleListeningPublicThumbprint); var connectionManager = new ConnectionManager(); //do it twice because this bug only triggers on multiple enumeration, having 1 in the collection doesn't trigger the bug connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString())); connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString())); connectionManager.Disconnect(serviceEndpoint, null); connectionManager.GetActiveConnections(serviceEndpoint).Should().BeNullOrEmpty(); }
void ClearActiveConnections(ServiceEndPoint serviceEndPoint, ILog log) { lock (activeConnections) { if (activeConnections.TryGetValue(serviceEndPoint, out var activeConnectionsForEndpoint)) { foreach (var connection in activeConnectionsForEndpoint.ToArray()) { SafelyDisposeConnection(connection, log); } } } }
public SecureClientFixture() { var services = new DelegateServiceFactory(); services.Register <IEchoService>(() => new EchoService()); tentacle = new HalibutRuntime(services, Certificates.TentacleListening); var tentaclePort = tentacle.Listen(); tentacle.Trust(Certificates.OctopusPublicThumbprint); endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint); log = new InMemoryConnectionLog(endpoint.ToString()); HalibutLimits.ConnectionErrorRetryTimeout = TimeSpan.MaxValue; }
void AddConnectionToActiveConnections(ServiceEndPoint serviceEndpoint, IConnection connection) { if (activeConnections.TryGetValue(serviceEndpoint, out var connections)) { connections.Add(connection); } else { connections = new HashSet <IConnection> { connection }; activeConnections.Add(serviceEndpoint, connections); } }
public void SetUp() { var services = new DelegateServiceFactory(); services.Register <IEchoService>(() => new EchoService()); tentacle = new HalibutRuntime(services, Certificates.TentacleListening); var tentaclePort = tentacle.Listen(); tentacle.Trust(Certificates.OctopusPublicThumbprint); endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint) { ConnectionErrorRetryTimeout = TimeSpan.MaxValue }; }
ClientWebSocket CreateConnectedClient(ServiceEndPoint serviceEndpoint, CancellationToken cancellationToken) { if (!serviceEndpoint.IsWebSocketEndpoint) { throw new Exception("Only wss:// endpoints are supported"); } var connectionId = Guid.NewGuid().ToString(); var client = new ClientWebSocket(); client.Options.ClientCertificates = new X509Certificate2Collection(new X509Certificate2Collection(clientCertificate)); client.Options.AddSubProtocol("Octopus"); client.Options.SetRequestHeader(ServerCertificateInterceptor.Header, connectionId); if (serviceEndpoint.Proxy != null) { client.Options.Proxy = new WebSocketProxy(serviceEndpoint.Proxy); } try { ServerCertificateInterceptor.Expect(connectionId); using (var cts = new CancellationTokenSource(serviceEndpoint.TcpClientConnectTimeout)) { using (cancellationToken.Register(() => cts?.Cancel())) client.ConnectAsync(serviceEndpoint.BaseUri, cts.Token) .ConfigureAwait(false).GetAwaiter().GetResult(); } ServerCertificateInterceptor.Validate(connectionId, serviceEndpoint); } catch { if (client.State == WebSocketState.Open) { using (var sendCancel = new CancellationTokenSource(TimeSpan.FromSeconds(1))) client.CloseAsync(WebSocketCloseStatus.ProtocolError, "Certificate thumbprint not recognised", sendCancel.Token) .ConfigureAwait(false).GetAwaiter().GetResult(); } client.Dispose(); throw; } finally { ServerCertificateInterceptor.Remove(connectionId); } return(client); }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { if (scope == null) { if (nullEndPoint.HasValue) { endPoint = nullEndPoint.Value; return(true); } endPoint = default(ServiceEndPoint); return(false); } return(endPoints.TryGetValue(scope, out endPoint)); }
public static void Validate(string connectionId, ServiceEndPoint endPoint) { X509Certificate2 providedCertificate; lock (certificates) if (!certificates.TryGetValue(connectionId, out providedCertificate)) { throw new Exception("Did not recieve a certificate from the server"); } if (providedCertificate.Thumbprint != endPoint.RemoteThumbprint) { throw new UnexpectedCertificateException(providedCertificate, endPoint); } }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { if (scope == null) { if (nullEndPoint.HasValue) { endPoint = nullEndPoint.Value; return true; } endPoint = default(ServiceEndPoint); return false; } return endPoints.TryGetValue(scope, out endPoint); }
TcpClient CreateConnectedTcpClient(ServiceEndPoint endPoint) { TcpClient client; if (endPoint.Proxy == null) { client = CreateTcpClient(); client.ConnectWithTimeout(endPoint.BaseUri, HalibutLimits.TcpClientConnectTimeout); } else { var log = logs.ForEndpoint(endPoint.BaseUri); log.Write(EventType.Diagnostic, "Creating a proxy client"); client = new ProxyClientFactory() .CreateProxyClient(log, endPoint.Proxy) .WithTcpClientFactory(CreateTcpClient) .CreateConnection(endPoint.BaseUri.Host, endPoint.BaseUri.Port, HalibutLimits.TcpClientConnectTimeout); } return client; }
private static void AssertEndPoint(IReadOnlyDictionary<string, IServiceTopology> topology, string serviceName, string scope, ServiceEndPoint expectedEndPoint) { IServiceTopology serviceTopology; ServiceEndPoint endPoint; Assert.That(topology.TryGetValue(serviceName, out serviceTopology), Is.True); Assert.That(serviceTopology.TryGetEndPoint(scope, out endPoint), Is.True); Assert.That(endPoint, Is.EqualTo(expectedEndPoint)); }
public SingleHostServiceTopology(ServiceEndPoint endPoint) { this.endPoint = endPoint; }
public HostSettings(ServiceEndPoint endPoint, IEnumerable<InterfaceImplementationTypePair> interfaceImplementationTypePairs) { this.endPoint = endPoint; this.interfaceImplementationTypePairs = interfaceImplementationTypePairs.ToArray(); }
public MapServiceTopology(ServiceEndPoint? nullEndPoint, IEnumerable<KeyValuePair<string, ServiceEndPoint>> endPoints) { this.nullEndPoint = nullEndPoint; this.endPoints = endPoints.ToDictionary(x => x.Key, x => x.Value); }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { return ServiceEndPoint.TryParse(scope, out endPoint); }
public ClientCertificateValidator(ServiceEndPoint endPoint) { this.endPoint = endPoint; }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { endPoint = this.endPoint; return true; }
public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint) { int index = random.Next(0, endPoints.Length); endPoint = endPoints[index]; return true; }
public void PollingMode(Uri subscription, ServiceEndPoint octopusServer) { tentacleHalibutRuntime.Poll(subscription, octopusServer); Text = "Tentacle: polling, subscription: " + subscription; }