예제 #1
0
        public void Test_WriteSingleEncodeableWithName()
        {
            var expected = "{\"bar_1\":{\"Foo\":\"bar_1\"}}";

            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);

            using (var encodeable = new FooBarEncodeable())
            {
                using (var encoder = new JsonEncoder(Context, true, false))
                {
                    encoder.WriteEncodeable(encodeable.Foo, encodeable, typeof(FooBarEncodeable));

                    var encoded = encoder.CloseAndReturnText();

                    TestContext.Out.WriteLine("Encoded:");
                    TestContext.Out.WriteLine(encoded);

                    TestContext.Out.WriteLine("Formatted Encoded:");
                    _ = PrettifyAndValidateJson(encoded);

                    Assert.That(encoded, Is.EqualTo(expected));
                }
            }
        }
예제 #2
0
        public void Test_WriteMultipleEncodeablesWithFieldNames()
        {
            var expected = "{\"bar_1\":{\"Foo\":\"bar_1\"},\"bar_2\":{\"Foo\":\"bar_2\"},\"bar_3\":{\"Foo\":\"bar_3\"}}";

            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);

            var encodeables = new List <FooBarEncodeable> {
                new FooBarEncodeable(), new FooBarEncodeable(), new FooBarEncodeable()
            };

            try
            {
                var encoder = new JsonEncoder(Context, true, null, false);

                foreach (var encodeable in encodeables)
                {
                    encoder.WriteEncodeable(encodeable.Foo, encodeable, typeof(FooBarEncodeable));
                }

                var encoded = encoder.CloseAndReturnText();
                TestContext.Out.WriteLine("Encoded:");
                TestContext.Out.WriteLine(encoded);

                TestContext.Out.WriteLine("Formatted Encoded:");
                _ = PrettifyAndValidateJson(encoded);

                Assert.That(encoded, Is.EqualTo(expected));
            }
            finally
            {
                encodeables.ForEach(e => e.Dispose());
            }
        }
예제 #3
0
        public void Test_WriteMultipleEncodeablesWithoutFieldNames(bool topLevelIsArray, string expected)
        {
            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);


            var encodeables = new List <FooBarEncodeable> {
                new FooBarEncodeable(), new FooBarEncodeable(), new FooBarEncodeable()
            };

            try
            {
                var encoder = new JsonEncoder(Context, true, null, topLevelIsArray);

                foreach (var encodeable in encodeables)
                {
                    encoder.WriteEncodeable(null, encodeable, typeof(FooBarEncodeable));
                }

                var encoded = encoder.CloseAndReturnText();
                TestContext.Out.WriteLine("Encoded:");
                TestContext.Out.WriteLine(encoded);

                TestContext.Out.WriteLine("Formatted Encoded:");
                _ = PrettifyAndValidateJson(encoded);

                Assert.That(encoded, Is.EqualTo(expected));
            }
            finally
            {
                encodeables.ForEach(e => e.Dispose());
            }
        }
예제 #4
0
        private void RunWriteEncodeableArrayTest(string fieldName, List <FooBarEncodeable> encodeables, string expected, bool topLevelIsArray, bool noExpectedValidation = false)
        {
            try
            {
                if (!noExpectedValidation)
                {
                    TestContext.Out.WriteLine("Expected:");
                    _ = PrettifyAndValidateJson(expected);
                }

                var encoder = new JsonEncoder(Context, true, null, topLevelIsArray);

                encoder.WriteEncodeableArray(
                    fieldName,
                    encodeables.Cast <IEncodeable>().ToList(),
                    typeof(FooBarEncodeable));

                var encoded = encoder.CloseAndReturnText();
                TestContext.Out.WriteLine("Encoded:");
                TestContext.Out.WriteLine(encoded);

                TestContext.Out.WriteLine("Formatted Encoded:");
                _ = PrettifyAndValidateJson(encoded);

                Assert.That(encoded, Is.EqualTo(expected));
            }
            finally
            {
                encodeables.ForEach(e => e.Dispose());
            }
        }
