Exemple #1
0
 /// <inheritdoc/>
 public Task HandleSampleAsync(MonitoredItemSampleModel sample)
 {
     // Set timestamp as source timestamp
     // TODO: Make configurable
     sample.Timestamp = sample.SourceTimestamp;
     return(_client.SendAsync(Encoding.UTF8.GetBytes(
                                  JsonConvertEx.SerializeObject(sample))));
 }
Exemple #2
0
        /// <inheritdoc/>
        public async Task HandleSampleAsync(MonitoredItemSampleModel sample)
        {
            var arguments = new object[] { sample.ToApiModel() };

            if (!string.IsNullOrEmpty(sample.EndpointId))
            {
                // Send to endpoint listeners
                await _callback.MulticastAsync(sample.EndpointId,
                                               EventTargets.PublisherSampleTarget, arguments);
            }
        }
 /// <inheritdoc/>
 private string GetNormalizedEntityName(MonitoredItemSampleModel sample)
 {
     if (string.IsNullOrEmpty(sample.PublisherId) ||
         string.IsNullOrEmpty(sample.DataSetWriterId) ||
         string.IsNullOrEmpty(sample.NodeId))
     {
         return(null);
     }
     return(GetNormalizedKey($"{sample.PublisherId}_{sample.DataSetWriterId}" +
                             $"_{sample.NodeId}"));
 }
Exemple #4
0
        /// <inheritdoc/>
        public Task HandleSampleAsync(MonitoredItemSampleModel sample)
        {
            // Set timestamp as source timestamp
            var properties = new Dictionary <string, string>()
            {
                [CommonProperties.EventSchemaType] =
                    MessageSchemaTypes.MonitoredItemMessageModelJson
            };

            return(_client.SendAsync(Encoding.UTF8.GetBytes(
                                         JsonConvertEx.SerializeObject(sample)), properties));
        }
Exemple #5
0
        /// <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 JsonDecoderEx(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>
 /// Convert to api model
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static MonitoredItemMessageApiModel ToApiModel(
     this MonitoredItemSampleModel model)
 {
     return(new MonitoredItemMessageApiModel {
         SubscriptionId = model.SubscriptionId,
         EndpointId = model.EndpointId,
         DataSetId = model.DataSetId,
         NodeId = model.NodeId,
         ServerPicoseconds = model.ServerPicoseconds,
         ServerTimestamp = model.ServerTimestamp,
         SourcePicoseconds = model.SourcePicoseconds,
         SourceTimestamp = model.SourceTimestamp,
         Timestamp = model.Timestamp,
         Value = model.Value
     });
 }
        /// <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 JsonDecoderEx(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         = DateTime.UtcNow,
                    SubscriptionId    = message.SubscriptionId,
                    EndpointId        = message?.ExtensionFields["EndpointId"],
                    NodeId            = message.NodeId.AsString(null),
                    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 Task HandleSampleAsync(MonitoredItemSampleModel sample)
        {
            var cdmModel = new SubscriberCdmSampleModel()
            {
                SubscriptionId = sample.SubscriptionId,
                EndpointId     = sample.EndpointId,
                DataSetId      = sample.DataSetId,
                NodeId         = sample.NodeId,
                Value          = sample.Value.ToString(),
                // Set timestamp as source timestamp - todo make configurable
                Timestamp       = sample.SourceTimestamp,
                ServerTimestamp = sample.ServerTimestamp,
                SourceTimestamp = sample.SourceTimestamp
            };

            return(_client.ProcessAsync(cdmModel));
        }
 /// <summary>
 /// Clone sample
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static MonitoredItemSampleModel Clone(this MonitoredItemSampleModel model)
 {
     if (model == null)
     {
         return(null);
     }
     return(new MonitoredItemSampleModel {
         SubscriptionId = model.SubscriptionId,
         EndpointId = model.EndpointId,
         DataSetId = model.DataSetId,
         NodeId = model.NodeId,
         ServerPicoseconds = model.ServerPicoseconds,
         ServerTimestamp = model.ServerTimestamp,
         SourcePicoseconds = model.SourcePicoseconds,
         SourceTimestamp = model.SourceTimestamp,
         Timestamp = model.Timestamp,
         TypeId = model.TypeId,
         Value = model.Value,
         Status = model.Status
     });
 }
 /// <summary>
 /// Convert to api model
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static MonitoredItemMessageApiModel ToApiModel(
     this MonitoredItemSampleModel model)
 {
     if (model == null)
     {
         return(null);
     }
     return(new MonitoredItemMessageApiModel {
         PublisherId = model.PublisherId,
         DataSetWriterId = model.DataSetWriterId,
         EndpointId = model.EndpointId,
         NodeId = model.NodeId,
         DisplayName = model.DisplayName,
         ServerTimestamp = model.ServerTimestamp,
         SourceTimestamp = model.SourceTimestamp,
         Timestamp = model.Timestamp,
         Value = model.TypeId?.IsPrimitive == true ?
                 model.Value : model.Value?.ToString(),
         TypeId = model?.TypeId?.FullName,
         Status = model.Status
     });
 }
