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)); } }
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); }
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)); } }
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)); } }
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)); } }
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)); } }
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)); } }
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)); } }