/// <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(); } }
/// <summary> /// Creates a new session /// </summary> /// <param name="identity"></param> /// <returns></returns> private async Task <Session> CreateSessionAsync(IUserIdentity identity) { if (_connection.Endpoint.SecurityMode != SecurityMode.SignAndEncrypt) { _logger.Warning("Establishing unencrypted connection."); } if (_urlQueue.TryDequeue(out var next)) { if (_endpointUrl != null && _endpointUrl != next) { _urlQueue.Enqueue(_endpointUrl); } _endpointUrl = next; _logger.Information("Creating session via {endpoint}.", _endpointUrl); } var selectedEndpoint = await DiscoverEndpointsAsync(_config, _connection.Endpoint, new Uri(_endpointUrl), (server, endpoints, channel) => SelectServerEndpoint(server, endpoints, channel, true)); if (selectedEndpoint == null) { throw new ConnectionException( $"Unable to select secure endpoint on {_connection.Endpoint.Url} via {_endpointUrl}"); } var configuredEndpoint = new ConfiguredEndpoint(selectedEndpoint.Server, EndpointConfiguration.Create(_config)); configuredEndpoint.Update(selectedEndpoint); var session = await Session.Create(_config, configuredEndpoint, true, false, _sessionName, (uint)(_timeout.TotalMilliseconds * 1.2), identity, null); if (session == null) { throw new ExternalDependencyException( $"Cannot establish session to {_connection.Endpoint.Url} via {_endpointUrl}."); } session.KeepAlive += (_, e) => e.CancelKeepAlive = true; session.KeepAliveInterval = -1; // No keep alives - we handle those ourselves. session.RenewUserIdentity += (_, user) => identity; // Reset back to default. try { var complexTypeSystem = new ComplexTypeSystem(session); await complexTypeSystem.Load(); } catch (Exception ex) { _logger.Error(ex, "Failed to load complex type system"); } return(session); }
/// <summary> /// Creates a new session. /// </summary> /// <returns>The new session object.</returns> public async Task <Session> Connect() { // disconnect from existing session. Disconnect(); // determine the URL that was selected. string serverUrl = UrlCB.Text; if (UrlCB.SelectedIndex >= 0) { serverUrl = (string)UrlCB.SelectedItem; } if (m_configuration == null) { throw new ArgumentNullException("m_configuration"); } // select the best endpoint. EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, UseSecurityCK.Checked, m_discoverTimeout); EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration); ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration); m_session = await Session.Create( m_configuration, endpoint, false, !DisableDomainCheck, (String.IsNullOrEmpty(SessionName))?m_configuration.ApplicationName : SessionName, 60000, UserIdentity, PreferredLocales); // set up keep alive callback. m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive); // raise an event. DoConnectComplete(null); var typeSystemLoader = new ComplexTypeSystem(m_session); await typeSystemLoader.Load(); // return the new session. return(m_session); }
public async Task LoadTypeSystem(bool onlyEnumTypes, bool disableDataTypeDefinition, bool disableDataTypeDictionary) { var typeSystem = new ComplexTypeSystem(m_session); Assert.NotNull(typeSystem); typeSystem.DisableDataTypeDefinition = disableDataTypeDefinition; typeSystem.DisableDataTypeDictionary = disableDataTypeDictionary; bool success = await typeSystem.Load(onlyEnumTypes, true).ConfigureAwait(false); Assert.IsTrue(success); var types = typeSystem.GetDefinedTypes(); TestContext.Out.WriteLine("Types loaded: {0} ", types.Length); foreach (var type in types) { TestContext.Out.WriteLine("Type: {0} ", type.FullName); } }
/// <summary> /// Asynchronously open the session. /// </summary> private void Open(object state) { try { Session session = ((object[])state)[0] as Session; string sessionName = ((object[])state)[1] as string; IUserIdentity identity = ((object[])state)[2] as IUserIdentity; IList <string> preferredLocales = ((object[])state)[3] as IList <string>; bool? checkDomain = ((object[])state)[4] as bool?; // open the session. session.Open(sessionName, (uint)session.SessionTimeout, identity, preferredLocales, checkDomain ?? true); var typeSystemLoader = new ComplexTypeSystem(session); typeSystemLoader.Load().Wait(); OpenComplete(null); } catch (Exception exception) { OpenComplete(exception); } }
/// <summary> /// Updates the application after connecting to or disconnecting from the server. /// </summary> private void Server_ConnectComplete(object sender, EventArgs e) { try { m_session = ConnectServerCTRL.Session; // browse the instances in the server. BrowseCTRL.Initialize(m_session, ObjectIds.RootFolder, ReferenceTypeIds.Organizes, ReferenceTypeIds.Aggregates, ReferenceTypeIds.HierarchicalReferences); if (m_session != null) { var typeSystem = new ComplexTypeSystem(m_session); typeSystem.Load().Wait(); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
private async Task <Session> ConsoleSampleClient() { Console.WriteLine("1 - Create an Application Configuration."); ExitCode = ExitCode.ErrorCreateApplication; ApplicationInstance application = new ApplicationInstance { ApplicationName = "UA Core Complex Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.ComplexClient" }; // load the application configuration. ApplicationConfiguration config = await application.LoadApplicationConfiguration(false).ConfigureAwait(false); // check the application certificate. bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0).ConfigureAwait(false); if (!haveAppCertificate) { throw new Exception("Application instance certificate invalid!"); } ReverseConnectManager reverseConnectManager = null; if (ReverseConnectUri != null) { // start the reverse connection manager reverseConnectManager = new ReverseConnectManager(); reverseConnectManager.AddEndpoint(ReverseConnectUri); reverseConnectManager.StartService(config); } if (haveAppCertificate) { config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { m_autoAccept = true; } config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } else { Console.WriteLine(" WARN: missing application certificate, using unsecure connection."); } Console.WriteLine("2 - Discover endpoints of {0}.", m_endpointURL); ExitCode = ExitCode.ErrorDiscoverEndpoints; EndpointDescription selectedEndpoint; if (reverseConnectManager == null) { selectedEndpoint = CoreClientUtils.SelectEndpoint(m_endpointURL, haveAppCertificate, 15000); } else { Console.WriteLine(" Waiting for reverse connection."); ITransportWaitingConnection connection = await reverseConnectManager.WaitForConnection( new Uri(m_endpointURL), null, new CancellationTokenSource(60000).Token); if (connection == null) { throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out."); } selectedEndpoint = CoreClientUtils.SelectEndpoint(config, connection, haveAppCertificate, 15000); } Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); ExitCode = ExitCode.ErrorCreateSession; // create the user identity UserIdentity userIdentity; if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password)) { userIdentity = new UserIdentity(new AnonymousIdentityToken()); } else { userIdentity = new UserIdentity(Username, Password); } // create worker session if (reverseConnectManager == null) { m_session = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); } else { Console.WriteLine(" Waiting for reverse connection."); ITransportWaitingConnection connection = await reverseConnectManager.WaitForConnection( new Uri(m_endpointURL), null, new CancellationTokenSource(60000).Token); if (connection == null) { throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out."); } m_session = await CreateSession(config, connection, selectedEndpoint, userIdentity).ConfigureAwait(false); } // register keep alive handler m_session.KeepAlive += Client_KeepAlive; Console.WriteLine("4 - Browse for all custom type variables."); ExitCode = ExitCode.ErrorReadComplexTypes; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var allVariableNodes = BrowseAdddressSpace ? BrowseAllVariables() : new List <INode>(); var allCustomTypeVariables = allVariableNodes.Where(n => ((VariableNode)n).DataType.NamespaceIndex != 0).ToList(); stopWatch.Stop(); Console.WriteLine($" -- Browse all nodes took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($" -- Browsed {allVariableNodes.Count} nodes, from which {allCustomTypeVariables.Count} are custom type variables."); stopWatch.Reset(); // for testing clear the nodecache m_session.NodeCache.Clear(); stopWatch.Start(); if (LoadTypeSystem) { Console.WriteLine("5 - Load the server type dictionary."); ExitCode = ExitCode.ErrorLoadTypeDictionary; stopWatch.Reset(); stopWatch.Start(); var complexTypeSystem = new ComplexTypeSystem(m_session); await complexTypeSystem.Load().ConfigureAwait(false); stopWatch.Stop(); Console.WriteLine($"Load type system took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($"Custom types defined for this session:"); foreach (var type in complexTypeSystem.GetDefinedTypes()) { Console.WriteLine($"{type.Namespace}.{type.Name}"); } Console.WriteLine($"Loaded {m_session.DataTypeSystem.Count} dictionaries:"); foreach (var dictionary in m_session.DataTypeSystem) { Console.WriteLine($" + {dictionary.Value.Name}"); foreach (var type in dictionary.Value.DataTypes) { Console.WriteLine($" -- {type.Key}:{type.Value}"); } } } else { Console.WriteLine("4 - Not loading the server type dictionary."); } foreach (VariableNode variableNode in allCustomTypeVariables) { try { var value = m_session.ReadValue(variableNode.NodeId); CastInt32ToEnum(variableNode, value); Console.WriteLine($" -- {variableNode}:{value}"); if (value.Value is ExtensionObject extensionObject) { if (extensionObject.Body is BaseComplexType complexType) { foreach (var item in complexType.GetPropertyEnumerator()) { if (Verbose) { Console.WriteLine($" -- -- {item.Name}:{complexType[item.Name]}"); } if (WriteComplexInt && item.PropertyType == typeof(Int32)) { var data = complexType[item.Name]; if (data != null) { complexType[item.Name] = (Int32)data + 1; } Console.WriteLine($" -- -- Increment: {item.Name}, {complexType[item.Name]}"); WriteValue(m_session, variableNode.NodeId, value); } } } } if (PrintAsJson) { PrintValueAsJson(variableNode.BrowseName.Name, value); } } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($" -- {variableNode}: Access denied!"); } } } Console.WriteLine("6 - Create test sessions which load only single types as needed."); if (LoadTypeSystem) { foreach (VariableNode variableNode in allCustomTypeVariables) { Session testSession = null; try { Console.WriteLine($"Open session for {variableNode}:"); testSession = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); var complexTypeSystem = new ComplexTypeSystem(testSession); NodeId dataType = variableNode.DataType; Type nullType = testSession.Factory.GetSystemType(dataType); var valueBefore = testSession.ReadValue(variableNode.NodeId); Console.WriteLine($" -- {valueBefore}"); Type systemType = await complexTypeSystem.LoadType(dataType).ConfigureAwait(false); var valueAfter = testSession.ReadValue(variableNode.NodeId); Console.WriteLine($" -- {variableNode}: {systemType} {dataType}"); Console.WriteLine($" -- {valueAfter}"); Console.WriteLine($"Custom types defined for {variableNode}:"); foreach (var type in complexTypeSystem.GetDefinedTypes()) { Console.WriteLine($" -- {type.Namespace}.{type.Name}"); } } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($" -- {variableNode}: Access denied!"); } } finally { testSession?.Close(); } } } else { Console.WriteLine("6 - Not testing to load individual types."); } Console.WriteLine("7 - Create a subscription with publishing interval of 1 second."); ExitCode = ExitCode.ErrorCreateSubscription; var subscription = new Subscription(m_session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("8 - Add all custom values and the server time to the subscription."); ExitCode = ExitCode.ErrorMonitoredItem; var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime.ToString() } }; list.ForEach(i => i.Notification += OnNotification); foreach (var customVariable in allCustomTypeVariables) { var newItem = new MonitoredItem(subscription.DefaultItem) { DisplayName = customVariable.DisplayName.Text, StartNodeId = ExpandedNodeId.ToNodeId(customVariable.NodeId, m_session.NamespaceUris) }; newItem.Notification += OnComplexTypeNotification; list.Add(newItem); } subscription.AddItems(list); Console.WriteLine("9 - Add the subscription to the session."); ExitCode = ExitCode.ErrorAddSubscription; m_session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("10 - Running...Press Ctrl-C to exit..."); ExitCode = ExitCode.ErrorRunning; return(m_session); }
/// <summary> /// Create session against endpoint /// </summary> /// <param name="endpointUrl"></param> /// <param name="id"></param> /// <param name="wrapper"></param> /// <returns></returns> private async Task <Session> CreateSessionAsync(string endpointUrl, ConnectionIdentifier id, SessionWrapper wrapper) { var sessionName = $"Azure IIoT {id}"; 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("Creating session '{id}' for endpoint '{endpointUrl}'...", id, endpointUrl); 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).ConfigureAwait(false); session.Handle = wrapper; wrapper.Session = session; session.KeepAliveInterval = _clientConfig.KeepAliveInterval > 0 ? _clientConfig.KeepAliveInterval : kDefaultOperationTimeout; session.KeepAlive += Session_KeepAlive; session.Notification += Session_Notification; // TODO - store the created session id (node id)? if (sessionName != session.SessionName) { _logger.Warning("Session '{id}' created with a revised name '{name}'", id, session.SessionName); } _logger.Information("Session '{id}' created, loading complex type system ... ", id); try { var complexTypeSystem = new ComplexTypeSystem(session); await complexTypeSystem.Load().ConfigureAwait(false); _logger.Information("Session '{id}' complex type system loaded", id); } catch (Exception ex) { _logger.Error(ex, "Failed to load complex type system for session '{id}'", id); } return(session); } }
private async Task <Session> ConsoleSampleClient() { Console.WriteLine("1 - Create an Application Configuration."); ExitCode = ExitCode.ErrorCreateApplication; ApplicationInstance application = new ApplicationInstance { ApplicationName = "UA Core Complex Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.ComplexClient" }; // load the application configuration. ApplicationConfiguration config = await application.LoadApplicationConfiguration(false); // check the application certificate. bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0); if (!haveAppCertificate) { throw new Exception("Application instance certificate invalid!"); } if (haveAppCertificate) { config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { _autoAccept = true; } config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } else { Console.WriteLine(" WARN: missing application certificate, using unsecure connection."); } Console.WriteLine("2 - Discover endpoints of {0}.", _endpointURL); ExitCode = ExitCode.ErrorDiscoverEndpoints; var selectedEndpoint = CoreClientUtils.SelectEndpoint(_endpointURL, haveAppCertificate, 15000); Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); ExitCode = ExitCode.ErrorCreateSession; var endpointConfiguration = EndpointConfiguration.Create(config); var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration); _session = await Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null); // register keep alive handler _session.KeepAlive += Client_KeepAlive; Console.WriteLine("4 - Browse for all custom type variables."); ExitCode = ExitCode.ErrorReadComplexTypes; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var allVariableNodes = BrowseAllVariables(); var allCustomTypeVariables = allVariableNodes.Where(n => ((VariableNode)n).DataType == DataTypeIds.Structure).ToList(); allCustomTypeVariables.AddRange(allVariableNodes.Where(n => ((VariableNode)n).DataType.NamespaceIndex != 0).ToList()); stopWatch.Stop(); Console.WriteLine($" -- Browse all nodes took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($" -- Browsed {allVariableNodes.Count} nodes, from which {allCustomTypeVariables.Count} are custom type variables."); if (LoadTypeSystem) { Console.WriteLine("5 - Load the server type dictionary."); ExitCode = ExitCode.ErrorLoadTypeDictionary; stopWatch.Reset(); stopWatch.Start(); var complexTypeSystem = new ComplexTypeSystem(_session); await complexTypeSystem.Load(); stopWatch.Stop(); Console.WriteLine($"Load type system took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($"Custom types defined for this session:"); foreach (var type in complexTypeSystem.GetDefinedTypes()) { Console.WriteLine($"{type.Namespace}.{type.Name}"); } Console.WriteLine($"Loaded {_session.DataTypeSystem.Count} dictionaries:"); foreach (var dictionary in _session.DataTypeSystem) { Console.WriteLine($" + {dictionary.Value.Name}"); foreach (var type in dictionary.Value.DataTypes) { Console.WriteLine($" -- {type.Key}:{type.Value}"); } } } else { Console.WriteLine("4 - Not loading the server type dictionary."); } foreach (VariableNode variableNode in allCustomTypeVariables) { try { var value = _session.ReadValue(variableNode.NodeId); CastInt32ToEnum(variableNode, value); Console.WriteLine($" -- {variableNode}:{value}"); var extensionObject = value.Value as ExtensionObject; if (extensionObject != null) { var complexType = extensionObject.Body as BaseComplexType; if (complexType != null) { foreach (var item in complexType.GetPropertyEnumerator()) { if (Verbose) { Console.WriteLine($" -- -- {item.Name}:{complexType[item.Name]}"); } if (WriteComplexInt && item.PropertyType == typeof(Int32)) { var data = complexType[item.Name]; if (data != null) { complexType[item.Name] = (Int32)data + 1; } Console.WriteLine($" -- -- Write: {item.Name}, {complexType[item.Name]}"); WriteValue(_session, variableNode.NodeId, value); } } } } if (PrintAsJson) { PrintValueAsJson(variableNode.BrowseName.Name, value); } } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($" -- {variableNode}: Access denied!"); } } } Console.WriteLine("6 - Create a subscription with publishing interval of 1 second."); ExitCode = ExitCode.ErrorCreateSubscription; var subscription = new Subscription(_session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("7 - Add all custom values and the server time to the subscription."); ExitCode = ExitCode.ErrorMonitoredItem; var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime.ToString() } }; list.ForEach(i => i.Notification += OnNotification); foreach (var customVariable in allCustomTypeVariables) { var newItem = new MonitoredItem(subscription.DefaultItem) { DisplayName = customVariable.DisplayName.Text, StartNodeId = ExpandedNodeId.ToNodeId(customVariable.NodeId, _session.NamespaceUris) }; newItem.Notification += OnComplexTypeNotification; list.Add(newItem); } subscription.AddItems(list); Console.WriteLine("8 - Add the subscription to the session."); ExitCode = ExitCode.ErrorAddSubscription; _session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("9 - Running...Press Ctrl-C to exit..."); ExitCode = ExitCode.ErrorRunning; return(_session); }
/// <summary> /// Create session against endpoint /// </summary> /// <param name="endpointUrl"></param> /// <param name="id"></param> /// <returns></returns> private async Task <Session> CreateSessionAsync(string endpointUrl, ConnectionIdentifier id) { var sessionName = $"Azure IIoT Publisher - {id}"; // 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 = await _clientConfig. ToApplicationConfigurationAsync(_identity, 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); if (sessionName != session.SessionName) { _logger.Warning("Session '{sessionName}' created with a revised name '{name}'", sessionName, session.SessionName); } _logger.Information("Session '{sessionName}' created.", sessionName); _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"); } // TODO - what happens when KeepAliveInterval is 0??? if (_clientConfig.KeepAliveInterval > 0) { session.KeepAliveInterval = _clientConfig.KeepAliveInterval; session.KeepAlive += Session_KeepAlive; session.Notification += Session_Notification; } return(session); } }
/// <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(); } }