Ejemplo n.º 1
0
        public async Task <Try <ICloudConnection> > Connect(IClientCredentials clientCredentials, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(clientCredentials, nameof(clientCredentials));

            try
            {
                Events.CreatingCloudConnectionUsingClientCredentials(clientCredentials);
                var cloudListener = new CloudListener(this.edgeHub.Expect(() => new InvalidOperationException("EdgeHub reference should not be null")), clientCredentials.Identity.Id);
                ConnectionMetadata connectionMetadata = await this.metadataStore.GetMetadata(clientCredentials.Identity.Id);

                string          productInfo = connectionMetadata.EdgeProductInfo;
                Option <string> modelId     = connectionMetadata.ModelId;
                if (this.edgeHubIdentity.Id.Equals(clientCredentials.Identity.Id))
                {
                    ICloudConnection cc = await CloudConnection.Create(
                        clientCredentials.Identity,
                        connectionStatusChangedHandler,
                        this.transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.edgeHubTokenProvider,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);

                    Events.SuccessCreatingCloudConnection(clientCredentials.Identity);
                    return(Try.Success(cc));
                }
                else if (clientCredentials is ITokenCredentials clientTokenCredentails)
                {
                    ICloudConnection cc = await ClientTokenCloudConnection.Create(
                        clientTokenCredentails,
                        connectionStatusChangedHandler,
                        this.transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);

                    Events.SuccessCreatingCloudConnection(clientCredentials.Identity);
                    return(Try.Success(cc));
                }
                else
                {
                    throw new InvalidOperationException($"Cannot connect using client credentials of type {clientCredentials.AuthenticationType} for identity {clientCredentials.Identity.Id}");
                }
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(clientCredentials.Identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }
Ejemplo n.º 2
0
        public static async Task <CloudConnection> Create(
            IIdentity identity,
            Action <string, CloudConnectionStatus> connectionStatusChangedHandler,
            ITransportSettings[] transportSettings,
            IMessageConverterProvider messageConverterProvider,
            IClientProvider clientProvider,
            ICloudListener cloudListener,
            ITokenProvider tokenProvider,
            TimeSpan idleTimeout,
            bool closeOnIdleTimeout,
            TimeSpan operationTimeout,
            string productInfo,
            Option <string> modelId)
        {
            Preconditions.CheckNotNull(tokenProvider, nameof(tokenProvider));
            var cloudConnection = new CloudConnection(
                identity,
                connectionStatusChangedHandler,
                transportSettings,
                messageConverterProvider,
                clientProvider,
                cloudListener,
                idleTimeout,
                closeOnIdleTimeout,
                operationTimeout,
                productInfo,
                modelId);
            ICloudProxy cloudProxy = await cloudConnection.CreateNewCloudProxyAsync(tokenProvider);

            cloudConnection.cloudProxy = Option.Some(cloudProxy);
            return(cloudConnection);
        }
Ejemplo n.º 3
0
        public async Task <Try <ICloudConnection> > Connect(IClientCredentials identity, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(identity, nameof(identity));

            try
            {
                var cloudListener   = new CloudListener(this.edgeHub.Expect(() => new InvalidOperationException("EdgeHub reference should not be null")), identity.Identity.Id);
                var cloudConnection = new CloudConnection(
                    connectionStatusChangedHandler,
                    this.transportSettings,
                    this.messageConverterProvider,
                    this.clientProvider,
                    cloudListener,
                    this.edgeHubTokenProvider,
                    this.deviceScopeIdentitiesCache,
                    this.idleTimeout,
                    this.closeOnIdleTimeout);

                await cloudConnection.CreateOrUpdateAsync(identity);

                Events.SuccessCreatingCloudConnection(identity.Identity);
                return(Try.Success <ICloudConnection>(cloudConnection));
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(identity.Identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }
Ejemplo n.º 4
0
        public async Task <Try <ICloudConnection> > Connect(IIdentity identity, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(identity, nameof(identity));

            try
            {
                var cloudListener = new CloudListener(this.edgeHub.Expect(() => new InvalidOperationException("EdgeHub reference should not be null")), identity.Id);
                Option <ServiceIdentity> serviceIdentity = (await this.deviceScopeIdentitiesCache.GetServiceIdentity(identity.Id))
                                                           .Filter(s => s.Status == ServiceIdentityStatus.Enabled);
                return(await serviceIdentity
                       .Map(
                           async si =>
                {
                    Events.CreatingCloudConnectionOnBehalfOf(identity);
                    ConnectionMetadata connectionMetadata = await this.metadataStore.GetMetadata(identity.Id);
                    string productInfo = connectionMetadata.EdgeProductInfo;
                    Option <string> modelId = connectionMetadata.ModelId;
                    ICloudConnection cc = await CloudConnection.Create(
                        identity,
                        connectionStatusChangedHandler,
                        this.transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.edgeHubTokenProvider,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);
                    Events.SuccessCreatingCloudConnection(identity);
                    return Try.Success(cc);
                })
                       .GetOrElse(
                           async() =>
                {
                    Events.ServiceIdentityNotFound(identity);
                    Option <IClientCredentials> clientCredentials = await this.credentialsCache.Get(identity);
                    return await clientCredentials
                    .Map(cc => this.Connect(cc, connectionStatusChangedHandler))
                    .GetOrElse(() => throw new InvalidOperationException($"Unable to find identity {identity.Id} in device scopes cache or credentials cache"));
                }));
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }
Ejemplo n.º 5
0
        public async Task <Try <ICloudConnection> > Connect(IClientCredentials identity, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(identity, nameof(identity));

            try
            {
                var cloudConnection = new CloudConnection(connectionStatusChangedHandler, this.transportSettings, this.messageConverterProvider, this.clientProvider);
                await cloudConnection.CreateOrUpdateAsync(identity);

                Events.SuccessCreatingCloudConnection(identity.Identity);
                return(Try.Success <ICloudConnection>(cloudConnection));
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(identity.Identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }
Ejemplo n.º 6
0
        async Task <Try <ICloudConnection> > TryCreateCloudConnectionFromServiceIdentity(IIdentity identity, Action <string, CloudConnectionStatus> connectionStatusChangedHandler, bool refreshOutOfDateCache, CloudListener cloudListener, string authChain)
        {
            Events.CreatingCloudConnectionOnBehalfOf(identity);
            ConnectionMetadata connectionMetadata = await this.metadataStore.GetMetadata(identity.Id);

            string          productInfo = connectionMetadata.EdgeProductInfo;
            Option <string> modelId     = connectionMetadata.ModelId;

            ITransportSettings[] transportSettings = GetTransportSettings(
                this.upstreamProtocol,
                this.connectionPoolSize,
                this.proxy,
                this.useServerHeartbeat,
                authChain);

            try
            {
                ICloudConnection cc = await CloudConnection.Create(
                    identity,
                    connectionStatusChangedHandler,
                    transportSettings,
                    this.messageConverterProvider,
                    this.clientProvider,
                    cloudListener,
                    this.edgeHubTokenProvider,
                    this.idleTimeout,
                    this.closeOnIdleTimeout,
                    this.operationTimeout,
                    productInfo,
                    modelId);

                Events.SuccessCreatingCloudConnection(identity);
                return(Try.Success(cc));
            }
            catch (UnauthorizedException ex) when(this.trackDeviceState)
            {
                return(await this.TryRecoverCloudConnection(identity, connectionStatusChangedHandler, refreshOutOfDateCache, ex));
            }
        }
Ejemplo n.º 7
0
        public async Task <Try <ICloudConnection> > Connect(IClientCredentials clientCredentials, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(clientCredentials, nameof(clientCredentials));

            try
            {
                Events.CreatingCloudConnectionUsingClientCredentials(clientCredentials);
                var cloudListener = new CloudListener(this.edgeHub.Expect(() => new InvalidOperationException("EdgeHub reference should not be null")), clientCredentials.Identity.Id);
                ConnectionMetadata connectionMetadata = await this.metadataStore.GetMetadata(clientCredentials.Identity.Id);

                string          productInfo = connectionMetadata.EdgeProductInfo;
                Option <string> modelId     = clientCredentials.ModelId.HasValue ? clientCredentials.ModelId : connectionMetadata.ModelId;
                string          authChain   = string.Empty;
                if (this.nestedEdgeEnabled)
                {
                    Option <string> authChainMaybe = await this.deviceScopeIdentitiesCache.GetAuthChain(clientCredentials.Identity.Id);

                    // It's possible to have no auth-chain for out-of-scope leaf devices connecting through
                    // us as a gateway. In this case we let the upstream connection happen anyways, as any
                    // unauthorized attempt here would be denied by IoTHub.
                    authChain = authChainMaybe.OrDefault();
                }

                // Get the transport settings
                ITransportSettings[] transportSettings = GetTransportSettings(
                    this.upstreamProtocol,
                    this.connectionPoolSize,
                    this.proxy,
                    this.useServerHeartbeat,
                    authChain);

                if (this.edgeHubIdentity.Id.Equals(clientCredentials.Identity.Id))
                {
                    ICloudConnection cc = await CloudConnection.Create(
                        clientCredentials.Identity,
                        connectionStatusChangedHandler,
                        transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.edgeHubTokenProvider,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);

                    Events.SuccessCreatingCloudConnection(clientCredentials.Identity);
                    return(Try.Success(cc));
                }
                else if (clientCredentials is ITokenCredentials clientTokenCredentails)
                {
                    ICloudConnection cc = await ClientTokenCloudConnection.Create(
                        clientTokenCredentails,
                        connectionStatusChangedHandler,
                        transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);

                    Events.SuccessCreatingCloudConnection(clientCredentials.Identity);
                    return(Try.Success(cc));
                }
                else
                {
                    throw new InvalidOperationException($"Cannot connect using client credentials of type {clientCredentials.AuthenticationType} for identity {clientCredentials.Identity.Id}");
                }
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(clientCredentials.Identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }
Ejemplo n.º 8
0
        async Task <Try <ICloudConnection> > ConnectInternal(IIdentity identity, Action <string, CloudConnectionStatus> connectionStatusChangedHandler)
        {
            Preconditions.CheckNotNull(identity, nameof(identity));

            try
            {
                var cloudListener = new CloudListener(this.edgeHub.Expect(() => new InvalidOperationException("EdgeHub reference should not be null")), identity.Id);
                Option <ServiceIdentity> serviceIdentity = (await this.deviceScopeIdentitiesCache.GetServiceIdentity(identity.Id))
                                                           .Filter(s => s.Status == ServiceIdentityStatus.Enabled);

                string authChain = string.Empty;
                if (this.nestedEdgeEnabled)
                {
                    Option <string> authChainMaybe = await this.deviceScopeIdentitiesCache.GetAuthChain(identity.Id);

                    authChain = authChainMaybe.Expect(() => new InvalidOperationException($"No auth chain for the client identity: {identity.Id}"));
                }

                ITransportSettings[] transportSettings = GetTransportSettings(
                    this.upstreamProtocol,
                    this.connectionPoolSize,
                    this.proxy,
                    this.useServerHeartbeat,
                    authChain);

                return(await serviceIdentity
                       .Map(
                           async si =>
                {
                    Events.CreatingCloudConnectionOnBehalfOf(identity);
                    ConnectionMetadata connectionMetadata = await this.metadataStore.GetMetadata(identity.Id);
                    string productInfo = connectionMetadata.EdgeProductInfo;
                    Option <string> modelId = connectionMetadata.ModelId;
                    ICloudConnection cc = await CloudConnection.Create(
                        identity,
                        connectionStatusChangedHandler,
                        transportSettings,
                        this.messageConverterProvider,
                        this.clientProvider,
                        cloudListener,
                        this.edgeHubTokenProvider,
                        this.idleTimeout,
                        this.closeOnIdleTimeout,
                        this.operationTimeout,
                        productInfo,
                        modelId);
                    Events.SuccessCreatingCloudConnection(identity);
                    return Try.Success(cc);
                })
                       .GetOrElse(
                           async() =>
                {
                    // allow to use credential cache when auth mode is not Scope only (could be CloudAndScope or Cloud) or identity is for edgeHub
                    if (!this.scopeAuthenticationOnly || this.edgeHubIdentity.Id.Equals(identity.Id))
                    {
                        Events.ServiceIdentityNotFound(identity);
                        Option <IClientCredentials> clientCredentials = await this.credentialsCache.Get(identity);
                        var clientCredential = clientCredentials.Expect(() => new InvalidOperationException($"Unable to find identity {identity.Id} in device scopes cache or credentials cache"));
                        return await this.Connect(clientCredential, connectionStatusChangedHandler);
                    }
                    else
                    {
                        throw new InvalidOperationException($"Unable to find identity {identity.Id} in device scopes cache");
                    }
                }));
            }
            catch (Exception ex)
            {
                Events.ErrorCreatingCloudConnection(identity, ex);
                return(Try <ICloudConnection> .Failure(ex));
            }
        }