Ejemplo n.º 1
0
        /// <inheritdoc/>
        public async Task RegisterAsync(EndpointModel endpoint,
                                        Func <EndpointConnectivityState, Task> callback)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }
            var id = new EndpointIdentifier(endpoint);

            if (!_callbacks.TryAdd(id, callback))
            {
                _callbacks.AddOrUpdate(id, callback, (k, v) => callback);
            }

            await _lock.WaitAsync();

            try {
                // Add a persistent session
                if (!_clients.TryGetValue(id, out var _))
                {
                    _clients.Add(id, new ClientSession(
                                     _opcApplicationConfig, id.Endpoint.Clone(), _logger,
                                     NotifyStateChangeAsync, true, _maxOpTimeout));
                    _logger.Debug("Open session for endpoint {id} ({endpoint}).",
                                  id, endpoint.Url);
                }
            }
            finally {
                _lock.Release();
            }
        }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        public async Task UnregisterAsync(EndpointModel endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            var id = new EndpointIdentifier(endpoint);

            _callbacks.TryRemove(id, out _);

            await _lock.WaitAsync();

            try {
                // Remove any session
                if (_clients.TryGetValue(id, out var client))
                {
                    await Try.Async(client.CloseAsync);

                    Try.Op(client.Dispose);

                    _clients.Remove(id);
                    _logger.Debug("Endpoint {id} ({endpoint}) closed.",
                                  id, endpoint.Url);
                }
                else
                {
                    _logger.Debug(
                        "Session for endpoint {id} ({endpoint}) not found.",
                        endpoint.Url, id);
                }
            }
            finally {
                _lock.Release();
            }
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public async Task UnregisterAsync(EndpointModel endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            var id = new EndpointIdentifier(endpoint);

            _callbacks.TryRemove(id, out _);

            await _lock.WaitAsync();

            try {
                // Remove any session
                if (_clients.TryGetValue(id, out var client))
                {
                    await Try.Async(client.CloseAsync);

                    _clients.Remove(id);
                }
            }
            finally {
                _lock.Release();
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Create session
 /// </summary>
 /// <param name="id"></param>
 /// <param name="persistent"></param>
 /// <returns></returns>
 internal IClientSession GetOrCreateSession(EndpointIdentifier id, bool persistent)
 {
     return(_clients.GetOrAdd(id, k => new ClientSession(
                                  CreateApplicationConfiguration(TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2)),
                                  k.Endpoint, () => Certificate, _logger, NotifyStateChangeAsync, persistent,
                                  _maxOpTimeout)));
 }
Ejemplo n.º 5
0
        IDisposable SubscribeStream()
        {
            EndpointIdentifier senderIdentifier = _identifier == EndpointIdentifier.Client ?
                                                  EndpointIdentifier.Server :
                                                  EndpointIdentifier.Client;

            return(_stream
                   .Receive(senderIdentifier)
                   .ObserveOn(NewThreadScheduler.Default)
                   .Subscribe(packet =>
            {
                _tracer.Verbose(ClientProperties.MqttChannel_ReceivedPacket(packet.Length));

                _receiver.OnNext(packet);
            }, ex =>
            {
                if (ex is ObjectDisposedException)
                {
                    _receiver.OnError(new MqttException(ClientProperties.MqttChannel_StreamDisconnected, ex));
                }
                else
                {
                    _receiver.OnError(ex);
                }
            }, () =>
            {
                _tracer.Warn(ClientProperties.MqttChannel_NetworkStreamCompleted);
                _receiver.OnCompleted();
            }));
        }
Ejemplo n.º 6
0
            /// <summary>
            /// Run export cycles
            /// </summary>
            /// <param name="id"></param>
            /// <param name="diagnostics"></param>
            /// <param name="ct"></param>
            /// <returns></returns>
            private async Task UploadModelAsync(EndpointIdentifier id, DiagnosticsModel diagnostics,
                                                CancellationToken ct)
            {
                var fullPath = Path.Combine(Path.GetTempPath(), FileName);

                try {
                    _outer._logger.Information("Start model upload to {fileName} for {url}.",
                                               FileName, id.Endpoint.Url);
                    using (var file = new FileStream(fullPath, FileMode.Create))
                        using (var stream = new GZipStream(file, CompressionMode.Compress)) {
                            // TODO: Try read nodeset from namespace metadata!
                            // ...

                            // Otherwise browse model
                            await BrowseEncodeModelAsync(id.Endpoint, diagnostics, stream, ct);
                        }
                    // now upload file
                    await _outer._upload.SendFileAsync(fullPath, Encoding);

                    _outer._logger.Information("Model uploaded to {fileName} for {url}.",
                                               FileName, id.Endpoint.Url);
                }
                catch (OperationCanceledException) {
                    _outer._logger.Information("Cancelled model upload of {fileName} for {url}",
                                               FileName, id.Endpoint.Url);
                }
                catch (Exception ex) {
                    _outer._logger.Error(ex, "Error during exportto {fileName} for {url}.",
                                         FileName, id.Endpoint.Url);
                }
                finally {
                    File.Delete(fullPath);
                    _outer._tasks.TryRemove(id, out var tmp);
                }
            }
Ejemplo n.º 7
0
        /// <inheritdoc/>
        public Task <T> ExecuteServiceAsync <T>(EndpointModel endpoint,
                                                CredentialModel elevation, int priority, Func <Session, Task <T> > service,
                                                TimeSpan?timeout, CancellationToken ct, Func <Exception, bool> handler)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            if (string.IsNullOrEmpty(endpoint.Url))
            {
                throw new ArgumentNullException(nameof(endpoint.Url));
            }
            var key = new EndpointIdentifier(endpoint);

            while (!_cts.IsCancellationRequested)
            {
                var client = GetOrCreateSession(key);
                if (!client.Inactive)
                {
                    var scheduled = client.TryScheduleServiceCall(elevation, priority,
                                                                  service, handler, timeout, ct, out var result);
                    if (scheduled)
                    {
                        // Session is owning the task to completion now.
                        return(result);
                    }
                }
                // Create new session next go around
                EvictIfInactive(key);
            }
            return(Task.FromCanceled <T>(_cts.Token));
        }
Ejemplo n.º 8
0
 public void Send(byte[] payload, EndpointIdentifier identifier)
 {
     if (_disposed)
     {
         throw new ObjectDisposedException(nameof(PrivateStream));
     }
     _payloadSequence.OnNext(Tuple.Create(payload, identifier));
 }
Ejemplo n.º 9
0
 public PrivateChannel(PrivateStream stream, EndpointIdentifier identifier, MqttConfiguration configuration)
 {
     this.stream        = stream;
     this.identifier    = identifier;
     receiver           = new ReplaySubject <byte[]> (window: TimeSpan.FromSeconds(configuration.WaitTimeoutSecs));
     sender             = new ReplaySubject <byte[]> (window: TimeSpan.FromSeconds(configuration.WaitTimeoutSecs));
     streamSubscription = SubscribeStream();
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Notify about session/endpoint state changes
        /// </summary>
        /// <param name="ep"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private Task NotifyStateChangeAsync(EndpointModel ep, EndpointConnectivityState state)
        {
            var id = new EndpointIdentifier(ep);

            if (_callbacks.TryGetValue(id, out var cb))
            {
                return(cb(state));
            }
            return(Task.CompletedTask);
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Create model upload task
 /// </summary>
 /// <param name="outer"></param>
 /// <param name="id"></param>
 /// <param name="contentType"></param>
 /// <param name="diagnostics"></param>
 public ModelUploadTask(DataUploadServices outer, EndpointIdentifier id,
                        string contentType, DiagnosticsModel diagnostics)
 {
     Encoding  = ValidateEncoding(contentType, out var extension);
     StartTime = DateTime.UtcNow;
     FileName  = $"{id.GetHashCode()}_{StartTime.ToBinary()}{extension}";
     _outer    = outer;
     _cts      = new CancellationTokenSource();
     _job      = _outer._scheduler.Run(() => UploadModelAsync(id, diagnostics, _cts.Token));
 }
Ejemplo n.º 12
0
        public IObservable <byte[]> Receive(EndpointIdentifier identifier)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(PrivateStream));
            }

            return(_payloadSequence
                   .Where(t => t.Item2 == identifier)
                   .Select(t => t.Item1));
        }