예제 #5
0
        private void PrintValueAsJson(string name, DataValue value)
        {
            var jsonEncoder = new JsonEncoder(m_session.MessageContext, JsonReversible);

            jsonEncoder.WriteDataValue(name, value);
            var textbuffer = jsonEncoder.CloseAndReturnText();

            // prettify
            using (var stringWriter = new StringWriter())
            {
                try
                {
                    using (var stringReader = new StringReader(textbuffer))
                    {
                        var jsonReader = new JsonTextReader(stringReader);
                        var jsonWriter = new JsonTextWriter(stringWriter)
                        {
                            Formatting = Formatting.Indented,
                            Culture    = CultureInfo.InvariantCulture
                        };
                        jsonWriter.WriteToken(jsonReader);
                        Console.WriteLine(stringWriter.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to format the JSON output:", ex.Message);
                    Console.WriteLine(textbuffer);
                    Console.WriteLine(stringWriter.ToString());
                    ExitCode = ExitCode.ErrorJSONDecode;
                    throw;
                }
            }
        }
예제 #6
0
        public void TestFieldValueEscapedArray(string fieldname, string foo, string expected)
        {
            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);

            using (var encodeable = new FooBarEncodeable(fieldname, foo))
            {
                var list = new List <IEncodeable>()
                {
                    encodeable, encodeable
                };
                using (var encoder = new JsonEncoder(Context, true))
                {
                    encoder.WriteEncodeableArray(encodeable.FieldName, list, typeof(FooBarEncodeable));

                    var encoded = encoder.CloseAndReturnText();
                    TestContext.Out.WriteLine("Encoded:");
                    TestContext.Out.WriteLine(encoded);

                    TestContext.Out.WriteLine("Formatted Encoded:");
                    _ = PrettifyAndValidateJson(encoded);

                    Assert.That(encoded, Is.EqualTo(expected));
                }
            }
        }
        /// <summary>
        /// Encodes the object and returns the resulting byte array.
        /// </summary>
        /// <returns></returns>
        public override byte[] Encode()
        {
            ServiceMessageContext messageContext = new ServiceMessageContext();

            messageContext.NamespaceUris = ServiceMessageContext.GlobalContext.NamespaceUris;
            messageContext.ServerUris    = ServiceMessageContext.GlobalContext.ServerUris;

            bool topLevelIsArray = !HasNetworkMessageHeader && !HasSingleDataSetMessage;

            using (JsonEncoder encoder = new JsonEncoder(messageContext, false, null, topLevelIsArray))
            {
                // handle no header
                if (HasNetworkMessageHeader)
                {
                    Encode(encoder);
                }
                else if (DataSetMessages != null && DataSetMessages.Count > 0)
                {
                    if (HasSingleDataSetMessage)
                    {
                        // encode single dataset message
                        JsonDataSetMessage jsonDataSetMessage = DataSetMessages[0] as JsonDataSetMessage;
                        if (jsonDataSetMessage != null)
                        {
                            if (!jsonDataSetMessage.HasDataSetMessageHeader)
                            {
                                // (UA Specs:) If the NetworkMessageHeader and the DataSetMessageHeader bits are not set
                                // and SingleDataSetMessage bit is set, the NetworkMessage
                                // is a JSON object containing the set of name/value pairs defined for a single DataSet.
                                jsonDataSetMessage.EncodePayload(encoder, false);
                            }
                            else
                            {
                                // If the SingleDataSetMessage bit of the NetworkMessageContentMask is set,
                                // the content of the Messages field is a JSON object containing a single DataSetMessage.
                                jsonDataSetMessage.Encode(encoder);
                            }
                        }
                    }
                    else
                    {
                        // If the NetworkMessageHeader bit of the NetworkMessageContentMask is not set,
                        // the NetworkMessage is the contents of the Messages field (e.g. a JSON array of DataSetMessages).
                        foreach (var message in DataSetMessages)
                        {
                            JsonDataSetMessage jsonDataSetMessage = message as JsonDataSetMessage;
                            if (jsonDataSetMessage != null)
                            {
                                jsonDataSetMessage.Encode(encoder);
                            }
                        }
                    }
                }

                byte[] bytes = System.Text.Encoding.ASCII.GetBytes(encoder.CloseAndReturnText());

                return(bytes);
            }
        }
 public void JsonEncoder_Constructor_Streamwriter_Reflection2()
 {
     using (var jsonEncoder = new JsonEncoder(m_context, false, false, m_memoryStream, true, StreamSize))
     {
         TestEncoding(jsonEncoder);
         var result = jsonEncoder.CloseAndReturnText();
     }
 }
 public void JsonEncoder_Constructor2()
 {
     using (var jsonEncoder = new JsonEncoder(m_context, false))
     {
         TestEncoding(jsonEncoder);
         _ = jsonEncoder.CloseAndReturnText();
     }
 }
예제 #10
0
        private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification == null)
                {
                    return;
                }

                DataValue value = notification.Value as DataValue;
                if (value == null)
                {
                    return;
                }

                using (var encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false))
                {
                    string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri;
                    encoder.WriteString("ApplicationUri", applicationURI);
                    encoder.WriteString("DisplayName", monitoredItem.DisplayName);
                    encoder.WriteNodeId("MonitoredItem", monitoredItem.ResolvedNodeId);
                    // suppress output of server timestamp in json by setting it to minvalue
                    value.ServerTimestamp = DateTime.MinValue;
                    encoder.WriteDataValue("Value", value);

                    string json = encoder.CloseAndReturnText();

                    var properties = new Dictionary <string, string>();
                    properties.Add("content-type", "application/opcua+uajson");
                    properties.Add("deviceName", Id);

                    if (SharedAccessKey != null)
                    {
                        properties.Add("source", "mapping");
                        properties.Add("deviceKey", SharedAccessKey);
                    }

                    try
                    {
                        Module.Publish(new Message(json, properties));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Opc.Ua.Client.SampleModule: Failed to publish message, dropping...");
                        Console.WriteLine(ex.ToString());
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine("Opc.Ua.Client.SampleModule: Error processing monitored item notification.");
                Console.WriteLine(exception.ToString());
            }
        }
