Beispiel #1
0
        /// <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();
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
            }
        }
Beispiel #6
0
        /// <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);
            }
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        /// <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);
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        /// <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);
            }
        }
Beispiel #11
0
        /// <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();
            }
        }