public static void Main(string[] args)
        {
            try
            {
                if ((args.Length == 0) || string.IsNullOrEmpty(args[0]) || args[0].Equals("localhost", StringComparison.OrdinalIgnoreCase))
                {
                    m_applicationName = Utils.GetHostName();
                }
                else
                {
                    m_applicationName = args[0];
                }

                Trace("Publisher is starting up...");
                ModuleConfiguration moduleConfiguration = new ModuleConfiguration(m_applicationName);
                m_configuration = moduleConfiguration.Configuration;
                m_configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

                // start our server interface
                try
                {
                    Trace("Starting server on endpoint " + m_configuration.ServerConfiguration.BaseAddresses[0].ToString() + "...");
                    m_server.Start(m_configuration);
                    Trace("Server started.");
                }
                catch (Exception ex)
                {
                    Trace("Starting server failed with: " + ex.Message);
                }

                // check if we also received an owner connection string
                string ownerConnectionString = string.Empty;
                if ((args.Length > 1) && !string.IsNullOrEmpty(args[1]))
                {
                    ownerConnectionString = args[1];
                }
                else
                {
                    Trace("IoT Hub owner connection string not passed as argument.");

                    // check if we have an environment variable to register ourselves with IoT Hub
                    if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS")))
                    {
                        ownerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS");
                    }
                }

                // register ourselves with IoT Hub
                if (ownerConnectionString != string.Empty)
                {
                    Trace("Attemping to register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
                    RegistryManager manager = RegistryManager.CreateFromConnectionString(ownerConnectionString);

                    // remove any existing device
                    Device existingDevice = manager.GetDeviceAsync(m_applicationName).Result;
                    if (existingDevice != null)
                    {
                        manager.RemoveDeviceAsync(m_applicationName).Wait();
                    }

                    Device newDevice = manager.AddDeviceAsync(new Device(m_applicationName)).Result;
                    if (newDevice != null)
                    {
                        string hostname = ownerConnectionString.Substring(0, ownerConnectionString.IndexOf(";"));
                        string deviceConnectionString = hostname + ";DeviceId=" + m_applicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey;
                        SecureIoTHubToken.Write(m_applicationName, deviceConnectionString);
                    }
                    else
                    {
                        Trace("Could not register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
                    }
                }
                else
                {
                    Trace("IoT Hub owner connection string not found, registration with IoT Hub abandoned.");
                }

                // try to read connection string from secure store and open IoTHub client
                Trace("Attemping to read connection string from secure store with certificate name: " + m_applicationName);
                string connectionString = SecureIoTHubToken.Read(m_applicationName);
                if (!string.IsNullOrEmpty(connectionString))
                {
                    Trace("Attemping to configure publisher with connection string: " + connectionString);
                    m_deviceClient             = DeviceClient.CreateFromConnectionString(connectionString, Microsoft.Azure.Devices.Client.TransportType.Mqtt);
                    m_deviceClient.RetryPolicy = RetryPolicyType.Exponential_Backoff_With_Jitter;
                    m_deviceClient.OpenAsync().Wait();
                }
                else
                {
                    Trace("Device connection string not found in secure store.");
                }

                // get a list of persisted endpoint URLs and create a session for each.
                try
                {
                    // check if we have an env variable specifying the published nodes path, otherwise use current directory
                    string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
                    if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
                    {
                        publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
                    }

                    Trace("Attemping to load nodes file from: " + publishedNodesFilePath);
                    m_nodesLookups = JsonConvert.DeserializeObject <PublishedNodesCollection>(File.ReadAllText(publishedNodesFilePath));
                    Trace("Loaded " + m_nodesLookups.Count.ToString() + " nodes.");
                }
                catch (Exception ex)
                {
                    Trace("Nodes file loading failed with: " + ex.Message);
                }

                foreach (NodeLookup nodeLookup in m_nodesLookups)
                {
                    if (!m_endpointUrls.Contains(nodeLookup.EndPointURL))
                    {
                        m_endpointUrls.Add(nodeLookup.EndPointURL);
                    }
                }

                // connect to the other servers
                Trace("Attemping to connect to servers...");
                try
                {
                    List <Task> connectionAttempts = new List <Task>();
                    foreach (Uri endpointUrl in m_endpointUrls)
                    {
                        Trace("Connecting to server: " + endpointUrl);
                        connectionAttempts.Add(EndpointConnect(endpointUrl));
                    }

                    // Wait for all sessions to be connected
                    Task.WaitAll(connectionAttempts.ToArray());
                }
                catch (Exception ex)
                {
                    Trace("Exception: " + ex.ToString() + "\r\n" + ex.InnerException != null ? ex.InnerException.ToString() : null);
                }

                // subscribe to preconfigured nodes
                Trace("Attemping to subscribe to published nodes...");
                if (m_nodesLookups != null)
                {
                    foreach (NodeLookup nodeLookup in m_nodesLookups)
                    {
                        try
                        {
                            CreateMonitoredItem(nodeLookup);
                        }
                        catch (Exception ex)
                        {
                            Trace("Unexpected error publishing node: " + ex.Message + "\r\nIgnoring node: " + nodeLookup.EndPointURL.AbsoluteUri + ", " + nodeLookup.NodeID.ToString());
                        }
                    }
                }


                Task dequeueAndSendTask = null;
                var  tokenSource        = new CancellationTokenSource();
                var  token = tokenSource.Token;

                Trace("Creating task to send OPC UA messages in batches to IoT Hub...");
                try
                {
                    dequeueAndSendTask = Task.Run(() => DeQueueMessagesAsync(token), token);
                }
                catch (Exception ex)
                {
                    Trace("Exception: " + ex.ToString());
                }

                Trace("Publisher is running. Press enter to quit.");
                Console.ReadLine();

                foreach (Session session in m_sessions)
                {
                    session.Close();
                }

                //Send cancellation token and wait for last IoT Hub message to be sent.
                try
                {
                    tokenSource.Cancel();
                    dequeueAndSendTask.Wait();
                }
                catch (Exception ex)
                {
                    Trace("Exception: " + ex.ToString());
                }

                if (m_deviceClient != null)
                {
                    m_deviceClient.CloseAsync().Wait();
                }
            }
            catch (Exception e)
            {
                Trace(e, "Unhandled exception in Publisher, exiting!");
            }
        }
Exemple #2
0
        /// <summary>
        /// Create module, throws if configuration is bad
        /// </summary>
        public void Create(Broker broker, byte[] configuration)
        {
            Trace("Opc.Ua.Publisher.Module: Creating...");

            m_broker = broker;

            string configString = Encoding.UTF8.GetString(configuration);

            // Deserialize from configuration string
            ModuleConfiguration moduleConfiguration = null;

            try
            {
                moduleConfiguration = JsonConvert.DeserializeObject <ModuleConfiguration>(configString);
            }
            catch (Exception ex)
            {
                Trace("Opc.Ua.Publisher.Module: Module config string " + configString + " could not be deserialized: " + ex.Message);
                throw;
            }

            m_configuration = moduleConfiguration.Configuration;
            m_configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

            // update log configuration, if available
            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP")))
            {
                m_configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
                m_configuration.TraceConfiguration.ApplySettings();
            }

            // get a list of persisted endpoint URLs and create a session for each.
            try
            {
                // check if we have an env variable specifying the published nodes path, otherwise use current directory
                string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
                {
                    publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
                }

                Trace("Opc.Ua.Publisher.Module: Attemping to load nodes file from: " + publishedNodesFilePath);
                m_nodesLookups = JsonConvert.DeserializeObject <PublishedNodesCollection>(File.ReadAllText(publishedNodesFilePath));
                Trace("Opc.Ua.Publisher.Module: Loaded " + m_nodesLookups.Count.ToString() + " nodes.");
            }
            catch (Exception ex)
            {
                Trace("Opc.Ua.Publisher.Module: Nodes file loading failed with: " + ex.Message);
            }

            foreach (NodeLookup nodeLookup in m_nodesLookups)
            {
                if (!m_endpointUrls.Contains(nodeLookup.EndPointURL))
                {
                    m_endpointUrls.Add(nodeLookup.EndPointURL);
                }
            }

            // start the server
            try
            {
                Trace("Opc.Ua.Publisher.Module: Starting server on endpoint " + m_configuration.ServerConfiguration.BaseAddresses[0].ToString() + "...");
                m_server.Start(m_configuration);
                Trace("Opc.Ua.Publisher.Module: Server started.");
            }
            catch (Exception ex)
            {
                Trace("Opc.Ua.Publisher.Module: Starting server failed with: " + ex.Message);
            }

            // check if we have an environment variable to register ourselves with IoT Hub
            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS")))
            {
                string ownerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS");

                if ((m_configuration != null) && (!string.IsNullOrEmpty(m_configuration.ApplicationName)))
                {
                    Trace("Attemping to register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
                    string deviceConnectionString = IoTHubRegistration.RegisterDeviceWithIoTHub(m_configuration.ApplicationName, ownerConnectionString);
                    if (!string.IsNullOrEmpty(deviceConnectionString))
                    {
                        SecureIoTHubToken.Write(m_configuration.ApplicationName, deviceConnectionString);
                    }
                    else
                    {
                        Trace("Could not register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
                    }
                }
            }

            // try to configure our publisher component
            TryConfigurePublisherAsync().Wait();

            // connect to servers
            Trace("Opc.Ua.Publisher.Module: Attemping to connect to servers...");
            try
            {
                List <Task> connectionAttempts = new List <Task>();
                foreach (Uri endpointUrl in m_endpointUrls)
                {
                    Trace("Opc.Ua.Publisher.Module: Connecting to server: " + endpointUrl);
                    connectionAttempts.Add(EndpointConnect(endpointUrl));
                }

                // Wait for all sessions to be connected
                Task.WaitAll(connectionAttempts.ToArray());
            }
            catch (Exception ex)
            {
                Trace("Opc.Ua.Publisher.Module: Exception: " + ex.ToString() + "\r\n" + ex.InnerException != null ? ex.InnerException.ToString() : null);
            }

            Trace("Opc.Ua.Publisher.Module: Created.");
        }