예제 #11
0
        public void Constructor_Default(bool useReversible, bool topLevelIsArray)
        {
            var context     = new ServiceMessageContext();
            var jsonEncoder = new JsonEncoder(context, useReversible, topLevelIsArray);

            TestEncoding(jsonEncoder, topLevelIsArray);
            var result = jsonEncoder.CloseAndReturnText();

            Assert.IsNotEmpty(result);
            Assert.NotNull(result);
            TestContext.Out.WriteLine("Result:");
            _ = PrettifyAndValidateJson(result);
        }
예제 #12
0
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server
        /// </summary>
        public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            try
            {
                if (args.NotificationValue == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
                if (notification == null)
                {
                    return;
                }

                DataValue value = notification.Value as DataValue;
                if (value == null)
                {
                    return;
                }

                JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);

                string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri;
                encoder.WriteString("ApplicationUri", (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}")));
                encoder.WriteString("DisplayName", monitoredItem.DisplayName);

                // write NodeId as ns=x;i=y
                NodeId nodeId = monitoredItem.ResolvedNodeId;
                encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString());

                // suppress output of server timestamp in json by setting it to minvalue
                value.ServerTimestamp = DateTime.MinValue;
                encoder.WriteDataValue("Value", value);

                string json = encoder.CloseAndReturnText();

                // add message to fifo send queue
                Trace(Utils.TraceMasks.OperationDetail, "Enqueue a new message:");
                Trace(Utils.TraceMasks.OperationDetail, "   ApplicationUri: " + (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}")));
                Trace(Utils.TraceMasks.OperationDetail, $"   DisplayName: {monitoredItem.DisplayName}");
                Trace(Utils.TraceMasks.OperationDetail, $"   Value: {value}");
                Program.IotHubMessaging.Enqueue(json);
            }
            catch (Exception e)
            {
                Trace(e, "Error processing monitored item notification");
            }
        }
