예제 #1
0
        public async Task HandleSaveOpcPublishedConfigurationAsJson_FormatIsRight_ShouldReinitializeNodeConfiguration(
            string testFilename,
            string testFileNameWithModifiedKey,
            int configuredSessions,
            int configuredSubscriptions,
            int configuredMonitoredItems,
            int configuredMonitoredEvents)
        {
            OpcNodeOnEndpointModel GetFirstNode()
            {
                var endpointId = NodeConfiguration.OpcSessions[0].EndpointId;
                var nodes      = NodeConfiguration.GetPublisherConfigurationFileEntries(endpointId, true, out uint version);

                return(nodes[0].OpcNodes[0]);
            }

            using (new ExecutionContext(testFilename))
            {
                var hubCommunicationBase = new HubCommunicationBase();
                AssertPreconditions(configuredSessions, configuredSubscriptions, configuredMonitoredItems, configuredMonitoredEvents);

                // Get node before saving new file.
                var opcNodeBeforeSave = GetFirstNode();

                // ------- Act -----

                // load different file with key change.
                var modifiedFilePath = CopyFileToTempData(testFileNameWithModifiedKey);
                // Read the file data as bytes
                var text = await File.ReadAllTextAsync(modifiedFilePath);

                var methodRequestModel = new HandleSaveOpcPublishedConfigurationMethodRequestModel(text);
                var json    = JsonConvert.SerializeObject(methodRequestModel);
                var bytes   = Encoding.UTF8.GetBytes(json);
                var request = new MethodRequest("SaveOpcPublishedConfigurationAsJson", bytes);
                // Feed the json string to the communication base
                var success = await hubCommunicationBase.HandleSaveOpcPublishedConfigurationAsJson(request, new object());

                // ------- Assert ------

                // The preconditions should not change, since only the key of the node is changed.
                AssertPreconditions(configuredSessions, configuredSubscriptions, configuredMonitoredItems, configuredMonitoredEvents);
                Assert.True(success.Status == (int)HttpStatusCode.OK);

                var opcNodeAfterSave = GetFirstNode();
                Assert.Equal(opcNodeBeforeSave.Id, opcNodeBeforeSave.Id);
                Assert.Equal("i=2267", opcNodeBeforeSave.Key);
                Assert.Equal("i=2267-test", opcNodeAfterSave.Key);
            }
        }
예제 #2
0
        /// <summary>
        /// Handle get message properties method call.
        /// </summary>
        public virtual Task <MethodResponse> HandleGetMessagePropertiesMethodAsync(MethodRequest methodRequest, object userContext)
        {
            var response = new GetMessagePropertiesReponseModel();

            var endpoints = NodeConfiguration.GetPublisherConfigurationFileEntries(Guid.Empty, false, out _)
                            .Select(e => new MessagePropertyValue(e.EndpointName, e.EndpointId.ToString()));
            var endpointMessageProperty = new MessageProperty("OPC UA endpoint", "endpointId", endpoints);

            response.Items.Add(endpointMessageProperty);

            string resultString = JsonConvert.SerializeObject(response);

            byte[] result = Encoding.UTF8.GetBytes(resultString);
            return(Task.FromResult(new MethodResponse(result, (int)HttpStatusCode.OK)));
        }
