/// <inheritdoc/>
 public Task ConfigureAsync(DiscoveryMode mode, DiscoveryConfigModel config)
 {
     _request = new DiscoveryRequest(mode, config);
     return(Task.CompletedTask);
 }
Пример #2
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);
        }
Пример #3
0
        public DiscoveryResponse Discovery(DiscoveryRequest alexaRequest)
        {
            //IPremiseObject PremiseServer.HomeObject, rootObject;
            var response = new DiscoveryResponse();

            #region CheckRequest

            if ((alexaRequest == null) || (alexaRequest.header == null) || (alexaRequest.header.payloadVersion == null) || (alexaRequest.header.payloadVersion == "1"))
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.UnexpectedInformationReceivedError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    faultingParameter = "alexaRequest"
                };
                return(response);
            }

            if (alexaRequest.header.name != "DiscoverAppliancesRequest")
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.UnsupportedOperationError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    faultingParameter = "alexaRequest.header.name"
                };
                return(response);
            }

            #endregion CheckRequest

            #region InitialzeResponse

            try
            {
                if (response.header.payloadVersion == "3")
                {
                    response.header.name = alexaRequest.header.name + ".Response";
                }
                else
                {
                    response.header.name = alexaRequest.header.name.Replace("Request", "Response");
                }
                response.header.messageId  = alexaRequest.header.messageId;
                response.header.@namespace = alexaRequest.header.@namespace;
            }
            catch (Exception)
            {
                response.header.@namespace = Faults.QueryNamespace;
                response.header.name       = Faults.UnexpectedInformationReceivedError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    faultingParameter = "alexaRequest.header.name"
                };
                return(response);
            }

            #endregion InitialzeResponse

            if (alexaRequest.header.name != "DiscoverAppliancesRequest")
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.UnsupportedOperationError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    faultingParameter = "alexaRequest.header.name"
                };
                return(response);
            }

            //SYSClient client = new SYSClient();

            #region ConnectToPremise

            if (PremiseServer.HomeObject == null)
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.DependentServiceUnavailableError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    dependentServiceName = "Premise Server"
                };
                return(response);
            }

            #endregion ConnectToPremise

            try
            {
                #region VerifyAccess

                if (!CheckAccessToken(alexaRequest.payload.accessToken).GetAwaiter().GetResult())
                {
                    response.header.@namespace = Faults.Namespace;
                    response.header.name       = Faults.InvalidAccessTokenError;
                    return(response);
                }

                #endregion VerifyAccess

                #region Perform Discovery

                InformLastContact(alexaRequest.header.name).GetAwaiter().GetResult();

                response.payload.discoveredAppliances = GetAppliances().GetAwaiter().GetResult();
                response.payload.discoveredAppliances.Sort(Appliance.CompareByFriendlyName);

                #endregion Perform Discovery
            }
            catch (Exception ex)
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.DriverpublicError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    errorInfo = new ErrorInfo
                    {
                        description = ex.Message
                    }
                };
            }

            return(response);
        }
        public Watch CreateWatch(
            bool ads,
            DiscoveryRequest request,
            ISet <string>?knownResourceNames,
            Action <Response> responseCallback)
        {
            var group = _hash(request.Node);

            // even though we're modifying, we take a readLock to allow multiple watches to be created in parallel since it
            // doesn't conflict
            _rwLock.EnterReadLock();
            try
            {
                var status = _statuses.GetOrAdd(group, g => new CacheStatusInfo <T>(group));

                status.SetLastWatchRequestTime(DateTimeOffset.UtcNow.Ticks);

                _snapshots.TryGetValue(group, out Snapshot? snapshot);
                var version = snapshot == null
                    ? string.Empty
                    : snapshot.GetVersion(request.TypeUrl, request.ResourceNames);

                var watch = new Watch(ads, request, responseCallback);

                if (snapshot != null)
                {
                    var requestedResources = ImmutableHashSet.CreateRange(request.ResourceNames);
                    var newResourceHints   = requestedResources.Except(knownResourceNames);

                    // If the request is asking for resources we haven't sent to the proxy yet, see if we have additional resources.
                    if (newResourceHints.Any())
                    {
                        // If any of the newly requested resources are in the snapshot respond immediately. If not we'll fall back to
                        // version comparisons.
                        if (snapshot.GetResources(request.TypeUrl).Keys.Any(newResourceHints.Contains))
                        {
                            this.Respond(watch, snapshot, group);
                            return(watch);
                        }
                    }
                }

                // If the requested version is up-to-date or missing a response, leave an open watch.
                if (snapshot == null || request.VersionInfo.Equals(version))
                {
                    long watchId = Interlocked.Increment(ref _watchCount);

                    Logger.LogDebug("open watch {0} for {1}[{2}] from node {3} for version {4}",
                                    watchId,
                                    request.TypeUrl,
                                    string.Join(", ", request.ResourceNames),
                                    group,
                                    request.VersionInfo);

                    status.SetWatch(watchId, watch);

                    watch.SetStop(() => status.RemoveWatch(watchId));

                    return(watch);
                }

                // Otherwise, the watch may be responded immediately
                var responded = this.Respond(watch, snapshot, group);

                if (!responded)
                {
                    long watchId = Interlocked.Increment(ref _watchCount);


                    Logger.LogDebug("did not respond immediately, leaving open watch {0} for {1}[{2}] from node {3} for version {4}",
                                    watchId,
                                    request.TypeUrl,
                                    string.Join(", ", request.ResourceNames),
                                    group,
                                    request.VersionInfo);

                    status.SetWatch(watchId, watch);
                    watch.SetStop(() => status.RemoveWatch(watchId));
                }

                return(watch);
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }
Пример #5
0
        private void OnHandleMessagesThread()
        {
            while (server.Status != NetPeerStatus.NotRunning)
            {
                server.MessageReceivedEvent.WaitOne();

                NetIncomingMessage msg;
                while (server.ReadMessage(out msg))
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.StatusChanged: {
                        NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
#if NETWORK_DEBUG
                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                        Console.Write("    S ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine("[" + msg.SenderEndPoint + "] " + status);
#endif
                        ClientStatusChangedEventArgs args = new ClientStatusChangedEventArgs(msg.SenderConnection, status);
                        ClientStatusChanged?.Invoke(args);
                        break;
                    }

                    case NetIncomingMessageType.Data: {
#if NETWORK_DEBUG__
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("    R ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine("[" + msg.SenderEndPoint + "] " + msg.LengthBytes + " bytes");
#endif

                        MessageReceivedEventArgs args = new MessageReceivedEventArgs(msg, false);
                        MessageReceived?.Invoke(args);

                        break;
                    }

                    case NetIncomingMessageType.UnconnectedData: {
#if NETWORK_DEBUG
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("    R ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine("Unconnected [" + msg.SenderEndPoint + "] " + msg.LengthBytes + " bytes");
#endif

                        MessageReceivedEventArgs args = new MessageReceivedEventArgs(msg, true);
                        MessageReceived?.Invoke(args);

                        break;
                    }

                    case NetIncomingMessageType.ConnectionApproval: {
                        ClientConnectedEventArgs args = new ClientConnectedEventArgs(msg);
                        ClientConnected?.Invoke(args);

                        if (args.DenyReason == null)
                        {
                            msg.SenderConnection.Approve();
                        }
                        else
                        {
                            msg.SenderConnection.Deny(args.DenyReason);
                        }
                        break;
                    }

                    case NetIncomingMessageType.DiscoveryRequest: {
#if NETWORK_DEBUG
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("    Q ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine("[" + msg.SenderEndPoint + "] " + msg.LengthBytes + " bytes");
#endif

                        DiscoveryRequestEventArgs args = new DiscoveryRequestEventArgs();
                        DiscoveryRequest?.Invoke(args);

                        server.SendDiscoveryResponse(args.Message, msg.SenderEndPoint);
                        break;
                    }

#if NETWORK_DEBUG
                    case NetIncomingMessageType.VerboseDebugMessage:
                        Console.ForegroundColor = ConsoleColor.DarkGray;
                        Console.Write("    D ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine(msg.ReadString());
                        break;

                    case NetIncomingMessageType.DebugMessage:
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write("    D ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine(msg.ReadString());
                        break;

                    case NetIncomingMessageType.WarningMessage:
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.Write("    W ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine(msg.ReadString());
                        break;

                    case NetIncomingMessageType.ErrorMessage:
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("    E ");
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine(msg.ReadString());
                        break;
#endif
                    }

                    server.Recycle(msg);
                }
            }

            server = null;

            Debug.WriteLine("ServerConnection: OnHandleMessagesThread exited!");
        }
Пример #6
0
 public Response(DiscoveryRequest request, IEnumerable <IMessage> resources, string version)
 {
     this.Request   = request;
     this.Resources = resources;
     this.Version   = version;
 }
Пример #7
0
 private static IEnumerable <PatientWithRank <Patient> > RanksFor(DiscoveryRequest request, Patient patient)
 {
Пример #8
0
 private void SetupMatchingRepositoryForDiscoveryRequest(DiscoveryRequest discoveryRequest)
 {
     SetupMatchingRepositoryForDiscoveryRequest(discoveryRequest, 1);
 }
Пример #9
0
 private static PatientWithRank <Patient> RankPatient(Patient patient, DiscoveryRequest request)
 {
     return(RanksFor(request, patient).Aggregate((rank, withRank) => rank + withRank));
 }
Пример #10
0
        public virtual async Task <ValueTuple <DiscoveryRepresentation, ErrorRepresentation> > PatientFor(
            DiscoveryRequest request)
        {
            if (await AlreadyExists(request.TransactionId))
            {
                logger.Log(LogLevel.Error, LogEvents.Discovery, "Discovery Request already exists for {request.TransactionId}.");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.DuplicateDiscoveryRequest, "Discovery Request already exists")));
            }

            var(linkedAccounts, exception) = await linkPatientRepository.GetLinkedCareContexts(request.Patient.Id);

            if (exception != null)
            {
                logger.Log(LogLevel.Critical, LogEvents.Discovery, exception, "Failed to get care contexts");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.FailedToGetLinkedCareContexts,
                                                         "Failed to get Linked Care Contexts")));
            }

            var linkedCareContexts = linkedAccounts.ToList();

            if (HasAny(linkedCareContexts))
            {
                logger.Log(LogLevel.Information,
                           LogEvents.Discovery,
                           "User has already linked care contexts: {TransactionID}",
                           request.TransactionId);
                var patient = await patientRepository.PatientWithAsync(linkedCareContexts.First().PatientReferenceNumber);

                return(await patient
                       .Map(async patient =>
                {
                    await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                                    request.Patient.Id, patient.Identifier));
                    return (new DiscoveryRepresentation(patient.ToPatientEnquiryRepresentation(
                                                            GetUnlinkedCareContexts(linkedCareContexts, patient))),
                            (ErrorRepresentation)null);
                })
                       .ValueOr(Task.FromResult(GetError(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound))));
            }
            IQueryable <Patient> patients;

            try {
                patients = await matchingRepository.Where(request);
            }
            catch (OpenMrsConnectionException)
            {
                return(GetError(ErrorCode.OpenMrsConnection, ErrorMessage.HipConnection));
            }

            try
            {
                foreach (var patient in patients)
                {
                    var careContexts = await careContextRepository.GetCareContexts(patient.Uuid);

                    patient.CareContexts = careContexts;
                }
            }
            catch (OpenMrsFormatException e)
            {
                logger.Log(LogLevel.Error,
                           LogEvents.Discovery, $"Could not get care contexts for transaction {request.TransactionId}.", e);
                return(GetError(ErrorCode.CareContextConfiguration, ErrorMessage.HipConfiguration));
            }

            var(patientEnquiryRepresentation, error) =
                DiscoveryUseCase.DiscoverPatient(Filter.Do(patients, request).AsQueryable());
            if (patientEnquiryRepresentation == null)
            {
                Log.Information($"No matching unique patient found for transaction {request.TransactionId}.", error);
                return(null, error);
            }

            await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                            request.Patient.Id, patientEnquiryRepresentation.ReferenceNumber));

            return(new DiscoveryRepresentation(patientEnquiryRepresentation), null);
        }
Пример #11
0
 public Task <DiscoveryResponse> ExecuteAsync(DiscoveryRequest request, CancellationToken cancellationToken = default(CancellationToken))
 => _service.ExecuteAsync(request, cancellationToken);
Пример #12
0
 public DiscoveryResponse Execute(DiscoveryRequest request)
 => _service.Execute(request);
 private static void AndTheResponseShouldContainTheTransactionId(GatewayDiscoveryRepresentation actualResponse,
                                                                 DiscoveryRequest discoveryRequest)
 {
     actualResponse.TransactionId.Should().Be(discoveryRequest.TransactionId);
 }