예제 #13
0
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server.
        /// </summary>
        public void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            try
            {
                if (args == null || args.NotificationValue == null || monitoredItem == null || monitoredItem.Subscription == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
                if (notification == null)
                {
                    return;
                }

                DataValue value = notification.Value as DataValue;
                if (value == null)
                {
                    return;
                }

                JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);

                string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri;
                encoder.WriteString("ApplicationUri", (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}")));
                encoder.WriteString("DisplayName", monitoredItem.DisplayName);

                // use the node Id as configured, to also have the namespace URI in case of a ExpandedNodeId.
                encoder.WriteString("NodeId", ConfigNodeId);

                // suppress output of server timestamp in json by setting it to minvalue
                value.ServerTimestamp = DateTime.MinValue;
                encoder.WriteDataValue("Value", value);

                string json = encoder.CloseAndReturnText();

                // add message to fifo send queue
                Trace(Utils.TraceMasks.OperationDetail, $"Enqueue a new message from subscription {monitoredItem.Subscription.Id} (publishing interval: {monitoredItem.Subscription.PublishingInterval}, sampling interval: {monitoredItem.SamplingInterval}):");
                Trace(Utils.TraceMasks.OperationDetail, "   ApplicationUri: " + (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}")));
                Trace(Utils.TraceMasks.OperationDetail, $"   DisplayName: {monitoredItem.DisplayName}");
                Trace(Utils.TraceMasks.OperationDetail, $"   Value: {value}");
                IotHubCommunication.Enqueue(json);
            }
            catch (Exception e)
            {
                Trace(e, "Error processing monitored item notification");
            }
        }
예제 #14
0
        public void WhenServerUrisAreLessThanNamespaces_ShouldNotThrowAndMustReturnCorrectServerUris()
        {
            //arrange
            UInt32 uriVersion     = 1234;
            var    namespaceTable = new NamespaceTable(new List <string> {
                Namespaces.OpcUa, "http://bar", "http://foo"
            });
            var expectedServerUri = "http://foobar";
            var serverUris        = new StringTable(new[] { Namespaces.OpcUa, expectedServerUri });
            var context           = new ServiceMessageContext {
                NamespaceUris = namespaceTable, ServerUris = serverUris
            };
            string result;

            using (var jsonEncoder = new JsonEncoder(context, true))
            {
                var envelope = new SessionLessServiceMessage {
                    UriVersion    = uriVersion,
                    NamespaceUris = context.NamespaceUris,
                    ServerUris    = context.ServerUris,
                    Message       = null
                };

                //act and validate it does not throw
                Assert.DoesNotThrow(() => {
                    envelope.Encode(jsonEncoder);
                });

                result = jsonEncoder.CloseAndReturnText();
            }

            var jObject = JObject.Parse(result);

            Assert.IsNotNull(jObject);
            UInt32 version = jObject["UriVersion"].ToObject <UInt32>();

            Assert.AreEqual(uriVersion, version);
            var serverUrisToken = jObject["ServerUris"];

            Assert.IsNotNull(serverUrisToken);
            var serverUrisEncoded = serverUrisToken.ToObject <string[]>();

            Assert.IsNotNull(serverUrisEncoded);
            Assert.AreEqual(1, serverUrisEncoded.Length);
            Assert.Contains(expectedServerUri, serverUrisEncoded);
        }
예제 #15
0
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server
        /// </summary>
        public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                if (e.NotificationValue == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification == null)
                {
                    return;
                }

                DataValue value = notification.Value as DataValue;
                if (value == null)
                {
                    return;
                }

                JsonEncoder encoder        = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                string      applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri;
                encoder.WriteString("ApplicationUri", applicationURI);
                encoder.WriteString("DisplayName", monitoredItem.DisplayName);

                // write NodeId as ns=x;i=y
                NodeId nodeId = monitoredItem.ResolvedNodeId;
                encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString());

                // suppress output of server timestamp in json by setting it to minvalue
                value.ServerTimestamp = DateTime.MinValue;
                encoder.WriteDataValue("Value", value);

                string json = encoder.CloseAndReturnText();

                // add message to fifo send queue
                m_sendQueue.Enqueue(json);
            }
            catch (Exception exception)
            {
                Trace("Error processing monitored item notification: " + exception.ToString());
            }
        }