예제 #3
0
        /// <summary>
        /// Handle method call to get list of configured nodes on a specific endpoint.
        /// </summary>
        public virtual Task <MethodResponse> HandleGetConfiguredEventsOnEndpointMethodAsync(MethodRequest methodRequest, object userContext)
        {
            const string logPrefix    = "HandleGetConfiguredEventsOnEndpointMethodAsync:";
            Guid         endpointId   = Guid.Empty;
            string       endpointName = null;
            string       endpointUrl  = null;
            GetConfiguredNodesOnEndpointMethodRequestModel getConfiguredEventNodesOnEndpointMethodRequest = null;
            uint nodeConfigVersion = 0;
            GetConfiguredEventNodesOnEndpointMethodResponseModel getConfiguredEventNodesOnEndpointMethodResponse = new GetConfiguredEventNodesOnEndpointMethodResponseModel();
            uint   actualNodeCount         = 0;
            uint   availableEventNodeCount = 0;
            var    opcEvents      = new List <OpcEventOnEndpointModel>();
            uint   startIndex     = 0;
            var    statusCode     = HttpStatusCode.OK;
            var    statusResponse = new List <string>();
            string statusMessage;

            try
            {
                Logger.Debug($"{logPrefix} called");
                getConfiguredEventNodesOnEndpointMethodRequest = JsonConvert.DeserializeObject <GetConfiguredNodesOnEndpointMethodRequestModel>(methodRequest.DataAsJson);
                if (getConfiguredEventNodesOnEndpointMethodRequest.EndpointId == null)
                {
                    statusMessage = $"New endpoint: there are no event nodes configured";
                    Logger.Information($"{logPrefix} {statusMessage}");
                    statusResponse.Add(statusMessage);
                    statusCode = HttpStatusCode.NoContent;
                }
                else
                {
                    endpointId = new Guid(getConfiguredEventNodesOnEndpointMethodRequest.EndpointId);
                }
            }
            catch (FormatException e)
            {
                statusMessage = $"Exception ({e.Message}) while parsing EndpointId '{getConfiguredEventNodesOnEndpointMethodRequest?.EndpointId}'";
                Logger.Error(e, $"{logPrefix} {statusMessage}");
                statusResponse.Add(statusMessage);
                statusCode = HttpStatusCode.InternalServerError;
            }
            catch (Exception e)
            {
                statusMessage = $"Exception ({e.Message}) while deserializing message payload";
                Logger.Error(e, $"{logPrefix} Exception");
                statusResponse.Add(statusMessage);
                statusCode = HttpStatusCode.InternalServerError;
            }

            if (statusCode == HttpStatusCode.OK)
            {
                // get the list of published nodes for the endpoint
                List <PublisherConfigurationFileEntryModel> configFileEntries = NodeConfiguration.GetPublisherConfigurationFileEntries(endpointId, false, out nodeConfigVersion);

                // return if there are no nodes configured for this endpoint
                if (configFileEntries.Count == 0)
                {
                    statusMessage = $"There are no event nodes configured for endpoint '{endpointId.ToString()}'";
                    Logger.Information($"{logPrefix} {statusMessage}");
                    statusResponse.Add(statusMessage);
                    statusCode = HttpStatusCode.NoContent;
                }
                else
                {
                    endpointName = configFileEntries.First().EndpointName;
                    endpointUrl  = configFileEntries.First().EndpointUrl.ToString();
                    foreach (var configFileEntry in configFileEntries)
                    {
                        if (configFileEntry?.OpcEvents != null)
                        {
                            opcEvents.AddRange(configFileEntry.OpcEvents);
                        }
                    }
                    uint configuredEventNodesOnEndpointCount = (uint)opcEvents.Count();

                    // validate version
                    startIndex = 0;
                    if (getConfiguredEventNodesOnEndpointMethodRequest?.ContinuationToken != null)
                    {
                        uint requestedNodeConfigVersion = (uint)(getConfiguredEventNodesOnEndpointMethodRequest.ContinuationToken >> 32);
                        if (nodeConfigVersion != requestedNodeConfigVersion)
                        {
                            statusMessage = $"The event node configuration has changed between calls. Requested version: {requestedNodeConfigVersion:X8}, Current version '{nodeConfigVersion:X8}'!";
                            Logger.Information($"{logPrefix} {statusMessage}");
                            statusResponse.Add(statusMessage);
                            statusCode = HttpStatusCode.Gone;
                        }
                        startIndex = (uint)(getConfiguredEventNodesOnEndpointMethodRequest.ContinuationToken & 0x0FFFFFFFFL);
                    }

                    if (statusCode == HttpStatusCode.OK)
                    {
                        // set count
                        var requestedEventNodeCount = configuredEventNodesOnEndpointCount - startIndex;
                        availableEventNodeCount = configuredEventNodesOnEndpointCount - startIndex;
                        actualNodeCount         = Math.Min(requestedEventNodeCount, availableEventNodeCount);
                        opcEvents.ForEach(x => x.OpcPublisherPublishState = OpcPublisherPublishState.Published);

                        // generate response
                        while (true)
                        {
                            string publishedNodesString    = JsonConvert.SerializeObject(opcEvents.GetRange((int)startIndex, (int)actualNodeCount));
                            var    publishedNodesByteArray = Encoding.UTF8.GetBytes(publishedNodesString);
                            if (publishedNodesByteArray.Length > MaxResponsePayloadLength)
                            {
                                actualNodeCount /= 2;
                                continue;
                            }

                            break;
                        }
                    }
                }
            }

            // build response
            string resultString;

            if (statusCode == HttpStatusCode.OK)
            {
                getConfiguredEventNodesOnEndpointMethodResponse.ContinuationToken = null;
                if (actualNodeCount < availableEventNodeCount)
                {
                    getConfiguredEventNodesOnEndpointMethodResponse.ContinuationToken = (ulong)nodeConfigVersion << 32 | actualNodeCount + startIndex;
                }

                // Todo: check if EventConfigurationModel mit endpointName = endpointUrl = null ok?
                getConfiguredEventNodesOnEndpointMethodResponse.EventNodes
                .AddRange(opcEvents
                          .GetRange((int)startIndex, (int)actualNodeCount)
                          .Select(n =>
                                  new OpcEventOnEndpointModel(
                                      new EventConfigurationModel(
                                          endpointId.ToString(),
                                          endpointName,
                                          endpointUrl,
                                          null,
                                          OpcAuthenticationMode.Anonymous,
                                          null,
                                          n.Id,
                                          n.DisplayName,
                                          n.SelectClauses,
                                          n.WhereClause,
                                          n.IotCentralEventPublishMode
                                          ),
                                      OpcPublisherPublishState.Published
                                      )
                                  )
                          );
                getConfiguredEventNodesOnEndpointMethodResponse.EndpointId = endpointId.ToString();
                resultString = JsonConvert.SerializeObject(getConfiguredEventNodesOnEndpointMethodResponse);
                Logger.Information($"{logPrefix} Success returning {actualNodeCount} event node(s) of {availableEventNodeCount} (start: {startIndex}) (node config version: {nodeConfigVersion:X8})!");
            }
            else if (statusCode == HttpStatusCode.NoContent)
            {
                resultString = JsonConvert.SerializeObject(getConfiguredEventNodesOnEndpointMethodResponse);
                Logger.Information($"{logPrefix} Success returning 0 event nodes.");
            }
            else
            {
                resultString = JsonConvert.SerializeObject(statusResponse);
            }
            byte[] result = Encoding.UTF8.GetBytes(resultString);
            if (result.Length > MaxResponsePayloadLength)
            {
                Logger.Error($"{logPrefix} Response size is too long");
                Array.Resize(ref result, result.Length > MaxResponsePayloadLength ? MaxResponsePayloadLength : result.Length);
            }
            MethodResponse methodResponse = new MethodResponse(result, (int)statusCode);

            Logger.Information($"{logPrefix} completed with result {statusCode.ToString()}");
            return(Task.FromResult(methodResponse));
        }