Exemple #11
0
 /// <summary>
 /// Convert to api model
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static MonitoredItemMessageApiModel ToApiModel(
     this MonitoredItemSampleModel model)
 {
     if (model == null)
     {
         return(null);
     }
     return(new MonitoredItemMessageApiModel {
         SubscriptionId = model.SubscriptionId,
         EndpointId = model.EndpointId,
         DataSetId = model.DataSetId,
         NodeId = model.NodeId,
         ServerPicoseconds = model.ServerPicoseconds,
         ServerTimestamp = model.ServerTimestamp,
         SourcePicoseconds = model.SourcePicoseconds,
         SourceTimestamp = model.SourceTimestamp,
         Timestamp = model.Timestamp,
         Value = model.TypeId?.IsPrimitive == true ?
                 model.Value : model.Value?.ToString(),
         TypeId = model?.TypeId?.FullName,
         Status = model.Status
     });
 }
        private bool GetEntityData(MonitoredItemSampleModel sample,
                                   out string partitionLocation, out string partitionDelimitor)
        {
            partitionLocation  = null;
            partitionDelimitor = kCsvPartitionsDelimiter;
            var key = GetNormalizedEntityName(sample.EndpointId, sample.NodeId);
            var entityDeclaration = Manifest.Entities.Item(key);

            if (entityDeclaration == null)
            {
                return(false);
            }
            var partition = entityDeclaration?.DataPartitions[0];

            if (partition == null)
            {
                return(false);
            }
            var csvTrait = partition.ExhibitsTraits.Item("is.partition.format.CSV");

            partitionLocation  = _cdmCorpus.Storage.CorpusPathToAdapterPath(partition.Location);
            partitionDelimitor = csvTrait?.Arguments?.FetchValue("delimiter") ?? kCsvPartitionsDelimiter;
            return(true);
        }
        private bool CreateEntityData(MonitoredItemSampleModel sample,
                                      out string partitionLocation, out string partitionDelimitor)
        {
            string key = GetNormalizedEntityName(sample.EndpointId, sample.NodeId);

            // check if the enetity was aleready added
            var entity = Manifest.Entities.Item(key);

            if (entity != null)
            {
                return(GetEntityData(sample, out partitionLocation, out partitionDelimitor));
            }

            // add a new entity for the Message
            var newSampleEntity = _cdmCorpus.MakeObject <CdmEntityDefinition>(
                CdmObjectType.EntityDef, key, false);

            var info = typeof(MonitoredItemSampleModel).GetProperties();

            foreach (var property in info)
            {
                // add the attributes required
                var attribute = _cdmCorpus.MakeObject <CdmTypeAttributeDefinition>(
                    CdmObjectType.TypeAttributeDef, property.Name, false);
                attribute.Purpose = _cdmCorpus.MakeRef <CdmPurposeReference>(
                    CdmObjectType.PurposeRef, "hasA", true);
                //  if we handle a value, lookup it's type property
                if (property.Name == "Value" &&
                    typeof(MonitoredItemSampleModel).
                    GetProperty("TypeId")?.GetValue(sample) is Type typeId)
                {
                    attribute.DataFormat = DataTypeToCdmDataFormat(typeId);
                }
                else
                {
                    attribute.DataFormat = DataTypeToCdmDataFormat(property.PropertyType);
                }
                attribute.DataType = _cdmCorpus.MakeRef <CdmDataTypeReference>(
                    CdmObjectType.DataTypeRef,
                    DataTypeToCdmDataString(attribute.DataFormat), true);
                newSampleEntity.Attributes.Add(attribute);
            }

            newSampleEntity.DisplayName = kPublisherSampleEntityName;
            newSampleEntity.Version     = "0.0.1";
            newSampleEntity.Description = "Opc Ua monitored item  sample model";

            // Create a new document where the new entity's definition will be stored
            var newSampleEntityDoc = _cdmCorpus.MakeObject <CdmDocumentDefinition>(
                CdmObjectType.DocumentDef, $"{newSampleEntity.EntityName}.cdm.json", false);

            newSampleEntityDoc.Imports.Add($"{newSampleEntity.EntityName}.cdm.json");
            // TODO: remove - apparently not necessary
            //newSampleEntityDoc.Imports.Add(kFoundationJsonPath);
            newSampleEntityDoc.Definitions.Add(newSampleEntity);
            _cdmCorpus.Storage.FetchRootFolder("adls").Documents.Add(
                newSampleEntityDoc, newSampleEntityDoc.Name);
            var newSampleEntityDef = Manifest.Entities.Add(newSampleEntity);

            // Define a partition and add it to the local declaration
            var newSampleEntityPartition = _cdmCorpus.MakeObject <CdmDataPartitionDefinition>(
                CdmObjectType.DataPartitionDef, newSampleEntity.EntityName);

            newSampleEntityDef.DataPartitions.Add(newSampleEntityPartition);
            newSampleEntityPartition.Location =
                $"adls:/{newSampleEntity.EntityName}/partition-data.csv";
            newSampleEntityPartition.Explanation = "Opc Ua monitored item sample messages storage";
            var csvTrait = newSampleEntityPartition.ExhibitsTraits.Add(
                "is.partition.format.CSV");

            csvTrait.Arguments.Add("columnHeaders", "true");
            csvTrait.Arguments.Add("delimiter", kCsvPartitionsDelimiter);

            partitionLocation  = _cdmCorpus.Storage.CorpusPathToAdapterPath(newSampleEntityPartition.Location);
            partitionDelimitor = csvTrait?.Arguments?.FetchValue("delimiter") ?? kCsvPartitionsDelimiter;
            return(true);
        }
        /// <inheritdoc/>
        private CdmDataPartitionDefinition GetOrCreateEntityDataPartition(string key,
                                                                          MonitoredItemSampleModel sample, out bool persist, bool forceNew = false)
        {
            persist = false;
            if (string.IsNullOrEmpty(key) || sample == null)
            {
                return(null);
            }

            // check if the enetity was aleready added
            var entityDefinition = Manifest.Entities.Item(key);

            if (entityDefinition == null)
            {
                // add a new entity for the sample

                // add a new entity for the Message
                var newSampleEntity = _cdmCorpus.MakeObject <CdmEntityDefinition>(
                    CdmObjectType.EntityDef, key, false);

                var info = typeof(MonitoredItemSampleModel).GetProperties();
                foreach (var property in info)
                {
                    // add the attributes required
                    var attribute = _cdmCorpus.MakeObject <CdmTypeAttributeDefinition>(
                        CdmObjectType.TypeAttributeDef, property.Name, false);
                    attribute.Purpose = _cdmCorpus.MakeRef <CdmPurposeReference>(
                        CdmObjectType.PurposeRef, "hasA", true);
                    //  if we handle a value, lookup it's type property
                    if (property.Name == "Value")
                    {
                        attribute.DataFormat = DataTypeToCdmDataFormat(sample.Value.GetType());
                    }
                    else
                    {
                        attribute.DataFormat = DataTypeToCdmDataFormat(property.PropertyType);
                    }

                    newSampleEntity.Attributes.Add(attribute);
                }

                newSampleEntity.DisplayName = kPublisherSampleEntityName;
                newSampleEntity.Version     = "0.0.2";
                newSampleEntity.Description = "Opc Ua Monitored Item Sample";

                // Create a new document where the new entity's definition will be stored
                var newSampleEntityDoc = _cdmCorpus.MakeObject <CdmDocumentDefinition>(
                    CdmObjectType.DocumentDef, $"{newSampleEntity.EntityName}.cdm.json", false);
                newSampleEntityDoc.Imports.Add($"{newSampleEntity.EntityName}.cdm.json");
                // TODO: remove - apparently not necessary
                newSampleEntityDoc.Imports.Add(kFoundationJsonPath);
                newSampleEntityDoc.Definitions.Add(newSampleEntity);
                _cdmCorpus.Storage.FetchRootFolder("adls").Documents.Add(
                    newSampleEntityDoc, newSampleEntityDoc.Name);
                entityDefinition = Manifest.Entities.Add(newSampleEntity);
                persist         |= true;
            }

            var partition = entityDefinition.DataPartitions.Count != 0
                ? entityDefinition.DataPartitions.Last() : null;

            if (forceNew || partition == null)
            {
                // Define a partition and add it to the local declaration
                var newPartition = _cdmCorpus.MakeObject <CdmDataPartitionDefinition>(
                    CdmObjectType.DataPartitionDef, entityDefinition.EntityName);
                var timestamp = DateTime.UtcNow.ToString(
                    "yyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                newPartition.Location =
                    $"adls:/{entityDefinition.EntityName}/partition-data-{timestamp}.csv";
                newPartition.Explanation = "OPC UA PubSub DataSet Partition";
                var partitionTrait = newPartition.ExhibitsTraits.Add(
                    "is.partition.format.CSV");
                partitionTrait.Arguments.Add("columnHeaders", "true");
                partitionTrait.Arguments.Add("delimiter", kCsvPartitionsDelimiter);
                partition = entityDefinition.DataPartitions.Add(newPartition);
                persist  |= true;
            }
            return(partition);
        }
Exemple #15
0
 /// <inheritdoc/>
 public Task HandleSampleAsync(MonitoredItemSampleModel sample)
 {
     return(_client.ProcessAsync(sample));
 }