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>(); }
public ServerConnection WaitAccept() => new ServerConnection(_testkit, ServerProbe.ExpectMsg <IActorRef>());
/// <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); } }
/// <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); }