/// <inheritdoc/> public void RegisterSubscription(ISubscription subscription) { var id = new ConnectionIdentifier(subscription.Connection); _lock.Wait(); try { if (!_sessions.TryGetValue(id, out var wrapper)) { wrapper = new SessionWrapper() { Id = id.ToString(), MissedKeepAlives = 0, MaxKeepAlives = (int)_clientConfig.MaxKeepAliveCount, State = SessionState.Init, Session = null, IdleCount = 0 }; _sessions.AddOrUpdate(id, wrapper); } wrapper._subscriptions.AddOrUpdate(subscription.Id, subscription); _logger.Information("Subscription '{subscriptionId}' registered/updated in session '{id}' in state {state}", subscription.Id, id, wrapper.State); if (wrapper.State == SessionState.Running) { wrapper.State = SessionState.Refresh; } TriggerKeepAlive(); } finally { _lock.Release(); } }
/// <inheritdoc/> public async Task <Session> GetOrCreateSessionAsync(ConnectionModel connection, bool createIfNotExists) { // Find session and if not exists create var id = new ConnectionIdentifier(connection); await _lock.WaitAsync(); try { if (!_sessions.TryGetValue(id, out var wrapper) && createIfNotExists) { var sessionName = id.ToString(); var applicationConfiguration = _clientConfig.ToApplicationConfiguration(true); var endpointConfiguration = _clientConfig.ToEndpointConfiguration(); var endpointDescription = new EndpointDescription(id.Connection.Endpoint.Url); var configuredEndpoint = new ConfiguredEndpoint( null, endpointDescription, endpointConfiguration); _logger.Information("Trying to create session {sessionName}...", sessionName); using (new PerfMarker(_logger, sessionName)) { var userIdentity = connection.User.ToStackModel() ?? new UserIdentity(new AnonymousIdentityToken()); var session = await Session.Create( applicationConfiguration, configuredEndpoint, true, sessionName, _clientConfig.DefaultSessionTimeout, userIdentity, null); _logger.Information($"Session '{sessionName}' created."); _logger.Information("Loading Complex Type System...."); var complexTypeSystem = new ComplexTypeSystem(session); await complexTypeSystem.Load(); _logger.Information("Complex Type system loaded."); if (_clientConfig.KeepAliveInterval > 0) { session.KeepAliveInterval = _clientConfig.KeepAliveInterval; session.KeepAlive += Session_KeepAlive; } wrapper = new SessionWrapper { MissedKeepAlives = 0, MaxKeepAlives = _clientConfig.MaxKeepAliveCount, Session = session }; _sessions.Add(id, wrapper); } } return(wrapper?.Session); } finally { _lock.Release(); } }
/// <inheritdoc/> public Session GetOrCreateSession(ConnectionModel connection, bool createIfNotExists) { // Find session and if not exists create var id = new ConnectionIdentifier(connection); _lock.Wait(); try { // try to get an existing session if (!_sessions.TryGetValue(id, out var wrapper)) { if (!createIfNotExists) { return(null); } wrapper = new SessionWrapper() { Id = id.ToString(), MissedKeepAlives = 0, // TODO this seem not to be the appropriate configuration argument MaxKeepAlives = (int)_clientConfig.MaxKeepAliveCount, State = SessionState.Init, Session = null, ReportedStatus = StatusCodes.Good, IdleCount = 0 }; _sessions.AddOrUpdate(id, wrapper); TriggerKeepAlive(); } switch (wrapper.State) { case SessionState.Running: case SessionState.Refresh: return(wrapper.Session); case SessionState.Retry: case SessionState.Init: case SessionState.Failed: case SessionState.Disconnect: break; default: throw new InvalidOperationException($"Illegal SessionState ({wrapper.State})"); } } catch (Exception ex) { _logger.Error(ex, "Failed to get/create session for Id '{id}'", id); } finally { _lock.Release(); } return(null); }
/// <inheritdoc/> public async Task <Session> GetOrCreateSessionAsync(ConnectionModel connection, bool createIfNotExists) { // Find session and if not exists create var id = new ConnectionIdentifier(connection); await _lock.WaitAsync(); try { if (!_sessions.TryGetValue(id, out var wrapper) && createIfNotExists) { var sessionName = id.ToString(); var applicationConfiguration = _clientConfig.ToApplicationConfiguration(true); var endpointConfiguration = _clientConfig.ToEndpointConfiguration(); var endpointDescription = SelectEndpoint(id.Connection.Endpoint.Url, id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy, (int)(connection.Endpoint.OperationTimeout.HasValue ? connection.Endpoint.OperationTimeout.Value.TotalMilliseconds : defaultOperationTimeout)); if (endpointDescription == null) { throw new EndpointNotAvailableException(id.Connection.Endpoint.Url, id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy); } if (id.Connection.Endpoint.SecurityMode.HasValue && id.Connection.Endpoint.SecurityMode != SecurityMode.None && endpointDescription.SecurityMode == MessageSecurityMode.None) { _logger.Warning("Although the use of security was configured, there was no security-enabled endpoint available at url {endpointUrl}. An endpoint with no security will be used.", id.Connection.Endpoint.Url); } var configuredEndpoint = new ConfiguredEndpoint( null, endpointDescription, endpointConfiguration); _logger.Information("Trying to create session {sessionName}...", sessionName); using (new PerfMarker(_logger, sessionName)) { var userIdentity = connection.User.ToStackModel() ?? new UserIdentity(new AnonymousIdentityToken()); var session = await Session.Create( applicationConfiguration, configuredEndpoint, true, sessionName, _clientConfig.DefaultSessionTimeout, userIdentity, null); _logger.Information($"Session '{sessionName}' created."); _logger.Information("Loading Complex Type System...."); try { var complexTypeSystem = new ComplexTypeSystem(session); await complexTypeSystem.Load(); _logger.Information("Complex Type system loaded."); } catch (Exception ex) { _logger.Error(ex, "Failed to load Complex Type System"); } if (_clientConfig.KeepAliveInterval > 0) { session.KeepAliveInterval = _clientConfig.KeepAliveInterval; session.KeepAlive += Session_KeepAlive; } wrapper = new SessionWrapper { MissedKeepAlives = 0, MaxKeepAlives = _clientConfig.MaxKeepAliveCount, Session = session }; _sessions.Add(id, wrapper); } } return(wrapper?.Session); } finally { _lock.Release(); } }
/// <summary> /// Create session against endpoint /// </summary> /// <param name="endpointUrl"></param> /// <param name="id"></param> /// <returns></returns> private async Task <SessionWrapper> CreateSessionAsync(string endpointUrl, ConnectionIdentifier id) { var sessionName = id.ToString(); // Validate certificates void OnValidate(CertificateValidator sender, CertificateValidationEventArgs e) { if (!e.Accept && e.Error.StatusCode == StatusCodes.BadCertificateUntrusted) { // Validate thumbprint provided if (e.Certificate.RawData != null && id.Connection.Endpoint.Certificate != null && e.Certificate.Thumbprint == id.Connection.Endpoint.Certificate) { // Validate e.Accept = true; } else if (_clientConfig.AutoAcceptUntrustedCertificates) { _logger.Warning("Publisher is configured to accept untrusted certs. " + "Accepting untrusted certificate on endpoint {endpointUrl}", endpointUrl); e.Accept = true; } } }; var applicationConfiguration = _clientConfig.ToApplicationConfiguration( true, OnValidate); var endpointConfiguration = _clientConfig.ToEndpointConfiguration(); var endpointDescription = SelectEndpoint(endpointUrl, id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy, (int)(id.Connection.OperationTimeout.HasValue ? id.Connection.OperationTimeout.Value.TotalMilliseconds : kDefaultOperationTimeout)); if (endpointDescription == null) { throw new EndpointNotAvailableException(endpointUrl, id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy); } if (id.Connection.Endpoint.SecurityMode.HasValue && id.Connection.Endpoint.SecurityMode != SecurityMode.None && endpointDescription.SecurityMode == MessageSecurityMode.None) { _logger.Warning("Although the use of security was configured, " + "there was no security-enabled endpoint available at url " + "{endpointUrl}. An endpoint with no security will be used.", endpointUrl); } var configuredEndpoint = new ConfiguredEndpoint( null, endpointDescription, endpointConfiguration); _logger.Information("Trying to create session {sessionName}...", sessionName); using (new PerfMarker(_logger, sessionName)) { var userIdentity = id.Connection.User.ToStackModel() ?? new UserIdentity(new AnonymousIdentityToken()); var session = await Session.Create( applicationConfiguration, configuredEndpoint, true, sessionName, _clientConfig.DefaultSessionTimeout, userIdentity, null); _logger.Information($"Session '{sessionName}' created."); _logger.Information("Loading Complex Type System...."); try { var complexTypeSystem = new ComplexTypeSystem(session); await complexTypeSystem.Load(); _logger.Information("Complex Type system loaded."); } catch (Exception ex) { _logger.Error(ex, "Failed to load Complex Type System"); } if (_clientConfig.KeepAliveInterval > 0) { session.KeepAliveInterval = _clientConfig.KeepAliveInterval; session.KeepAlive += Session_KeepAlive; session.Notification += Session_Notification; } var wrapper = new SessionWrapper { MissedKeepAlives = 0, MaxKeepAlives = _clientConfig.MaxKeepAliveCount, Session = session }; return(wrapper); } }