Ejemplo n.º 13
0
        /// <inheritdoc/>
        public Task Unregister(EndpointModel endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }

            var id = new EndpointIdentifier(endpoint);

            _callbacks.TryRemove(id, out _);
            // Remove persistent session
            if (_clients.TryRemove(id, out var client))
            {
                return(Try.Async(client.CloseAsync));
            }
            return(Task.CompletedTask);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Handle inactive
 /// </summary>
 /// <param name="id"></param>
 /// <returns></returns>
 private void EvictIfInactive(EndpointIdentifier id)
 {
     _lock.Wait();
     try {
         if (_clients.TryGetValue(id, out var item))
         {
             if (item.Inactive && _clients.Remove(id))
             {
                 item.Dispose();
                 _logger.Debug("Evicted inactive session from session cache.");
             }
         }
     }
     finally {
         _lock.Release();
     }
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Create session
 /// </summary>
 /// <param name="id"></param>
 /// <returns></returns>
 private IClientSession GetOrCreateSession(EndpointIdentifier id)
 {
     _lock.Wait();
     try {
         if (!_clients.TryGetValue(id, out var session))
         {
             session = new ClientSession(
                 _opcApplicationConfig, id.Endpoint.Clone(), _logger,
                 NotifyStateChangeAsync, false, _maxOpTimeout);
             _clients.Add(id, session);
             _logger.Debug("Add new session to session cache.");
         }
         return(session);
     }
     finally {
         _lock.Release();
     }
 }
Ejemplo n.º 16
0
        /// <inheritdoc/>
        public Task Register(EndpointModel endpoint,
                             Func <EndpointConnectivityState, Task> callback)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            var id = new EndpointIdentifier(endpoint);

            if (!_callbacks.TryAdd(id, callback))
            {
                _callbacks.AddOrUpdate(id, callback, (k, v) => callback);
            }
            // Create persistent session
            GetOrCreateSession(id, true);
            return(Task.CompletedTask);
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RxHciMessage"/> class.
 /// </summary>
 /// <param name="endpointIdentifier">the identifier of the endpoint.</param>
 /// <param name="payload">the payload.</param>
 protected RxHciMessage(EndpointIdentifier endpointIdentifier, IList <byte> payload)
 {
     EndpointIdentifier = endpointIdentifier;
     Payload            = payload ?? throw new ArgumentNullException(nameof(payload));
 }
 public PrivateChannelFactory(ISubject <PrivateStream> privateStreamListener, EndpointIdentifier identifier, MqttConfiguration configuration)
 {
     this.privateStreamListener = privateStreamListener;
     this.identifier            = identifier;
     this.configuration         = configuration;
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TxHciMessage"/> class.
 /// </summary>
 /// <param name="identifier">Identifier for destination endpoint.</param>
 /// <param name="payload">payload to be sent.</param>
 protected TxHciMessage(EndpointIdentifier identifier, List <byte>?payload)
 {
     EndpointIdentifier = identifier;
     Payload            = payload;
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Creates an appropriate mail endpoint and forwards the SendMessageRequest to it
 /// for processing
 /// </summary>
 /// <returns></returns>
 public bool SendMail(SendMessageRequest message, EndpointIdentifier serviceIdentifier)
 {
     var mailEndpoint = _mailEndpointFactory.CreateEndpoint(serviceIdentifier);
     return mailEndpoint.SendMail(message);
 }
Ejemplo n.º 21
0
 public PrivateBinding(ISubject <PrivateStream> privateStreamListener, EndpointIdentifier identifier)
 {
     this.privateStreamListener = privateStreamListener;
     this.identifier            = identifier;
 }
Ejemplo n.º 22
0
 /// <summary>
 /// Creates an IMailEndpoint for the given EndpointIdentifier
 /// </summary>
 public IMailEndpoint CreateEndpoint(EndpointIdentifier endpointIdentifier)
 {
     return(_scope.ResolveNamed <IMailEndpoint>(endpointIdentifier.ToString()));
 }