/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { try { var context = new ServiceMessageContext(); var decoder = new BinaryDecoder(new MemoryStream(payload), context); var messages = decoder.ReadBoolean(null) // is Batch? ? decoder.ReadEncodeableArray(null, typeof(NetworkMessage)) as NetworkMessage[] : (decoder.ReadEncodeable(null, typeof(NetworkMessage)) as NetworkMessage).YieldReturn(); foreach (var message in messages) { foreach (var dataSetMessage in message.Messages) { var dataset = new DataSetMessageModel { PublisherId = message.PublisherId, MessageId = message.MessageId, DataSetClassId = message.DataSetClassId, DataSetWriterId = dataSetMessage.DataSetWriterId, SequenceNumber = dataSetMessage.SequenceNumber, Status = StatusCode.LookupSymbolicId(dataSetMessage.Status.Code), MetaDataVersion = $"{dataSetMessage.MetaDataVersion.MajorVersion}" + $".{dataSetMessage.MetaDataVersion.MinorVersion}", Timestamp = dataSetMessage.Timestamp, Payload = new Dictionary <string, DataValueModel>() }; foreach (var datapoint in dataSetMessage.Payload) { var codec = _encoder.Create(context); var type = BuiltInType.Null; dataset.Payload[datapoint.Key] = new DataValueModel { Value = datapoint.Value == null ? null : codec.Encode(datapoint.Value.WrappedValue, out type), DataType = type == BuiltInType.Null ? null : type.ToString(), Status = (datapoint.Value?.StatusCode.Code == StatusCodes.Good) ? null : StatusCode.LookupSymbolicId(datapoint.Value.StatusCode.Code), SourceTimestamp = (datapoint.Value?.SourceTimestamp == DateTime.MinValue) ? null : datapoint.Value?.SourceTimestamp, SourcePicoseconds = (datapoint.Value?.SourcePicoseconds == 0) ? null : datapoint.Value?.SourcePicoseconds, ServerTimestamp = (datapoint.Value?.ServerTimestamp == DateTime.MinValue) ? null : datapoint.Value?.ServerTimestamp, ServerPicoseconds = (datapoint.Value?.ServerPicoseconds == 0) ? null : datapoint.Value?.ServerPicoseconds }; } await Task.WhenAll(_handlers.Select(h => h.HandleMessageAsync(dataset))); } } } catch (Exception ex) { _logger.Error(ex, "Subscriber binary network message handling failed - skip"); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { try { var context = new ServiceMessageContext(); var decoder = new BinaryDecoder(new MemoryStream(payload), context); var messages = decoder.ReadBoolean(null) // is Batch? ? decoder.ReadEncodeableArray(null, typeof(MonitoredItemMessage)) as MonitoredItemMessage[] : (decoder.ReadEncodeable(null, typeof(MonitoredItemMessage)) as MonitoredItemMessage).YieldReturn(); foreach (var message in messages) { var type = BuiltInType.Null; var codec = _encoder.Create(context); var dataset = new DataSetMessageModel { PublisherId = (message.ExtensionFields != null && message.ExtensionFields.TryGetValue("PublisherId", out var publisherId)) ? publisherId : message.ApplicationUri ?? message.EndpointUrl, MessageId = null, DataSetClassId = message.NodeId.AsString(null), DataSetWriterId = (message.ExtensionFields != null && message.ExtensionFields.TryGetValue("DataSetWriterId", out var dataSetWriterId)) ? dataSetWriterId : message.EndpointUrl ?? message.ApplicationUri, SequenceNumber = message.SequenceNumber, Status = StatusCode.LookupSymbolicId(message.Value.StatusCode.Code), MetaDataVersion = "1.0", Timestamp = message.Timestamp, Payload = new Dictionary <string, DataValueModel>() { [message.NodeId.AsString(context)] = new DataValueModel { Value = message?.Value == null ? null : codec.Encode(message.Value.WrappedValue, out type), DataType = type == BuiltInType.Null ? null : type.ToString(), Status = (message?.Value?.StatusCode.Code == StatusCodes.Good) ? null : StatusCode.LookupSymbolicId(message.Value.StatusCode.Code), SourceTimestamp = (message?.Value?.SourceTimestamp == DateTime.MinValue) ? null : message?.Value?.SourceTimestamp, SourcePicoseconds = (message?.Value?.SourcePicoseconds == 0) ? null : message?.Value?.SourcePicoseconds, ServerTimestamp = (message?.Value?.ServerTimestamp == DateTime.MinValue) ? null : message?.Value?.ServerTimestamp, ServerPicoseconds = (message?.Value?.ServerPicoseconds == 0) ? null : message?.Value?.ServerPicoseconds, } } }; await Task.WhenAll(_handlers.Select(h => h.HandleMessageAsync(dataset))); } } catch (Exception ex) { _logger.Error(ex, "Publishing messages failed - skip"); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { MonitoredItemMessage message; try { var context = new ServiceMessageContext(); using (var stream = new MemoryStream(payload)) { using (var decoder = new BinaryDecoder(stream, context)) { var result = decoder.ReadEncodeable(null, typeof(MonitoredItemMessage)) as MonitoredItemMessage; message = result; } } } catch (Exception ex) { _logger.Error(ex, "Failed to decode message"); return; } try { var dataset = new DataSetMessageModel { PublisherId = (message.ExtensionFields != null && message.ExtensionFields.TryGetValue("PublisherId", out var publisherId)) ? publisherId : message.ApplicationUri ?? message.EndpointUrl, MessageId = null, DataSetClassId = message.NodeId.AsString(null), DataSetWriterId = (message.ExtensionFields != null && message.ExtensionFields.TryGetValue("DataSetWriterId", out var dataSetWriterId)) ? dataSetWriterId : message.EndpointUrl ?? message.ApplicationUri, SequenceNumber = 0, Status = StatusCode.LookupSymbolicId(message.Value.StatusCode.Code), MetaDataVersion = "1.0", Timestamp = message.Timestamp, Payload = new Dictionary <string, DataValueModel>() { [message.NodeId.AsString(null)] = new DataValueModel() { Value = message?.Value?.WrappedValue.Value, Status = (message?.Value?.StatusCode.Code == StatusCodes.Good) ? null : StatusCode.LookupSymbolicId(message.Value.StatusCode.Code), SourceTimestamp = (message?.Value?.SourceTimestamp == DateTime.MinValue) ? null : (DateTime?)message?.Value?.SourceTimestamp, ServerTimestamp = (message?.Value?.ServerTimestamp == DateTime.MinValue) ? null : (DateTime?)message?.Value?.ServerTimestamp } } }; await Task.WhenAll(_handlers.Select(h => h.HandleMessageAsync(dataset))); } catch (Exception ex) { _logger.Error(ex, "Publishing message {message} failed with exception - skip", message); } }
/// <summary> /// Extracts the extension object body. /// </summary> /// <param name="value">Extension object.</param> /// <returns>IEncodeable object</returns> public static object GetExtensionObjectBody(ExtensionObject value) { object body = value.Body; IEncodeable encodeable = body as IEncodeable; if (encodeable != null) { return(encodeable); } Type expectedType = EncodeableFactory.GetSystemType(value.TypeId); if (expectedType == null) { return(body); } IServiceMessageContext context = new ServiceMessageContext() { Factory = EncodeableFactory }; XmlElement xml = body as XmlElement; if (xml != null) { XmlQualifiedName xmlName = Opc.Ua.EncodeableFactory.GetXmlName(expectedType); XmlDecoder decoder = new XmlDecoder(xml, context); decoder.PushNamespace(xmlName.Namespace); body = decoder.ReadEncodeable(xmlName.Name, expectedType); decoder.PopNamespace(); decoder.Close(); return((IEncodeable)body); } byte[] bytes = body as byte[]; if (bytes != null) { BinaryDecoder decoder = new BinaryDecoder(bytes, context); body = decoder.ReadEncodeable(null, expectedType); decoder.Close(); return((IEncodeable)body); } return(body); }
/// <summary> /// Convert buffer to encodeable /// </summary> /// <param name="buffer"></param> /// <param name="typeId"></param> /// <param name="context"></param> /// <returns></returns> public static IEncodeable ToEncodeable(this byte[] buffer, ExpandedNodeId typeId, IServiceMessageContext context) { var systemType = TypeInfo.GetSystemType(typeId.ToNodeId(context.NamespaceUris), context.Factory); if (systemType == null) { return(null); } using (var decoder = new BinaryDecoder(buffer, context)) { return(decoder.ReadEncodeable(null, systemType)); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { MonitoredItemMessage message; try { var context = new ServiceMessageContext(); using (var stream = new MemoryStream(payload)) { using (var decoder = new BinaryDecoder(stream, context)) { var result = decoder.ReadEncodeable(null, typeof(MonitoredItemMessage)) as MonitoredItemMessage; message = result; } } } catch (Exception ex) { _logger.Error(ex, "Failed to decode message"); return; } try { var sample = new MonitoredItemSampleModel() { Value = (message?.Value?.WrappedValue.Value != null) ? message.Value.WrappedValue.Value : null, Status = StatusCode.LookupSymbolicId(message.Value.StatusCode.Code), TypeId = (message?.Value?.WrappedValue.TypeInfo != null) ? TypeInfo.GetSystemType( message.Value.WrappedValue.TypeInfo.BuiltInType, message.Value.WrappedValue.TypeInfo.ValueRank) : null, DataSetId = !string.IsNullOrEmpty(message.DisplayName) ? message.DisplayName : message.NodeId.AsString(null), Timestamp = message.Timestamp, EndpointId = (message.ExtensionFields != null && message.ExtensionFields.TryGetValue("EndpointId", out var endpointId)) ? endpointId : message.ApplicationUri ?? message.SubscriptionId, SubscriptionId = message.SubscriptionId ?? message.ApplicationUri, NodeId = message.NodeId.AsString(null), DisplayName = message.DisplayName, SourcePicoseconds = message.Value.SourcePicoseconds, ServerPicoseconds = message.Value.ServerPicoseconds, SourceTimestamp = message.Value.SourceTimestamp, ServerTimestamp = message.Value.ServerTimestamp }; await Task.WhenAll(_handlers.Select(h => h.HandleSampleAsync(sample))); } catch (Exception ex) { _logger.Error(ex, "Publishing message {message} failed with exception - skip", message); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { var json = Encoding.UTF8.GetString(payload); using (var stream = new MemoryStream(payload)) { var context = new ServiceMessageContext(); using (var decoder = new BinaryDecoder(stream, context)) { var networkMessage = decoder.ReadEncodeable(null, typeof(NetworkMessage)) as NetworkMessage; foreach (var message in networkMessage.Messages) { foreach (var datapoint in message.Payload) { try { var sample = new MonitoredItemSampleModel() { Value = (datapoint.Value?.WrappedValue.Value != null) ? datapoint.Value.WrappedValue.Value : null, Status = StatusCode.LookupSymbolicId(datapoint.Value.StatusCode.Code), TypeId = (datapoint.Value?.WrappedValue.TypeInfo != null) ? TypeInfo.GetSystemType( datapoint.Value.WrappedValue.TypeInfo.BuiltInType, datapoint.Value.WrappedValue.TypeInfo.ValueRank) : null, DataSetId = message.DataSetWriterId, Timestamp = DateTime.UtcNow, SubscriptionId = message.DataSetWriterId, EndpointId = networkMessage.PublisherId, NodeId = datapoint.Key, SourcePicoseconds = datapoint.Value.SourcePicoseconds, ServerPicoseconds = datapoint.Value.ServerPicoseconds, SourceTimestamp = datapoint.Value.SourceTimestamp, ServerTimestamp = datapoint.Value.ServerTimestamp }; if (sample == null) { continue; } await Task.WhenAll(_handlers.Select(h => h.HandleSampleAsync(sample))); } catch (Exception ex) { _logger.Error(ex, "Subscriber message {message} failed with exception - skip", message); } } } } } }
/// <summary> /// Decodes a message from a buffer. /// </summary> private static IEncodeable DecodeBinaryMessage(Stream stream, ServiceMessageContext context) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } MemoryStream buffer = null; try { // // Binary decoder unfortunately uses seeking (to keep track of // position). Therefore we need to wrap a non seeking stream. // if (!stream.CanSeek) { // Read entire buffer and pass as memory stream. var segment = stream.ReadAsBuffer(); stream = buffer = new MemoryStream(segment.Array, 0, segment.Count); } using (var decoder = new BinaryDecoder(stream, context)) { // read the node id. var typeId = decoder.ReadNodeId(null); // convert to absolute node id. var absoluteId = NodeId.ToExpandedNodeId(typeId, context.NamespaceUris); // lookup message type. var actualType = context.Factory.GetSystemType(absoluteId); if (actualType == null) { throw new ServiceResultException(StatusCodes.BadEncodingError, $"Cannot decode message with type id: {absoluteId}."); } // read the message. return(decoder.ReadEncodeable(null, actualType)); } } finally { buffer?.Dispose(); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { var json = Encoding.UTF8.GetString(payload); using (var stream = new MemoryStream(payload)) { var context = new ServiceMessageContext(); try { using (var decoder = new BinaryDecoder(stream, context)) { var networkMessage = decoder.ReadEncodeable(null, typeof(NetworkMessage)) as NetworkMessage; foreach (var dataSetMessage in networkMessage.Messages) { var dataset = new DataSetMessageModel { PublisherId = networkMessage.PublisherId, MessageId = networkMessage.MessageId, DataSetClassId = networkMessage.DataSetClassId, DataSetWriterId = dataSetMessage.DataSetWriterId, SequenceNumber = dataSetMessage.SequenceNumber, Status = StatusCode.LookupSymbolicId(dataSetMessage.Status.Code), MetaDataVersion = $"{dataSetMessage.MetaDataVersion.MajorVersion}" + $".{dataSetMessage.MetaDataVersion.MinorVersion}", Timestamp = dataSetMessage.Timestamp, Payload = new Dictionary <string, DataValueModel>() }; foreach (var datapoint in dataSetMessage.Payload) { dataset.Payload[datapoint.Key] = new DataValueModel() { Value = datapoint.Value?.Value, Status = (datapoint.Value?.StatusCode.Code == StatusCodes.Good) ? null : StatusCode.LookupSymbolicId(datapoint.Value.StatusCode.Code), SourceTimestamp = (datapoint.Value?.SourceTimestamp == DateTime.MinValue) ? null : (DateTime?)datapoint.Value?.SourceTimestamp, ServerTimestamp = (datapoint.Value?.ServerTimestamp == DateTime.MinValue) ? null : (DateTime?)datapoint.Value?.ServerTimestamp }; } await Task.WhenAll(_handlers.Select(h => h.HandleMessageAsync(dataset))); } } } catch (Exception ex) { _logger.Error(ex, "Subscriber binary network message handling failed - skip"); } } }