Ejemplo n.º 1
0
            public Server(TestKitBase testkit, EndPoint address = null)
            {
                _testkit = testkit;
                Address  = address ?? TestUtils.TemporaryServerAddress();

                ServerProbe = testkit.CreateTestProbe();
                ServerRef   = testkit.ActorOf(TestServerProps(Address, ServerProbe.Ref));
                ServerProbe.ExpectMsg <Tcp.Bound>();
            }
Ejemplo n.º 2
0
 public ServerConnection WaitAccept() => new ServerConnection(_testkit, ServerProbe.ExpectMsg <IActorRef>());
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public async Task <IPublisherClient> ConnectAsync()
        {
            const string kPublisherName = "opcpublisher";
            const int    kPublisherPort = 62222;

            _logger.Information("Finding publisher to use as publish service...");

            var deviceId = _identity.DeviceId;

            if (string.IsNullOrEmpty(deviceId))
            {
                // No identity at this point - look up from IoT Edge environment
                deviceId = Environment.GetEnvironmentVariable("IOTEDGE_DEVICEID");
            }
            if (!string.IsNullOrEmpty(deviceId))
            {
                _logger.Debug("Get all modules in current edge context.");
                // Get modules
                var modules = await _modules.GetModulesAsync(deviceId);

                var publisherModule = modules
                                      .Where(m => m.Status.EqualsIgnoreCase("running"))
                                      .FirstOrDefault(m =>
                                                      m.ImageName?.Contains("opc-publisher") ?? (false ||
                                                                                                 m.Id.EqualsIgnoreCase(kPublisherName)));

                if (publisherModule == null)
                {
                    _logger.Warning("No publisher module running in edge context.");
                }

                // Have publisher module
                var moduleId = publisherModule?.Id ?? kPublisherName;
                _logger.Information("Testing publisher module {moduleId} using methods...",
                                    moduleId);
                var publisher = new PublisherMethodClient(_methods, deviceId, moduleId, _logger);
                var error     = await TestConnectivityAsync(publisher);

                if (error == null)
                {
                    _logger.Information(
                        "Success - using publisher module '{moduleId}' ({image}) via methods.",
                        moduleId, publisherModule?.ImageName ?? "<unknown>");
                    return(publisher);
                }
                _logger.Debug("Publisher module {moduleId} method call uncuccessful." +
                              " Fallback to UA server...", moduleId, error);
            }

            using (var cts = new CancellationTokenSource()) {
                // Try shortcut of finding it on default publisher edge module
                var edgeUri       = new Uri($"opc.tcp://{kPublisherName}:{kPublisherPort}");
                var edgeEndpoints = await _discovery.FindEndpointsAsync(edgeUri, null, cts.Token);

                if (edgeEndpoints.Any())
                {
#if !TEST_PNP_SCAN
                    var publisher = new PublisherServerClient(_client, edgeUri, _logger);
                    var error     = await TestConnectivityAsync(publisher);

                    if (error == null)
                    {
                        _logger.Information("Using publisher server on localhost.");
                        return(publisher);
                    }
#endif
                }

                // Try shortcut of finding it on localhost
                var uri            = new Uri($"opc.tcp://{Utils.GetHostName()}:{kPublisherPort}");
                var localEndpoints = await _discovery.FindEndpointsAsync(uri, null, cts.Token);

                if (localEndpoints.Any())
                {
#if !TEST_PNP_SCAN
                    var publisher = new PublisherServerClient(_client, uri, _logger);
                    var error     = await TestConnectivityAsync(publisher);

                    if (error == null)
                    {
                        _logger.Information("Using publisher server on localhost.");
                        return(publisher);
                    }
#endif
                }

                // Discover publishers in network - use fast scanning
                _logger.Information("Try finding publishers in module network...");
                var addresses = new List <IPAddress>();
                using (var netscanner = new NetworkScanner(_logger,
                                                           (_, reply) => addresses.Add(reply.Address), false,
                                                           NetworkInformationEx.GetAllNetInterfaces(NetworkClass.Wired)
                                                           .Select(t => new AddressRange(t, false, 24)),
                                                           NetworkClass.Wired, 1000, // TODO: make configurable - intent is fast.
                                                           null, cts.Token)) {
                    await netscanner.Completion;
                }
                var publishers = new List <IPEndPoint>();
                var probe      = new ServerProbe(_logger);
                using (var portscan = new PortScanner(_logger,
                                                      addresses.Select(a => new IPEndPoint(a, kPublisherPort)),
                                                      (_, found) => {
                    cts.Cancel();     // Cancel on first found publisher.
                    publishers.Add(found);
                }, probe, null, null, null, cts.Token)) {
                    try {
                        await portscan.Completion;
                    }
                    catch (TaskCanceledException) {
                        // We got a port, and scanning is cancelled.
                    }
                }

                // We might have found a couple publishers - lets test them...
                foreach (var ep in publishers)
                {
                    var remoteEp = await ep.TryResolveAsync();

                    _logger.Information("Test publisher at address {remoteEp} in network.",
                                        remoteEp);
                    uri = new Uri("opc.tcp://" + remoteEp);
                    var endpoints = await _discovery.FindEndpointsAsync(uri, null,
                                                                        CancellationToken.None);

                    if (!endpoints.Any())
                    {
                        continue;
                    }
                    var publisher = new PublisherServerClient(_client, uri, _logger);
                    var error     = await TestConnectivityAsync(publisher);

                    if (error == null)
                    {
                        _logger.Information("Using publisher server at address {remoteEp}.",
                                            remoteEp);
                        return(publisher);
                    }
                }

                // TODO: Consider loading publisher as side car service?
                // No publisher found - will try again later.
                return(null);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Run a network discovery
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private async Task <List <ApplicationRegistrationModel> > DiscoverServersAsync(
            DiscoveryRequest request)
        {
            var discoveryUrls = await GetDiscoveryUrlsAsync(request.DiscoveryUrls);

            if (request.Mode == DiscoveryMode.Off)
            {
                return(await DiscoverServersAsync(request, discoveryUrls,
                                                  request.Configuration.Locales));
            }

            _logger.Information("Start {mode} discovery run...", request.Mode);
            var watch = Stopwatch.StartNew();

            //
            // Set up scanner pipeline and start discovery
            //
            var local = request.Mode == DiscoveryMode.Local;

#if !NO_WATCHDOG
            _counter = 0;
#endif
            var addresses = new List <IPAddress>();
            _progress.OnNetScanStarted(request.Request, 0, 0, request.TotalAddresses);
            using (var netscanner = new NetworkScanner(_logger, (scanner, reply) => {
                _progress.OnNetScanResult(request.Request, scanner.ActiveProbes,
                                          scanner.ScanCount, request.TotalAddresses, addresses.Count, reply.Address);
                addresses.Add(reply.Address);
            }, local, local ? null : request.AddressRanges, request.NetworkClass,
                                                       request.Configuration.MaxNetworkProbes, request.Configuration.NetworkProbeTimeout,
                                                       request.Token)) {
                // Log progress
                using (var progress = new Timer(_ => ProgressTimer(
                                                    () => _progress.OnNetScanProgress(request.Request, netscanner.ActiveProbes,
                                                                                      netscanner.ScanCount, request.TotalAddresses, addresses.Count)),
                                                null, kProgressInterval, kProgressInterval)) {
                    await netscanner.Completion;
                }
                _progress.OnNetScanFinished(request.Request, netscanner.ActiveProbes,
                                            netscanner.ScanCount, request.TotalAddresses, addresses.Count);
            }
            request.Token.ThrowIfCancellationRequested();

            await AddLoopbackAddressesAsync(addresses);

            if (addresses.Count == 0)
            {
                return(new List <ApplicationRegistrationModel>());
            }

            var ports      = new List <IPEndPoint>();
            var totalPorts = request.TotalPorts * addresses.Count;
            var probe      = new ServerProbe(_logger);
#if !NO_WATCHDOG
            _counter = 0;
#endif
            _progress.OnPortScanStart(request.Request, 0, 0, totalPorts);
            using (var portscan = new PortScanner(_logger,
                                                  addresses.SelectMany(address => {
                var ranges = request.PortRanges ?? PortRange.OpcUa;
                return(ranges.SelectMany(x => x.GetEndpoints(address)));
            }), (scanner, ep) => {
                _progress.OnPortScanResult(request.Request, scanner.ActiveProbes,
                                           scanner.ScanCount, totalPorts, ports.Count, ep);
                ports.Add(ep);
            }, probe, request.Configuration.MaxPortProbes,
                                                  request.Configuration.MinPortProbesPercent,
                                                  request.Configuration.PortProbeTimeout, request.Token)) {
                using (var progress = new Timer(_ => ProgressTimer(
                                                    () => _progress.OnPortScanProgress(request.Request, portscan.ActiveProbes,
                                                                                       portscan.ScanCount, totalPorts, ports.Count)),
                                                null, kProgressInterval, kProgressInterval)) {
                    await portscan.Completion;
                }
                _progress.OnPortScanFinished(request.Request, portscan.ActiveProbes,
                                             portscan.ScanCount, totalPorts, ports.Count);
            }
            request.Token.ThrowIfCancellationRequested();
            if (ports.Count == 0)
            {
                return(new List <ApplicationRegistrationModel>());
            }

            //
            // Collect discovery urls
            //
            foreach (var ep in ports)
            {
                request.Token.ThrowIfCancellationRequested();
                var resolved = await ep.TryResolveAsync();

                var url = new Uri($"opc.tcp://" + resolved);
                discoveryUrls.Add(ep, url);
            }
            request.Token.ThrowIfCancellationRequested();

            //
            // Create application model list from discovered endpoints...
            //
            var discovered = await DiscoverServersAsync(request, discoveryUrls,
                                                        request.Configuration.Locales);

            _logger.Information("Discovery took {elapsed} and found {count} servers.",
                                watch.Elapsed, discovered.Count);
            return(discovered);
        }