public async Task PublishNodesStressTest()
        {
            var standaloneCliModelProviderMock = new Mock <IStandaloneCliModelProvider>();
            var agentConfigProviderMock        = new Mock <IAgentConfigProvider>();
            var engineConfigMock         = new Mock <IEngineConfiguration>();
            var clientConfignMock        = new Mock <IClientServicesConfig>();
            var newtonSoftJsonSerializer = new NewtonSoftJsonSerializer();
            var jobSerializer            = new PublisherJobSerializer(newtonSoftJsonSerializer);
            var logger = TraceLogger.Create();
            var publishedNodesJobConverter = new PublishedNodesJobConverter(logger, newtonSoftJsonSerializer,
                                                                            engineConfigMock.Object, clientConfignMock.Object);

            using (var fileStream = new FileStream(_tempFile, FileMode.Open, FileAccess.Write)) {
                fileStream.Write(Encoding.UTF8.GetBytes("[]"));
            }

            var standaloneCliModel = new StandaloneCliModel {
                PublishedNodesFile       = _tempFile,
                PublishedNodesSchemaFile = "Storage/publishednodesschema.json"
            };

            standaloneCliModelProviderMock.Setup(p => p.StandaloneCliModel).Returns(standaloneCliModel);
            agentConfigProviderMock.Setup(p => p.Config).Returns(new AgentConfigModel());

            var publishedNodesProvider = new PublishedNodesProvider(standaloneCliModelProviderMock.Object, logger);

            var orchestrator = new StandaloneJobOrchestrator(
                publishedNodesJobConverter,
                standaloneCliModelProviderMock.Object,
                agentConfigProviderMock.Object,
                jobSerializer,
                logger,
                publishedNodesProvider,
                newtonSoftJsonSerializer
                );

            var numberOfEndpoints = 100;
            var numberOfNodes     = 1000;

            var payload = new List <PublishedNodesEntryModel>();

            for (int endpointIndex = 0; endpointIndex < numberOfEndpoints; ++endpointIndex)
            {
                var model = new PublishedNodesEntryModel {
                    EndpointUrl = new Uri($"opc.tcp://server{endpointIndex}:49580"),
                };

                model.OpcNodes = new List <OpcNodeModel>();
                for (var nodeIndex = 0; nodeIndex < numberOfNodes; ++nodeIndex)
                {
                    model.OpcNodes.Add(new OpcNodeModel {
                        Id = $"ns=2;s=Node-Server-{nodeIndex}",
                    });
                }

                payload.Add(model);
            }

            // Publish all nodes.
            foreach (var request in payload)
            {
                await FluentActions
                .Invoking(async() => await orchestrator.PublishNodesAsync(request).ConfigureAwait(false))
                .Should()
                .NotThrowAsync()
                .ConfigureAwait(false);
            }

            async Task CheckEndpointsAndNodes(
                int expectedNumberOfEndpoints,
                int expectedNumberOfNodes
                )
            {
                var tasks = new List <Task <JobProcessingInstructionModel> >();

                for (var i = 0; i < expectedNumberOfEndpoints + 1; i++)
                {
                    tasks.Add(orchestrator.GetAvailableJobAsync(i.ToString(), new JobRequestModel()));
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                tasks.Count(t => t.Result != null)
                .Should()
                .Be(expectedNumberOfEndpoints);

                var distinctConfigurations = tasks
                                             .Where(t => t.Result != null)
                                             .Select(t => t.Result.Job.JobConfiguration)
                                             .Distinct();

                distinctConfigurations.Count()
                .Should()
                .Be(expectedNumberOfEndpoints);

                var writerGroups = tasks
                                   .Where(t => t.Result != null)
                                   .Select(t => jobSerializer.DeserializeJobConfiguration(
                                               t.Result.Job.JobConfiguration, t.Result.Job.JobConfigurationType) as WriterGroupJobModel);

                writerGroups.Select(
                    jobModel => jobModel.WriterGroup.DataSetWriters
                    .Select(writer => writer.DataSet.DataSetSource.PublishedVariables.PublishedData.Count())
                    .Sum()
                    ).Count(v => v == expectedNumberOfNodes)
                .Should()
                .Be(expectedNumberOfEndpoints);
            }

            // Check
            await CheckEndpointsAndNodes(numberOfEndpoints, numberOfNodes).ConfigureAwait(false);

            // Publish one more node for each endpoint.
            var payloadDiff = new List <PublishedNodesEntryModel>();

            for (int endpointIndex = 0; endpointIndex < numberOfEndpoints; ++endpointIndex)
            {
                var model = new PublishedNodesEntryModel {
                    EndpointUrl = new Uri($"opc.tcp://server{endpointIndex}:49580"),
                    OpcNodes    = new List <OpcNodeModel> {
                        new OpcNodeModel {
                            Id = $"ns=2;s=Node-Server-{numberOfNodes}",
                        }
                    }
                };

                payloadDiff.Add(model);
            }

            foreach (var request in payloadDiff)
            {
                await FluentActions
                .Invoking(async() => await orchestrator.PublishNodesAsync(request).ConfigureAwait(false))
                .Should()
                .NotThrowAsync()
                .ConfigureAwait(false);
            }

            // Check
            await CheckEndpointsAndNodes(numberOfEndpoints, numberOfNodes + 1).ConfigureAwait(false);

            // Unpublish new nodes for each endpoint.
            foreach (var request in payloadDiff)
            {
                await FluentActions
                .Invoking(async() => await orchestrator.UnpublishNodesAsync(request).ConfigureAwait(false))
                .Should()
                .NotThrowAsync()
                .ConfigureAwait(false);
            }

            // Check
            await CheckEndpointsAndNodes(numberOfEndpoints, numberOfNodes).ConfigureAwait(false);
        }
Ejemplo n.º 2
0
        public async Task DmApiPublishNodesToJobTest(string publishedNodesFile)
        {
            var standaloneCliModelProviderMock = new Mock <IStandaloneCliModelProvider>();
            var agentConfigProviderMock        = new Mock <IAgentConfigProvider>();
            var identityMock             = new Mock <IIdentity>();
            var newtonSoftJsonSerializer = new NewtonSoftJsonSerializer();
            var jobSerializer            = new PublisherJobSerializer(newtonSoftJsonSerializer);
            var logger            = TraceLogger.Create();
            var engineConfigMock  = new Mock <IEngineConfiguration>();
            var clientConfignMock = new Mock <IClientServicesConfig>();

            var publishedNodesJobConverter = new PublishedNodesJobConverter(logger, newtonSoftJsonSerializer,
                                                                            engineConfigMock.Object, clientConfignMock.Object);

            Utils.CopyContent("Engine/empty_pn.json", _tempFile);
            var standaloneCli = new StandaloneCliModel {
                PublishedNodesFile       = _tempFile,
                PublishedNodesSchemaFile = "Storage/publishednodesschema.json"
            };

            standaloneCliModelProviderMock.Setup(p => p.StandaloneCliModel).Returns(standaloneCli);
            agentConfigProviderMock.Setup(p => p.Config).Returns(new AgentConfigModel());

            var publishedNodesProvider = new PublishedNodesProvider(standaloneCliModelProviderMock.Object, logger);

            var orchestrator = new StandaloneJobOrchestrator(
                publishedNodesJobConverter,
                standaloneCliModelProviderMock.Object,
                agentConfigProviderMock.Object,
                jobSerializer,
                logger,
                publishedNodesProvider,
                newtonSoftJsonSerializer
                );

            var methodsController = new PublisherMethodsController(orchestrator);

            using var publishPayloads = new StreamReader(publishedNodesFile);
            var publishNodesRequests = newtonSoftJsonSerializer.Deserialize <List <PublishNodesEndpointApiModel> >
                                           (await publishPayloads.ReadToEndAsync().ConfigureAwait(false));

            foreach (var request in publishNodesRequests)
            {
                await FluentActions
                .Invoking(async() => await methodsController
                          .PublishNodesAsync(request).ConfigureAwait(false))
                .Should()
                .NotThrowAsync()
                .ConfigureAwait(false);
            }

            var tasks = new List <Task <JobProcessingInstructionModel> >();

            for (var i = 0; i < 10; i++)
            {
                tasks.Add(orchestrator.GetAvailableJobAsync(i.ToString(), new JobRequestModel()));
            }

            var job = tasks.Where(t => t.Result != null)
                      .Select(t => t.Result.Job)
                      .Distinct();

            job.Count()
            .Should()
            .Be(2);

            var jobModel = jobSerializer.DeserializeJobConfiguration(
                job.First().JobConfiguration, job.First().JobConfigurationType) as WriterGroupJobModel;

            jobModel.WriterGroup.DataSetWriters.Count.Should().Be(4);
            foreach (var datasetWriter in jobModel.WriterGroup.DataSetWriters)
            {
                datasetWriter.DataSet.DataSetSource.Connection.Endpoint.Url
                .Should()
                .Be(publishNodesRequests.First().EndpointUrl);
                datasetWriter.DataSet.DataSetSource.Connection.Endpoint.SecurityMode
                .Should()
                .Be(publishNodesRequests.First().UseSecurity ? SecurityMode.Best : SecurityMode.None);

                datasetWriter.DataSet.DataSetSource.Connection.User.
                IsSameAs(new CredentialModel {
                    Type = publishNodesRequests.First().OpcAuthenticationMode == AuthenticationMode.Anonymous ?
                           CredentialType.None :
                           CredentialType.UserName,
                    Value = newtonSoftJsonSerializer.FromObject(
                        new {
                        user     = publishNodesRequests.First().UserName,
                        password = publishNodesRequests.First().Password,
                    })
                })
                .Should()
                .BeTrue();
            }
        }