예제 #16
0
        public void Constructor_Stream()
        {
            var context      = new ServiceMessageContext();
            var memoryStream = new MemoryStream();

            using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, true))
            {
                TestEncoding(jsonEncoder);
            }
            var result1 = Encoding.UTF8.GetString(memoryStream.ToArray());

            Assert.IsNotEmpty(result1);
            TestContext.Out.WriteLine("Result1:");
            _ = PrettifyAndValidateJson(result1);

            // recycle the StreamWriter, ensure the result is equal
            using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, true))
            {
                TestEncoding(jsonEncoder);
            }
            var result2 = Encoding.UTF8.GetString(memoryStream.ToArray());

            Assert.IsNotEmpty(result2);
            TestContext.Out.WriteLine("Result2:");
            _ = PrettifyAndValidateJson(result2);
            Assert.AreEqual(result1, result2);

            // recycle the StreamWriter, ensure the result is equal,
            // use reflection to return result in external stream
            using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, false))
            {
                TestEncoding(jsonEncoder);
                var result3 = jsonEncoder.CloseAndReturnText();
                Assert.IsNotEmpty(result3);
                TestContext.Out.WriteLine("Result3:");
                _ = PrettifyAndValidateJson(result3);
                Assert.AreEqual(result1, result3);
            }

            // ensure the memory stream was closed
            Assert.Throws <ArgumentException>(() => _ = new StreamWriter(memoryStream));
        }
예제 #17
0
        public void Test_WriteSingleEncodeableWithoutName(bool topLevelIsArray, string expected)
        {
            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);

            using (var encodeable = new FooBarEncodeable())
            {
                var encoder = new JsonEncoder(Context, true, null, topLevelIsArray);

                encoder.WriteEncodeable(null, encodeable, typeof(FooBarEncodeable));

                var encoded = encoder.CloseAndReturnText();

                TestContext.Out.WriteLine("Encoded:");
                TestContext.Out.WriteLine(encoded);

                TestContext.Out.WriteLine("Formatted Encoded:");
                _ = PrettifyAndValidateJson(encoded);

                Assert.That(encoded, Is.EqualTo(expected));
            }
        }
예제 #18
0
        public void TestFieldValueEscapedVariant(string fieldname, string foo, string expected)
        {
            TestContext.Out.WriteLine("Expected:");
            _ = PrettifyAndValidateJson(expected);

            using (var encodeable = new FooBarEncodeable(fieldname, foo))
            {
                var variant = new Variant(new ExtensionObject(encodeable));
                // non reversible to save some space
                var encoder = new JsonEncoder(Context, false);
                encoder.WriteVariant(encodeable.FieldName, variant);

                var encoded = encoder.CloseAndReturnText();
                TestContext.Out.WriteLine("Encoded:");
                TestContext.Out.WriteLine(encoded);

                TestContext.Out.WriteLine("Formatted Encoded:");
                _ = PrettifyAndValidateJson(encoded);

                Assert.That(encoded, Is.EqualTo(expected));
            }
        }
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server.
        /// </summary>
        public void MonitoredItemNotificationEventHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                if (e == null || e.NotificationValue == null || monitoredItem == null || monitoredItem.Subscription == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                if (!(e.NotificationValue is MonitoredItemNotification notification))
                {
                    return;
                }

                if (!(notification.Value is DataValue value))
                {
                    return;
                }

                MessageData messageData = new MessageData();
                if (IotCentralMode)
                {
                    // for IoTCentral we use the DisplayName as the key in the telemetry and the Value as the value.
                    if (monitoredItem.DisplayName != null)
                    {
                        // use the DisplayName as reported in the MonitoredItem
                        messageData.DisplayName = monitoredItem.DisplayName;
                    }
                    if (value.Value != null)
                    {
                        // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder
                        JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                        value.ServerTimestamp = DateTime.MinValue;
                        value.SourceTimestamp = DateTime.MinValue;
                        value.StatusCode      = StatusCodes.Good;
                        encoder.WriteDataValue("Value", value);
                        string valueString = encoder.CloseAndReturnText();
                        // we only want the value string, search for everything till the real value starts
                        // and get it
                        string marker      = "{\"Value\":{\"Value\":";
                        int    markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture);
                        messageData.PreserveValueQuotes = true;
                        if (markerStart >= 0)
                        {
                            // we either have a value in quotes or just a value
                            int valueLength;
                            int valueStart = marker.Length;
                            if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0)
                            {
                                // value is in quotes and two closing curly brackets at the end
                                valueStart++;
                                valueLength = valueString.Length - valueStart - 3;
                            }
                            else
                            {
                                // value is without quotes with two curly brackets at the end
                                valueLength = valueString.Length - marker.Length - 2;
                                messageData.PreserveValueQuotes = false;
                            }
                            messageData.Value = valueString.Substring(valueStart, valueLength);
                        }
                        Logger.Debug($"   IoTCentral key: {messageData.DisplayName}");
                        Logger.Debug($"   IoTCentral values: {messageData.Value}");
                    }
                }
                else
                {
                    // update the required message data to pass only the required data to HubCommunication
                    EndpointTelemetryConfiguration telemetryConfiguration = GetEndpointTelemetryConfiguration(EndpointUrl);

                    // the endpoint URL is required to allow HubCommunication lookup the telemetry configuration
                    messageData.EndpointUrl = EndpointUrl;
                    if (telemetryConfiguration.NodeId.Publish == true)
                    {
                        messageData.NodeId = OriginalId;
                    }
                    if (telemetryConfiguration.MonitoredItem.ApplicationUri.Publish == true)
                    {
                        messageData.ApplicationUri = (monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri + (string.IsNullOrEmpty(OpcSession.PublisherSite) ? "" : $":{OpcSession.PublisherSite}"));
                    }
                    if (telemetryConfiguration.MonitoredItem.DisplayName.Publish == true && monitoredItem.DisplayName != null)
                    {
                        // use the DisplayName as reported in the MonitoredItem
                        messageData.DisplayName = monitoredItem.DisplayName;
                    }
                    if (telemetryConfiguration.Value.SourceTimestamp.Publish == true && value.SourceTimestamp != null)
                    {
                        // use the SourceTimestamp as reported in the notification event argument in ISO8601 format
                        messageData.SourceTimestamp = value.SourceTimestamp.ToString("o", CultureInfo.InvariantCulture);
                    }
                    if (telemetryConfiguration.Value.StatusCode.Publish == true && value.StatusCode != null)
                    {
                        // use the StatusCode as reported in the notification event argument
                        messageData.StatusCode = value.StatusCode.Code;
                    }
                    if (telemetryConfiguration.Value.Status.Publish == true && value.StatusCode != null)
                    {
                        // use the StatusCode as reported in the notification event argument to lookup the symbolic name
                        messageData.Status = StatusCode.LookupSymbolicId(value.StatusCode.Code);
                    }
                    if (telemetryConfiguration.Value.Value.Publish == true && value.Value != null)
                    {
                        // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder
                        JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                        value.ServerTimestamp = DateTime.MinValue;
                        value.SourceTimestamp = DateTime.MinValue;
                        value.StatusCode      = StatusCodes.Good;
                        encoder.WriteDataValue("Value", value);
                        string valueString = encoder.CloseAndReturnText();
                        // we only want the value string, search for everything till the real value starts
                        // and get it
                        string marker      = "{\"Value\":{\"Value\":";
                        int    markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture);
                        messageData.PreserveValueQuotes = true;
                        if (markerStart >= 0)
                        {
                            // we either have a value in quotes or just a value
                            int valueLength;
                            int valueStart = marker.Length;
                            if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0)
                            {
                                // value is in quotes and two closing curly brackets at the end
                                valueStart++;
                                valueLength = valueString.Length - valueStart - 3;
                            }
                            else
                            {
                                // value is without quotes with two curly brackets at the end
                                valueLength = valueString.Length - marker.Length - 2;
                                messageData.PreserveValueQuotes = false;
                            }
                            messageData.Value = valueString.Substring(valueStart, valueLength);
                        }
                    }

                    // currently the pattern processing is done here, which adds runtime to the notification processing.
                    // In case of perf issues it can be also done in CreateJsonMessageAsync of IoTHubMessaging.cs.

                    // apply patterns
                    messageData.ApplyPatterns(telemetryConfiguration);

                    Logger.Debug($"   ApplicationUri: {messageData.ApplicationUri}");
                    Logger.Debug($"   EndpointUrl: {messageData.EndpointUrl}");
                    Logger.Debug($"   DisplayName: {messageData.DisplayName}");
                    Logger.Debug($"   Value: {messageData.Value}");
                }

                // add message to fifo send queue
                if (monitoredItem.Subscription == null)
                {
                    Logger.Debug($"Subscription already removed. No more details available.");
                }
                else
                {
                    Logger.Debug($"Enqueue a new message from subscription {(monitoredItem.Subscription == null ? "removed" : monitoredItem.Subscription.Id.ToString(CultureInfo.InvariantCulture))}");
                    Logger.Debug($" with publishing interval: {monitoredItem.Subscription.PublishingInterval} and sampling interval: {monitoredItem.SamplingInterval}):");
                }
                HubCommunication.Enqueue(messageData);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error processing monitored item notification");
            }
        }
예제 #20
0
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server
        /// </summary>
        public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                if (e.NotificationValue == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification == null)
                {
                    return;
                }

                DataValue value = notification.Value as DataValue;
                if (value == null)
                {
                    return;
                }

                JsonEncoder encoder        = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                string      applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri;
                encoder.WriteString("ApplicationUri", applicationURI);
                encoder.WriteString("DisplayName", monitoredItem.DisplayName);

                // write NodeId as ns=x;i=y
                NodeId nodeId = monitoredItem.ResolvedNodeId;
                encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString());

                // suppress output of server timestamp in json by setting it to minvalue
                value.ServerTimestamp = DateTime.MinValue;
                encoder.WriteDataValue("Value", value);

                string json  = encoder.CloseAndReturnText();
                byte[] bytes = new UTF8Encoding(false).GetBytes(json);

                // publish
                var properties = new Dictionary <string, string>();
                properties.Add("content-type", "application/opcua+uajson");
                properties.Add("deviceName", m_deviceName);

                if (m_accessKey != null)
                {
                    properties.Add("source", "mapping");
                    properties.Add("deviceKey", m_accessKey);
                }

                try
                {
                    Publish(new Message(json, properties));
                    Trace("Opc.Ua.Publisher.Module: Published: " + json + " from " + m_deviceName);
                }
                catch (Exception ex)
                {
                    Trace("Opc.Ua.Publisher.Module: Failed to publish message, dropping...");
                    Trace(ex.ToString());
                }
            }
            catch (Exception exception)
            {
                Trace("Opc.Ua.Publisher.Module: Error processing monitored item notification: " + exception.ToString());
            }
        }