public CloudConnectionProvider( IMessageConverterProvider messageConverterProvider, int connectionPoolSize, IClientProvider clientProvider, Option <UpstreamProtocol> upstreamProtocol, ITokenProvider edgeHubTokenProvider, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, ICredentialsCache credentialsCache, IIdentity edgeHubIdentity, TimeSpan idleTimeout, bool closeOnIdleTimeout, TimeSpan operationTimeout, bool useServerHeartbeat, Option <IWebProxy> proxy, IMetadataStore metadataStore, bool nestedEdgeEnabled = false) { this.messageConverterProvider = Preconditions.CheckNotNull(messageConverterProvider, nameof(messageConverterProvider)); this.clientProvider = Preconditions.CheckNotNull(clientProvider, nameof(clientProvider)); this.upstreamProtocol = upstreamProtocol; this.connectionPoolSize = Preconditions.CheckRange(connectionPoolSize, 1, nameof(connectionPoolSize)); this.proxy = proxy; this.edgeHub = Option.None <IEdgeHub>(); this.idleTimeout = idleTimeout; this.closeOnIdleTimeout = closeOnIdleTimeout; this.useServerHeartbeat = useServerHeartbeat; this.edgeHubTokenProvider = Preconditions.CheckNotNull(edgeHubTokenProvider, nameof(edgeHubTokenProvider)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.credentialsCache = Preconditions.CheckNotNull(credentialsCache, nameof(credentialsCache)); this.edgeHubIdentity = Preconditions.CheckNotNull(edgeHubIdentity, nameof(edgeHubIdentity)); this.operationTimeout = operationTimeout; this.metadataStore = Preconditions.CheckNotNull(metadataStore, nameof(metadataStore)); this.nestedEdgeEnabled = nestedEdgeEnabled; }
public static async Task <EdgeHubConnection> Create( IIdentity edgeHubIdentity, IEdgeHub edgeHub, ITwinManager twinManager, IConnectionManager connectionManager, RouteFactory routeFactory, IMessageConverter <TwinCollection> twinCollectionMessageConverter, VersionInfo versionInfo, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache) { Preconditions.CheckNotNull(edgeHubIdentity, nameof(edgeHubIdentity)); Preconditions.CheckNotNull(edgeHub, nameof(edgeHub)); Preconditions.CheckNotNull(connectionManager, nameof(connectionManager)); Preconditions.CheckNotNull(twinCollectionMessageConverter, nameof(twinCollectionMessageConverter)); Preconditions.CheckNotNull(routeFactory, nameof(routeFactory)); Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); var edgeHubConnection = new EdgeHubConnection( edgeHubIdentity, twinManager, routeFactory, twinCollectionMessageConverter, versionInfo ?? VersionInfo.Empty, deviceScopeIdentitiesCache); await InitEdgeHub(edgeHubConnection, connectionManager, edgeHubIdentity, edgeHub); connectionManager.DeviceConnected += edgeHubConnection.DeviceConnected; connectionManager.DeviceDisconnected += edgeHubConnection.DeviceDisconnected; Events.Initialized(edgeHubIdentity); return(edgeHubConnection); }
public CloudConnectionProvider( IMessageConverterProvider messageConverterProvider, int connectionPoolSize, IClientProvider clientProvider, Option <UpstreamProtocol> upstreamProtocol, ITokenProvider edgeHubTokenProvider, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, ICredentialsCache credentialsCache, IIdentity edgeHubIdentity, TimeSpan idleTimeout, bool closeOnIdleTimeout, TimeSpan operationTimeout, Option <IWebProxy> proxy, IProductInfoStore productInfoStore) { Preconditions.CheckRange(connectionPoolSize, 1, nameof(connectionPoolSize)); this.messageConverterProvider = Preconditions.CheckNotNull(messageConverterProvider, nameof(messageConverterProvider)); this.clientProvider = Preconditions.CheckNotNull(clientProvider, nameof(clientProvider)); this.transportSettings = GetTransportSettings(upstreamProtocol, connectionPoolSize, proxy); this.edgeHub = Option.None <IEdgeHub>(); this.idleTimeout = idleTimeout; this.closeOnIdleTimeout = closeOnIdleTimeout; this.edgeHubTokenProvider = Preconditions.CheckNotNull(edgeHubTokenProvider, nameof(edgeHubTokenProvider)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.credentialsCache = Preconditions.CheckNotNull(credentialsCache, nameof(credentialsCache)); this.edgeHubIdentity = Preconditions.CheckNotNull(edgeHubIdentity, nameof(edgeHubIdentity)); this.operationTimeout = operationTimeout; this.productInfoStore = Preconditions.CheckNotNull(productInfoStore, nameof(productInfoStore)); }
async Task <EdgeHubScopeResult> HandleDevicesAndModulesInTargetDeviceScopeAsync(string actorDeviceId, string actorModuleId, NestedScopeRequest request) { Events.ReceivedScopeRequest(actorDeviceId, actorModuleId, request); Preconditions.CheckNonWhiteSpace(request.AuthChain, nameof(request.AuthChain)); if (!this.TryGetTargetDeviceId(request.AuthChain, out string targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.BadRequest, Events.InvalidRequestAuthchain(request.AuthChain))); } // Check that the actor device is authorized to act OnBehalfOf the target IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); if (!await this.AuthorizeActorAsync(identitiesCache, actorDeviceId, actorModuleId, targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, Events.UnauthorizedActor(actorDeviceId, actorModuleId, targetDeviceId))); } // Get the children of the target device and the target device itself; IList <ServiceIdentity> identities = await identitiesCache.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId); Option <ServiceIdentity> targetDevice = await identitiesCache.GetServiceIdentity(targetDeviceId); targetDevice.ForEach(d => identities.Add(d)); // Construct the result from the identities Events.SendingScopeResult(targetDeviceId, identities); return(MakeResultFromIdentities(identities)); }
public async Task InitializeFromStoreTest() { // Arrange var iterator = new Mock <IServiceIdentitiesIterator>(); iterator.Setup(i => i.HasNext).Returns(true); iterator.Setup(i => i.GetNext()).ThrowsAsync(new InvalidOperationException("Some error")); var serviceProxy = new Mock <IServiceProxy>(); serviceProxy.Setup(s => s.GetServiceIdentitiesIterator()).Returns(iterator.Object); var store = GetEntityStore("cache"); var serviceAuthentication = new ServiceAuthentication(ServiceAuthenticationType.None); var si1 = new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); var si2 = new ServiceIdentity("d2", "m1", "2345", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); var storedSi1 = new DeviceScopeIdentitiesCache.StoredServiceIdentity(si1); await store.Put(si1.Id, storedSi1.ToJson()); var storedSi2 = new DeviceScopeIdentitiesCache.StoredServiceIdentity(si2); await store.Put(si2.Id, storedSi2.ToJson()); // Act IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy.Object, store, TimeSpan.FromHours(1)); Option <ServiceIdentity> receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); Option <ServiceIdentity> receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); // Assert Assert.True(si1.Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2.Equals(receivedServiceIdentity2.OrDefault())); }
async Task <bool> AuthorizeActorAsync(IDeviceScopeIdentitiesCache identitiesCache, string actorDeviceId, string actorModuleId, string targetId) { if (actorModuleId != Constants.EdgeHubModuleId) { // Only child EdgeHubs are allowed to act OnBehalfOf of devices/modules. Events.AuthFail_BadActor(actorDeviceId, actorModuleId, targetId); return(false); } // Actor device is claiming to be our child, and that the target device is its child. // So we should have an authchain already cached for the target device. Option <string> targetAuthChainOption = await identitiesCache.GetAuthChain(targetId); if (!targetAuthChainOption.HasValue) { Events.AuthFail_NoAuthChain(targetId); return(false); } // Validate the target auth-chain string targetAuthChain = targetAuthChainOption.Expect(() => new InvalidOperationException()); if (!AuthChainHelpers.ValidateAuthChain(actorDeviceId, targetId, targetAuthChain)) { Events.AuthFail_InvalidAuthChain(actorDeviceId, targetId, targetAuthChain); return(false); } return(true); }
public async Task GetDeviceAndModuleOnBehalfOfAsync([FromRoute] string actorDeviceId, [FromRoute] string actorModuleId, [FromBody] IdentityOnBehalfOfRequest request) { actorDeviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorDeviceId, nameof(actorDeviceId))); actorModuleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorModuleId, nameof(actorModuleId))); Preconditions.CheckNonWhiteSpace(request.AuthChain, nameof(request.AuthChain)); if (actorModuleId != Constants.EdgeHubModuleId) { // Only child EdgeHubs are allowed to act OnBehalfOf of devices/modules. var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, Events.UnauthorizedActor(actorDeviceId, actorModuleId, string.IsNullOrWhiteSpace(request.TargetModuleId) ? request.TargetDeviceId : $"{request.TargetDeviceId}/{request.TargetModuleId}")); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } IHttpRequestAuthenticator authenticator = await this.authenticatorGetter; HttpAuthResult authResult = await authenticator.AuthenticateAsync(actorDeviceId, Option.Some(actorModuleId), Option.Some(request.AuthChain), this.HttpContext); if (authResult.Authenticated) { IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); EdgeHubScopeResult reqResult = await HandleGetDeviceAndModuleOnBehalfOfAsync(actorDeviceId, actorModuleId, request, identitiesCache); await this.SendResponse(reqResult.Status, JsonConvert.SerializeObject(reqResult)); } else { var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, authResult.ErrorMessage); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } }
public DeviceScopeCertificateAuthenticator( IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, IAuthenticator underlyingAuthenticator, IList <X509Certificate2> trustBundle, bool syncServiceIdentityOnFailure) : base(deviceScopeIdentitiesCache, underlyingAuthenticator, false, syncServiceIdentityOnFailure) { this.trustBundle = Preconditions.CheckNotNull(trustBundle, nameof(trustBundle)); }
public async Task DeleteModuleAsync( [FromRoute] string deviceId, [FromRoute] string moduleId) { try { Events.ReceivedRequest(nameof(this.DeleteModuleAsync), deviceId, moduleId); try { deviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(deviceId, nameof(deviceId))); moduleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(moduleId, nameof(moduleId))); } catch (Exception ex) { Events.BadRequest(nameof(this.DeleteModuleAsync), ex.Message); await this.SendResponseAsync(HttpStatusCode.BadRequest, FormatErrorResponseMessage(ex.Message)); return; } IHttpRequestAuthenticator authenticator = await this.authenticatorGetter; if (!await AuthenticateAsync(deviceId, Option.None <string>(), Option.None <string>(), this.HttpContext, authenticator)) { await this.SendResponseAsync(HttpStatusCode.Unauthorized); return; } IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); Option <string> targetAuthChain = await identitiesCache.GetAuthChain(deviceId); if (!targetAuthChain.HasValue) { Events.AuthorizationFail_NoAuthChain(deviceId); await this.SendResponseAsync(HttpStatusCode.Unauthorized); return; } string edgeDeviceId = edgeHub.GetEdgeDeviceId(); var requestData = new DeleteModuleOnBehalfOfData($"{targetAuthChain.OrDefault()}", moduleId); RegistryApiHttpResult result = await this.apiClient.DeleteModuleAsync(edgeDeviceId, requestData); await this.SendResponseAsync(result.StatusCode, result.JsonContent); Events.CompleteRequest(nameof(this.DeleteModuleAsync), edgeDeviceId, requestData.AuthChain, result); } catch (Exception ex) { Events.InternalServerError(nameof(this.DeleteModuleAsync), ex); await this.SendResponseAsync(HttpStatusCode.InternalServerError, FormatErrorResponseMessage(ex.ToString())); } }
protected DeviceScopeAuthenticator( IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, IAuthenticator underlyingAuthenticator, bool allowDeviceAuthForModule, bool syncServiceIdentityOnFailure) { this.underlyingAuthenticator = Preconditions.CheckNotNull(underlyingAuthenticator, nameof(underlyingAuthenticator)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.allowDeviceAuthForModule = allowDeviceAuthForModule; this.syncServiceIdentityOnFailure = syncServiceIdentityOnFailure; }
public DeviceScopeTokenAuthenticator( IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, string iothubHostName, string edgeHubHostName, IAuthenticator underlyingAuthenticator) { this.underlyingAuthenticator = Preconditions.CheckNotNull(underlyingAuthenticator, nameof(underlyingAuthenticator)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.iothubHostName = Preconditions.CheckNonWhiteSpace(iothubHostName, nameof(iothubHostName)); this.edgeHubHostName = Preconditions.CheckNotNull(edgeHubHostName, nameof(edgeHubHostName)); }
public DeviceScopeTokenAuthenticator( IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, string iothubHostName, string edgeHubHostName, IAuthenticator underlyingAuthenticator, bool allowDeviceAuthForModule, bool syncServiceIdentityOnFailure) : base(deviceScopeIdentitiesCache, underlyingAuthenticator, allowDeviceAuthForModule, syncServiceIdentityOnFailure) { this.iothubHostName = Preconditions.CheckNonWhiteSpace(iothubHostName, nameof(iothubHostName)); this.edgeHubHostName = Preconditions.CheckNotNull(edgeHubHostName, nameof(edgeHubHostName)); }
public DeviceScopeTokenAuthenticator(IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, string iothubHostName, string edgeHubHostName, IAuthenticator underlyingAuthenticator, IConnectionManager connectionManager) { this.underlyingAuthenticator = Preconditions.CheckNotNull(underlyingAuthenticator, nameof(underlyingAuthenticator)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.iothubHostName = Preconditions.CheckNonWhiteSpace(iothubHostName, nameof(iothubHostName)); this.edgeHubHostName = Preconditions.CheckNotNull(edgeHubHostName, nameof(edgeHubHostName)); this.connectionManager = Preconditions.CheckNotNull(connectionManager, nameof(connectionManager)); this.deviceScopeIdentitiesCache.ServiceIdentityUpdated += this.HandleServiceIdentityUpdate; this.deviceScopeIdentitiesCache.ServiceIdentityRemoved += this.HandleServiceIdentityRemove; }
internal EdgeHubConnection( IIdentity edgeHubIdentity, ITwinManager twinManager, RouteFactory routeFactory, IMessageConverter <TwinCollection> twinCollectionMessageConverter, VersionInfo versionInfo, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache) { this.edgeHubIdentity = edgeHubIdentity; this.twinManager = twinManager; this.twinCollectionMessageConverter = twinCollectionMessageConverter; this.routeFactory = routeFactory; this.versionInfo = versionInfo ?? VersionInfo.Empty; this.deviceScopeIdentitiesCache = deviceScopeIdentitiesCache; }
public CloudConnectionProvider(IMessageConverterProvider messageConverterProvider, int connectionPoolSize, IClientProvider clientProvider, Option <UpstreamProtocol> upstreamProtocol, ITokenProvider edgeHubTokenProvider, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, TimeSpan idleTimeout) { Preconditions.CheckRange(connectionPoolSize, 1, nameof(connectionPoolSize)); this.messageConverterProvider = Preconditions.CheckNotNull(messageConverterProvider, nameof(messageConverterProvider)); this.clientProvider = Preconditions.CheckNotNull(clientProvider, nameof(clientProvider)); this.transportSettings = GetTransportSettings(upstreamProtocol, connectionPoolSize); this.edgeHub = Option.None <IEdgeHub>(); this.idleTimeout = idleTimeout; this.edgeHubTokenProvider = Preconditions.CheckNotNull(edgeHubTokenProvider, nameof(edgeHubTokenProvider)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); }
public static async Task <EdgeHubConnection> Create( IClientCredentials edgeHubCredentials, IEdgeHub edgeHub, ITwinManager twinManager, IConnectionManager connectionManager, ICloudProxy cloudProxy, RouteFactory routeFactory, IMessageConverter <TwinCollection> twinCollectionMessageConverter, IMessageConverter <Twin> twinMessageConverter, VersionInfo versionInfo, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache ) { Preconditions.CheckNotNull(edgeHubCredentials, nameof(edgeHubCredentials)); Preconditions.CheckNotNull(edgeHub, nameof(edgeHub)); Preconditions.CheckNotNull(connectionManager, nameof(connectionManager)); Preconditions.CheckNotNull(cloudProxy, nameof(cloudProxy)); Preconditions.CheckNotNull(twinCollectionMessageConverter, nameof(twinCollectionMessageConverter)); Preconditions.CheckNotNull(twinMessageConverter, nameof(twinMessageConverter)); Preconditions.CheckNotNull(routeFactory, nameof(routeFactory)); Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); var edgeHubConnection = new EdgeHubConnection( edgeHubCredentials.Identity as IModuleIdentity, twinManager, routeFactory, twinCollectionMessageConverter, twinMessageConverter, versionInfo ?? VersionInfo.Empty, deviceScopeIdentitiesCache ); IDeviceProxy deviceProxy = new EdgeHubDeviceProxy(edgeHubConnection); await connectionManager.AddDeviceConnection(edgeHubCredentials); connectionManager.BindDeviceProxy(edgeHubCredentials.Identity, deviceProxy); await edgeHub.AddSubscription(edgeHubCredentials.Identity.Id, DeviceSubscription.DesiredPropertyUpdates); await edgeHub.AddSubscription(edgeHubCredentials.Identity.Id, DeviceSubscription.Methods); // Clear out all the reported devices. await edgeHubConnection.ClearDeviceConnectionStatuses(); connectionManager.DeviceConnected += edgeHubConnection.DeviceConnected; connectionManager.DeviceDisconnected += edgeHubConnection.DeviceDisconnected; Events.Initialized(edgeHubCredentials.Identity); return(edgeHubConnection); }
public CloudConnection(Action <string, CloudConnectionStatus> connectionStatusChangedHandler, ITransportSettings[] transportSettings, IMessageConverterProvider messageConverterProvider, IClientProvider clientProvider, ICloudListener cloudListener, ITokenProvider edgeHubTokenProvider, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, TimeSpan idleTimeout) { this.connectionStatusChangedHandler = connectionStatusChangedHandler; this.transportSettingsList = Preconditions.CheckNotNull(transportSettings, nameof(transportSettings)); this.messageConverterProvider = Preconditions.CheckNotNull(messageConverterProvider, nameof(messageConverterProvider)); this.tokenGetter = Option.None <TaskCompletionSource <string> >(); this.clientProvider = Preconditions.CheckNotNull(clientProvider, nameof(clientProvider)); this.cloudListener = Preconditions.CheckNotNull(cloudListener, nameof(cloudListener)); this.idleTimeout = idleTimeout; this.edgeHubTokenProvider = Preconditions.CheckNotNull(edgeHubTokenProvider, nameof(edgeHubTokenProvider)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); }
public ConnectionReauthenticator( IConnectionManager connectionManager, IAuthenticator authenticator, ICredentialsCache credentialsCache, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache, TimeSpan reauthenticateFrequency, IIdentity edgeHubIdentity) { this.connectionManager = Preconditions.CheckNotNull(connectionManager, nameof(connectionManager)); this.authenticator = Preconditions.CheckNotNull(authenticator, nameof(authenticator)); this.credentialsCache = Preconditions.CheckNotNull(credentialsCache, nameof(credentialsCache)); this.edgeHubIdentity = Preconditions.CheckNotNull(edgeHubIdentity, nameof(edgeHubIdentity)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); this.timer = new Timer(reauthenticateFrequency.TotalMilliseconds); this.timer.Elapsed += this.ReauthenticateConnections; this.connectionManager.CloudConnectionEstablished += this.CloudConnectionEstablishedHandler; this.deviceScopeIdentitiesCache.ServiceIdentityUpdated += this.HandleServiceIdentityUpdate; this.deviceScopeIdentitiesCache.ServiceIdentityRemoved += this.HandleServiceIdentityRemove; }
public RoutingEdgeHub( Router router, Core.IMessageConverter <IRoutingMessage> messageConverter, IConnectionManager connectionManager, ITwinManager twinManager, string edgeDeviceId, IInvokeMethodHandler invokeMethodHandler, ISubscriptionProcessor subscriptionProcessor, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache) { this.router = Preconditions.CheckNotNull(router, nameof(router)); this.messageConverter = Preconditions.CheckNotNull(messageConverter, nameof(messageConverter)); this.connectionManager = Preconditions.CheckNotNull(connectionManager, nameof(connectionManager)); this.twinManager = Preconditions.CheckNotNull(twinManager, nameof(twinManager)); this.edgeDeviceId = Preconditions.CheckNonWhiteSpace(edgeDeviceId, nameof(edgeDeviceId)); this.invokeMethodHandler = Preconditions.CheckNotNull(invokeMethodHandler, nameof(invokeMethodHandler)); this.subscriptionProcessor = Preconditions.CheckNotNull(subscriptionProcessor, nameof(subscriptionProcessor)); this.deviceScopeIdentitiesCache = Preconditions.CheckNotNull(deviceScopeIdentitiesCache, nameof(deviceScopeIdentitiesCache)); }
internal static async Task <Try <string> > AuthorizeOnBehalfOf( string actorDeviceId, string authChain, string source, HttpContext httpContext, IEdgeHub edgeHub, IHttpRequestAuthenticator authenticator) { if (!AuthChainHelpers.TryGetTargetDeviceId(authChain, out string targetDeviceId)) { Events.InvalidRequestAuthChain(source, authChain); return(Try <string> .Failure(new ValidationException(HttpStatusCode.BadRequest, FormatErrorResponseMessage($"Invalid request auth chain {authChain}.")))); } if (!await AuthenticateAsync(actorDeviceId, Option.Some(Constants.EdgeHubModuleId), Option.Some(authChain), httpContext, authenticator)) { return(Try <string> .Failure(new ValidationException(HttpStatusCode.Unauthorized))); } IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); Option <string> targetAuthChain = await identitiesCache.GetAuthChain(targetDeviceId); return(targetAuthChain.Match( ac => { if (!AuthChainHelpers.ValidateAuthChain(actorDeviceId, targetDeviceId, ac)) { Events.AuthorizationFail_InvalidAuthChain(actorDeviceId, targetDeviceId, ac); return Try <string> .Failure(new ValidationException(HttpStatusCode.Unauthorized)); } return ac; }, () => { Events.AuthorizationFail_NoAuthChain(targetDeviceId); return Try <string> .Failure(new ValidationException(HttpStatusCode.Unauthorized)); })); }
async Task <EdgeHubScopeResult> HandleDevicesAndModulesInTargetDeviceScopeAsync(string actorDeviceId, string actorModuleId, NestedScopeRequest request) { Events.ReceivedScopeRequest(actorDeviceId, actorModuleId, request); if (!AuthChainHelpers.TryGetTargetDeviceId(request.AuthChain, out string targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.BadRequest, Events.InvalidRequestAuthchain(request.AuthChain))); } // Get the children of the target device and the target device itself; IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); IList <ServiceIdentity> identities = await identitiesCache.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId); Option <ServiceIdentity> targetDevice = await identitiesCache.GetServiceIdentity(targetDeviceId); targetDevice.ForEach(d => identities.Add(d)); // Construct the result from the identities Events.SendingScopeResult(targetDeviceId, identities); return(MakeResultFromIdentities(identities)); }
public async Task RefreshServiceIdentityTest_List() { // Arrange var store = new EntityStore <string, string>(new InMemoryDbStore(), "cache"); var serviceAuthenticationNone = new ServiceAuthentication(ServiceAuthenticationType.None); var serviceAuthenticationSas = new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())); var si1_initial = new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthenticationNone, ServiceIdentityStatus.Enabled); var si1_updated = new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthenticationSas, ServiceIdentityStatus.Enabled); var si2 = new ServiceIdentity("d2", "5678", Enumerable.Empty <string>(), serviceAuthenticationSas, ServiceIdentityStatus.Enabled); var iterator1 = new Mock <IServiceIdentitiesIterator>(); iterator1.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator1.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1_initial, si2 }); var serviceProxy = new Mock <IServiceProxy>(); serviceProxy.Setup(s => s.GetServiceIdentitiesIterator()) .Returns(iterator1.Object); serviceProxy.Setup(s => s.GetServiceIdentity(It.Is <string>(id => id == "d1"))).ReturnsAsync(Option.Some(si1_updated)); serviceProxy.Setup(s => s.GetServiceIdentity(It.Is <string>(id => id == "d2"))).ReturnsAsync(Option.None <ServiceIdentity>()); var updatedIdentities = new List <ServiceIdentity>(); var removedIdentities = new List <string>(); // Act IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy.Object, store, TimeSpan.FromHours(1)); deviceScopeIdentitiesCache.ServiceIdentityUpdated += (sender, identity) => updatedIdentities.Add(identity); deviceScopeIdentitiesCache.ServiceIdentityRemoved += (sender, s) => removedIdentities.Add(s); // Wait for refresh to complete await Task.Delay(TimeSpan.FromSeconds(3)); Option <ServiceIdentity> receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); Option <ServiceIdentity> receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2"); // Assert Assert.True(si1_initial.Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2.Equals(receivedServiceIdentity2.OrDefault())); // Update the identities await deviceScopeIdentitiesCache.RefreshServiceIdentities(new[] { "d1", "d2" }); receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2"); // Assert Assert.True(si1_updated.Equals(receivedServiceIdentity1.OrDefault())); Assert.False(receivedServiceIdentity2.HasValue); Assert.Equal(1, removedIdentities.Count); Assert.Equal("d2", removedIdentities[0]); Assert.Equal(1, updatedIdentities.Count); Assert.Equal("d1", updatedIdentities[0].Id); }
protected override void Load(ContainerBuilder builder) { // IMessageConverter<IRoutingMessage> builder.Register(c => new RoutingMessageConverter()) .As <Core.IMessageConverter <IRoutingMessage> >() .SingleInstance(); // IRoutingPerfCounter builder.Register( c => { Routing.PerfCounter = NullRoutingPerfCounter.Instance; return(Routing.PerfCounter); }) .As <IRoutingPerfCounter>() .AutoActivate() .SingleInstance(); // IRoutingUserAnalyticsLogger builder.Register( c => { Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; return(Routing.UserAnalyticsLogger); }) .As <IRoutingUserAnalyticsLogger>() .AutoActivate() .SingleInstance(); // IRoutingUserMetricLogger builder.Register( c => { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; return(Routing.UserMetricLogger); }) .As <IRoutingUserMetricLogger>() .AutoActivate() .SingleInstance(); // IMessageConverter<Message> builder.Register(c => new DeviceClientMessageConverter()) .As <Core.IMessageConverter <Message> >() .SingleInstance(); // IMessageConverter<Twin> builder.Register(c => new TwinMessageConverter()) .As <Core.IMessageConverter <Twin> >() .SingleInstance(); // IMessageConverter<TwinCollection> builder.Register(c => new TwinCollectionMessageConverter()) .As <Core.IMessageConverter <TwinCollection> >() .SingleInstance(); // IMessageConverterProvider builder.Register( c => new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() }, { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() }, { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() } })) .As <IMessageConverterProvider>() .SingleInstance(); // IDeviceConnectivityManager builder.Register( c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); IDeviceConnectivityManager deviceConnectivityManager = this.experimentalFeatures.DisableConnectivityCheck ? new NullDeviceConnectivityManager() : new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2), edgeHubCredentials.Identity) as IDeviceConnectivityManager; return(deviceConnectivityManager); }) .As <IDeviceConnectivityManager>() .SingleInstance(); // IDeviceClientProvider builder.Register( c => { IClientProvider underlyingClientProvider = new ClientProvider(); IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>()); return(connectivityAwareClientProvider); }) .As <IClientProvider>() .SingleInstance(); // Task<ICloudConnectionProvider> builder.Register( async c => { var productInfoStore = await c.Resolve <Task <IProductInfoStore> >(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var clientProvider = c.Resolve <IClientProvider>(); var tokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubClientAuthTokenProvider"); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var proxy = c.Resolve <Option <IWebProxy> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask; ICredentialsCache credentialsCache = await credentialsCacheTask; ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider( messageConverterProvider, this.connectionPoolSize, clientProvider, this.upstreamProtocol, tokenProvider, deviceScopeIdentitiesCache, credentialsCache, edgeHubCredentials.Identity, this.cloudConnectionIdleTimeout, this.closeCloudConnectionOnIdleTimeout, this.operationTimeout, this.useServerHeartbeat, proxy, productInfoStore); return(cloudConnectionProvider); }) .As <Task <ICloudConnectionProvider> >() .SingleInstance(); // IIdentityProvider builder.Register(_ => new IdentityProvider(this.iotHubName)) .As <IIdentityProvider>() .SingleInstance(); // Task<IConnectionManager> builder.Register( async c => { var cloudConnectionProviderTask = c.Resolve <Task <ICloudConnectionProvider> >(); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var identityProvider = c.Resolve <IIdentityProvider>(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); ICloudConnectionProvider cloudConnectionProvider = await cloudConnectionProviderTask; ICredentialsCache credentialsCache = await credentialsCacheTask; IConnectionManager connectionManager = new ConnectionManager( cloudConnectionProvider, credentialsCache, identityProvider, deviceConnectivityManager, this.maxConnectedClients, this.closeCloudConnectionOnDeviceDisconnect); return(connectionManager); }) .As <Task <IConnectionManager> >() .SingleInstance(); // Task<IEndpointFactory> builder.Register( async c => { var messageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new EndpointFactory(connectionManager, messageConverter, this.edgeDeviceId, this.maxUpstreamBatchSize, this.upstreamFanOutFactor) as IEndpointFactory); }) .As <Task <IEndpointFactory> >() .SingleInstance(); // Task<RouteFactory> builder.Register(async c => new EdgeRouteFactory(await c.Resolve <Task <IEndpointFactory> >()) as RouteFactory) .As <Task <RouteFactory> >() .SingleInstance(); // RouterConfig builder.Register(c => new RouterConfig(Enumerable.Empty <Route>())) .As <RouterConfig>() .SingleInstance(); if (!this.isStoreAndForwardEnabled) { // EndpointExecutorConfig builder.Register( c => { RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // IEndpointExecutorFactory builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>())) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); var routerConfig = c.Resolve <RouterConfig>(); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory); return(router); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register( async c => { if (!this.useV1TwinManager) { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); ITwinManager twinManager = new PassThroughTwinManager(connectionManager, messageConverterProvider); return(twinManager); } else { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>())); } }) .As <Task <ITwinManager> >() .SingleInstance(); } else { // EndpointExecutorConfig builder.Register( c => { // Endpoint executor config values - // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default) // Num of retries = int.MaxValue(we want to keep retrying till the message is sent) // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires) // Timeout - time for which we want for the ack from the endpoint = 30s // TODO - Should the number of retries be tied to the Store and Forward ttl? Not // doing that right now as that value can be changed at runtime, but these settings // cannot. Need to make the number of retries dynamically configurable for that. TimeSpan minWait = TimeSpan.FromSeconds(1); TimeSpan maxWait = TimeSpan.FromSeconds(60); TimeSpan delta = TimeSpan.FromSeconds(1); int retries = int.MaxValue; RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta); TimeSpan timeout = TimeSpan.FromSeconds(30); TimeSpan revivePeriod = TimeSpan.FromSeconds(30); return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // Task<ICheckpointStore> builder.Register( async c => { var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider); return(checkpointStore); }) .As <Task <ICheckpointStore> >() .SingleInstance(); // Task<IMessageStore> builder.Register( async c => { var checkpointStore = await c.Resolve <Task <ICheckpointStore> >(); var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, checkpointStore, this.storeAndForwardConfiguration.TimeToLive, this.checkEntireQueueOnCleanup); return(messageStore); }) .As <Task <IMessageStore> >() .SingleInstance(); // Task<IEndpointExecutorFactory> builder.Register( async c => { var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>(); var messageStore = await c.Resolve <Task <IMessageStore> >(); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore); return(endpointExecutorFactory); }) .As <Task <IEndpointExecutorFactory> >() .SingleInstance(); // Task<Router> builder.Register( async c => { var checkpointStore = await c.Resolve <Task <ICheckpointStore> >(); var routerConfig = c.Resolve <RouterConfig>(); var endpointExecutorFactory = await c.Resolve <Task <IEndpointExecutorFactory> >(); return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore)); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register( async c => { if (this.useV1TwinManager) { var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.Some <IStoreProvider>(new StoreProvider(dbStoreProvider)))); } else { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); IEntityStore <string, TwinStoreEntity> entityStore = await this.GetTwinStore(c); IConnectionManager connectionManager = await connectionManagerTask; ITwinManager twinManager = StoringTwinManager.Create( connectionManager, messageConverterProvider, entityStore, deviceConnectivityManager, new ReportedPropertiesValidator(), this.minTwinSyncPeriod, this.reportedPropertiesSyncFrequency); return(twinManager); } }) .As <Task <ITwinManager> >() .SingleInstance(); } // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // Task<IInvokeMethodHandler> builder.Register( async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new InvokeMethodHandler(connectionManager) as IInvokeMethodHandler); }) .As <Task <IInvokeMethodHandler> >() .SingleInstance(); // Task<ISubscriptionProcessor> builder.Register( async c => { var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); if (this.experimentalFeatures.DisableCloudSubscriptions) { return(new LocalSubscriptionProcessor(await connectionManagerTask) as ISubscriptionProcessor); } else { var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; return(new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager) as ISubscriptionProcessor); } }) .As <Task <ISubscriptionProcessor> >() .SingleInstance(); // Task<IEdgeHub> builder.Register( async c => { var routingMessageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); var routerTask = c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var subscriptionProcessorTask = c.Resolve <Task <ISubscriptionProcessor> >(); Router router = await routerTask; ITwinManager twinManager = await twinManagerTask; IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; ISubscriptionProcessor subscriptionProcessor = await subscriptionProcessorTask; IEdgeHub hub = new RoutingEdgeHub( router, routingMessageConverter, connectionManager, twinManager, this.edgeDeviceId, invokeMethodHandler, subscriptionProcessor); return(hub); }) .As <Task <IEdgeHub> >() .SingleInstance(); // Task<ConfigUpdater> builder.Register( async c => { IMessageStore messageStore = this.isStoreAndForwardEnabled ? await c.Resolve <Task <IMessageStore> >() : null; var storageSpaceChecker = c.Resolve <IStorageSpaceChecker>(); var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); Router router = await c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); var twinManager = await twinManagerTask; var configUpdater = new ConfigUpdater(router, messageStore, this.configUpdateFrequency, storageSpaceChecker); return(configUpdater); }) .As <Task <ConfigUpdater> >() .SingleInstance(); // Task<IConfigSource> builder.Register <Task <IConfigSource> >( async c => { RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); if (this.useTwinConfig) { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var edgeHubTask = c.Resolve <Task <IEdgeHub> >(); ITwinManager twinManager = await twinManagerTask; IEdgeHub edgeHub = await edgeHubTask; IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials.Identity, edgeHub, twinManager, connectionManager, routeFactory, twinCollectionMessageConverter, this.versionInfo, deviceScopeIdentitiesCache); return(new TwinConfigSource(edgeHubConnection, edgeHubCredentials.Identity.Id, this.versionInfo, twinManager, twinMessageConverter, twinCollectionMessageConverter, routeFactory)); } else { return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration)); } }) .As <Task <IConfigSource> >() .SingleInstance(); // Task<IConnectionProvider> builder.Register( async c => { var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var edgeHubTask = c.Resolve <Task <IEdgeHub> >(); IConnectionManager connectionManager = await connectionManagerTask; IEdgeHub edgeHub = await edgeHubTask; IConnectionProvider connectionProvider = new ConnectionProvider(connectionManager, edgeHub, this.messageAckTimeout); return(connectionProvider); }) .As <Task <IConnectionProvider> >() .SingleInstance(); base.Load(builder); }
protected override void Load(ContainerBuilder builder) { // IMessageConverter<IRoutingMessage> builder.Register(c => new RoutingMessageConverter()) .As <Core.IMessageConverter <IRoutingMessage> >() .SingleInstance(); // IRoutingPerfCounter builder.Register( c => { Routing.PerfCounter = NullRoutingPerfCounter.Instance; return(Routing.PerfCounter); }) .As <IRoutingPerfCounter>() .AutoActivate() .SingleInstance(); // IRoutingUserAnalyticsLogger builder.Register( c => { Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; return(Routing.UserAnalyticsLogger); }) .As <IRoutingUserAnalyticsLogger>() .AutoActivate() .SingleInstance(); // IRoutingUserMetricLogger builder.Register( c => { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; return(Routing.UserMetricLogger); }) .As <IRoutingUserMetricLogger>() .AutoActivate() .SingleInstance(); // IMessageConverter<Message> builder.Register(c => new DeviceClientMessageConverter()) .As <Core.IMessageConverter <Message> >() .SingleInstance(); // IMessageConverter<Twin> builder.Register(c => new TwinMessageConverter()) .As <Core.IMessageConverter <Twin> >() .SingleInstance(); // IMessageConverter<TwinCollection> builder.Register(c => new TwinCollectionMessageConverter()) .As <Core.IMessageConverter <TwinCollection> >() .SingleInstance(); // IMessageConverterProvider builder.Register( c => new MessageConverterProvider(new Dictionary <Type, IMessageConverter>() { { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() }, { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() }, { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() } })) .As <IMessageConverterProvider>() .SingleInstance(); // IDeviceConnectivityManager builder.Register( c => { IDeviceConnectivityManager deviceConnectivityManager = new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2)); return(deviceConnectivityManager); }) .As <IDeviceConnectivityManager>() .SingleInstance(); // IDeviceClientProvider builder.Register(c => { IClientProvider underlyingClientProvider = new ClientProvider(); IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>()); return(connectivityAwareClientProvider); }) .As <IClientProvider>() .SingleInstance(); // Task<ICloudConnectionProvider> builder.Register( async c => { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var clientProvider = c.Resolve <IClientProvider>(); var tokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubClientAuthTokenProvider"); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider( messageConverterProvider, this.connectionPoolSize, clientProvider, this.upstreamProtocol, tokenProvider, deviceScopeIdentitiesCache, TimeSpan.FromMinutes(60)); return(cloudConnectionProvider); }) .As <Task <ICloudConnectionProvider> >() .SingleInstance(); // Task<ICredentialsStore> builder.Register(async c => { if (this.cacheTokens) { IKeyValueStore <string, string> encryptedStore = await c.ResolveNamed <Task <IKeyValueStore <string, string> > >("EncryptedStore"); return(new TokenCredentialsStore(encryptedStore)); } else { return(new NullCredentialsStore() as ICredentialsStore); } }) .As <Task <ICredentialsStore> >() .SingleInstance(); // Task<IConnectionManager> builder.Register( async c => { ICloudConnectionProvider cloudConnectionProvider = await c.Resolve <Task <ICloudConnectionProvider> >(); IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, this.maxConnectedClients); return(connectionManager); }) .As <Task <IConnectionManager> >() .SingleInstance(); // Task<IEndpointFactory> builder.Register(async c => { var messageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new EndpointFactory(connectionManager, messageConverter, this.edgeDeviceId) as IEndpointFactory); }) .As <Task <IEndpointFactory> >() .SingleInstance(); // Task<RouteFactory> builder.Register(async c => new EdgeRouteFactory(await c.Resolve <Task <IEndpointFactory> >()) as RouteFactory) .As <Task <RouteFactory> >() .SingleInstance(); // RouterConfig builder.Register(c => new RouterConfig(Enumerable.Empty <Route>())) .As <RouterConfig>() .SingleInstance(); if (!this.isStoreAndForwardEnabled) { // EndpointExecutorConfig builder.Register( c => { RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // IEndpointExecutorFactory builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>())) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); var routerConfig = c.Resolve <RouterConfig>(); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory); return(router); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register(async c => { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>())); }) .As <Task <ITwinManager> >() .SingleInstance(); } else { // EndpointExecutorConfig builder.Register( c => { // Endpoint executor config values - // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default) // Num of retries = int.MaxValue(we want to keep retrying till the message is sent) // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires) // Timeout - time for which we want for the ack from the endpoint = 30s // TODO - Should the number of retries be tied to the Store and Forward ttl? Not // doing that right now as that value can be changed at runtime, but these settings // cannot. Need to make the number of retries dynamically configurable for that. TimeSpan minWait = TimeSpan.FromSeconds(1); TimeSpan maxWait = TimeSpan.FromSeconds(60); TimeSpan delta = TimeSpan.FromSeconds(1); int retries = int.MaxValue; RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta); TimeSpan timeout = TimeSpan.FromSeconds(30); TimeSpan revivePeriod = TimeSpan.FromSeconds(30); return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // ICheckpointStore builder.Register(c => CheckpointStore.Create(c.Resolve <IDbStoreProvider>())) .As <ICheckpointStore>() .SingleInstance(); // IMessageStore builder.Register( c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var dbStoreProvider = c.Resolve <IDbStoreProvider>(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, checkpointStore, TimeSpan.MaxValue); return(messageStore); }) .As <IMessageStore>() .SingleInstance(); // IEndpointExecutorFactory builder.Register( c => { var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>(); var messageStore = c.Resolve <IMessageStore>(); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore); return(endpointExecutorFactory); }) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var routerConfig = c.Resolve <RouterConfig>(); var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore)); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register(async c => { var dbStoreProvider = c.Resolve <IDbStoreProvider>(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.Some <IStoreProvider>(new StoreProvider(dbStoreProvider)))); }) .As <Task <ITwinManager> >() .SingleInstance(); } // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // Task<ICloudProxy> "EdgeHubCloudProxy" builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); Try <ICloudProxy> cloudProxyTry = await connectionManager.CreateCloudConnectionAsync(edgeHubCredentials); if (!cloudProxyTry.Success) { throw new EdgeHubConnectionException("Edge hub is unable to connect to IoT Hub", cloudProxyTry.Exception); } ICloudProxy cloudProxy = cloudProxyTry.Value; return(cloudProxy); }) .Named <Task <ICloudProxy> >("EdgeHubCloudProxy") .SingleInstance(); // Task<IInvokeMethodHandler> builder.Register(async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new InvokeMethodHandler(connectionManager) as IInvokeMethodHandler); }) .As <Task <IInvokeMethodHandler> >() .SingleInstance(); // Task<IEdgeHub> builder.Register( async c => { var routingMessageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); var routerTask = c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); Router router = await routerTask; ITwinManager twinManager = await twinManagerTask; IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; IEdgeHub hub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, this.edgeDeviceId, invokeMethodHandler); return(hub); }) .As <Task <IEdgeHub> >() .SingleInstance(); // Task<ConfigUpdater> builder.Register( async c => { IMessageStore messageStore = this.isStoreAndForwardEnabled ? c.Resolve <IMessageStore>() : null; Router router = await c.Resolve <Task <Router> >(); var configUpdater = new ConfigUpdater(router, messageStore); return(configUpdater); }) .As <Task <ConfigUpdater> >() .SingleInstance(); // Task<IConfigSource> builder.Register( async c => { RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); if (this.useTwinConfig) { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); ITwinManager twinManager = await c.Resolve <Task <ITwinManager> >(); ICloudProxy cloudProxy = await c.ResolveNamed <Task <ICloudProxy> >("EdgeHubCloudProxy"); IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); IConfigSource edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials, edgeHub, twinManager, connectionManager, cloudProxy, routeFactory, twinCollectionMessageConverter, twinMessageConverter, this.versionInfo, deviceScopeIdentitiesCache ); return(edgeHubConnection); } else { return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration)); } }) .As <Task <IConfigSource> >() .SingleInstance(); // Task<IConnectionProvider> builder.Register( async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConnectionProvider connectionProvider = new ConnectionProvider(connectionManager, edgeHub); return(connectionProvider); }) .As <Task <IConnectionProvider> >() .SingleInstance(); base.Load(builder); }
public async Task GetServiceIdentityTest_Module() { // Arrange var store = GetEntityStore("cache"); var serviceAuthenticationNone = new ServiceAuthentication(ServiceAuthenticationType.None); var serviceAuthenticationSas = new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())); var si1_initial = new ServiceIdentity("d1", "m1", "1234", Enumerable.Empty <string>(), serviceAuthenticationNone, ServiceIdentityStatus.Enabled); var si1_updated = new ServiceIdentity("d1", "m1", "1234", Enumerable.Empty <string>(), serviceAuthenticationSas, ServiceIdentityStatus.Disabled); var si2 = new ServiceIdentity("d2", "m2", "5678", Enumerable.Empty <string>(), serviceAuthenticationSas, ServiceIdentityStatus.Enabled); var si3 = new ServiceIdentity("d3", "m3", "0987", Enumerable.Empty <string>(), serviceAuthenticationSas, ServiceIdentityStatus.Enabled); var iterator1 = new Mock <IServiceIdentitiesIterator>(); iterator1.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator1.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1_initial, si2 }); var serviceProxy = new Mock <IServiceProxy>(); serviceProxy.Setup(s => s.GetServiceIdentitiesIterator()) .Returns(iterator1.Object); serviceProxy.Setup(s => s.GetServiceIdentity("d1", "m1")).ReturnsAsync(Option.Some(si1_updated)); serviceProxy.Setup(s => s.GetServiceIdentity("d2", "m2")).ReturnsAsync(Option.None <ServiceIdentity>()); serviceProxy.Setup(s => s.GetServiceIdentity("d3", "m3")).ReturnsAsync(Option.Some(si3)); var updatedIdentities = new List <ServiceIdentity>(); var removedIdentities = new List <string>(); // Act IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy.Object, store, TimeSpan.FromHours(1)); deviceScopeIdentitiesCache.ServiceIdentityUpdated += (sender, identity) => updatedIdentities.Add(identity); deviceScopeIdentitiesCache.ServiceIdentityRemoved += (sender, s) => removedIdentities.Add(s); // Wait for refresh to complete await Task.Delay(TimeSpan.FromSeconds(3)); Option <ServiceIdentity> receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1/m1"); Option <ServiceIdentity> receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m2"); Option <ServiceIdentity> receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3/m3"); // Assert Assert.True(si1_initial.Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2.Equals(receivedServiceIdentity2.OrDefault())); Assert.False(receivedServiceIdentity3.HasValue); // Get the identities with refresh receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1/m1", true); receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m2", true); receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3/m3", true); // Assert Assert.True(si1_initial.Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2.Equals(receivedServiceIdentity2.OrDefault())); Assert.True(si3.Equals(receivedServiceIdentity3.OrDefault())); Assert.Empty(removedIdentities); Assert.Empty(updatedIdentities); }
public async Task RefreshCacheTest() { // Arrange var store = GetEntityStore("cache"); var serviceAuthentication = new ServiceAuthentication(ServiceAuthenticationType.None); Func <ServiceIdentity> si1 = () => new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si2 = () => new ServiceIdentity("d2", "m1", "2345", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si3 = () => new ServiceIdentity("d3", "5678", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si4 = () => new ServiceIdentity("d2", "m4", "9898", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); var iterator1 = new Mock <IServiceIdentitiesIterator>(); iterator1.SetupSequence(i => i.HasNext) .Returns(true) .Returns(true) .Returns(false); iterator1.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1(), si2() }) .ReturnsAsync( new List <ServiceIdentity> { si3(), si4() }); var iterator2 = new Mock <IServiceIdentitiesIterator>(); iterator2.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator2.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1(), si2(), si3() }); var serviceProxy = new Mock <IServiceProxy>(); serviceProxy.SetupSequence(s => s.GetServiceIdentitiesIterator()) .Returns(iterator1.Object) .Returns(iterator2.Object); var updatedIdentities = new List <ServiceIdentity>(); var removedIdentities = new List <string>(); // Act IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy.Object, store, TimeSpan.FromSeconds(8)); deviceScopeIdentitiesCache.ServiceIdentityUpdated += (sender, identity) => updatedIdentities.Add(identity); deviceScopeIdentitiesCache.ServiceIdentityRemoved += (sender, s) => removedIdentities.Add(s); // Wait for refresh to complete await Task.Delay(TimeSpan.FromSeconds(3)); Option <ServiceIdentity> receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); Option <ServiceIdentity> receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); Option <ServiceIdentity> receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3"); Option <ServiceIdentity> receivedServiceIdentity4 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m4"); // Assert Assert.True(si1().Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2().Equals(receivedServiceIdentity2.OrDefault())); Assert.True(si3().Equals(receivedServiceIdentity3.OrDefault())); Assert.True(si4().Equals(receivedServiceIdentity4.OrDefault())); Assert.Empty(updatedIdentities); Assert.Empty(removedIdentities); // Wait for another refresh cycle to complete await Task.Delay(TimeSpan.FromSeconds(8)); receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3"); receivedServiceIdentity4 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m4"); // Assert Assert.True(si1().Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2().Equals(receivedServiceIdentity2.OrDefault())); Assert.True(si3().Equals(receivedServiceIdentity3.OrDefault())); Assert.False(receivedServiceIdentity4.HasValue); Assert.Empty(updatedIdentities); Assert.Single(removedIdentities); Assert.Contains("d2/m4", removedIdentities); }
async Task <EdgeHubScopeResult> HandleGetDeviceAndModuleOnBehalfOfAsync(string actorDeviceId, string actorModuleId, IdentityOnBehalfOfRequest request) { Events.ReceivedIdentityOnBehalfOfRequest(actorDeviceId, actorModuleId, request); Preconditions.CheckNonWhiteSpace(request.TargetDeviceId, nameof(request.TargetDeviceId)); bool isModule = false; string targetId = request.TargetDeviceId; if (!request.TargetModuleId.IsNullOrWhiteSpace()) { isModule = true; targetId += "/" + request.TargetModuleId; } IEdgeHub edgeHub = await this.edgeHubGetter; // Check if the actor has provided the originating EdgeHub ID, // if not, then we must be by definition by the origin. string originatingEdge = edgeHub.GetEdgeDeviceId(); if (this.Request.Headers.TryGetValue(Constants.OriginEdgeHeaderKey, out StringValues originHeader) && originHeader.Count > 0) { originatingEdge = originHeader.First(); } // We must always forward the call further upstream first, // as this is invoked for refreshing an identity on-demand, // and we don't know whether our cache is out-of-date. IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); await identitiesCache.RefreshServiceIdentityOnBehalfOf(targetId, originatingEdge); Option <ServiceIdentity> targetIdentity = await identitiesCache.GetServiceIdentity(targetId); if (!targetIdentity.HasValue) { // Identity still doesn't exist, this can happen if the identity // is newly added and we couldn't refresh the individual identity // because we don't know where it resides in the nested hierarchy. // In this case our only recourse is to refresh the whole cache // and hope the identity shows up. identitiesCache.InitiateCacheRefresh(); await identitiesCache.WaitForCacheRefresh(TimeSpan.FromSeconds(100)); targetIdentity = await identitiesCache.GetServiceIdentity(targetId); } // Add the identity to the result var identityList = new List <ServiceIdentity>(); targetIdentity.ForEach(i => identityList.Add(i)); // If the target is a module, we also need to // include the parent device as well to match // IoT Hub API behavior if (isModule) { Option <ServiceIdentity> device = await identitiesCache.GetServiceIdentity(request.TargetDeviceId); device.ForEach(i => identityList.Add(i)); } Events.SendingScopeResult(targetId, identityList); return(MakeResultFromIdentities(identityList)); }
static async Task <IList <BrokerServiceIdentity> > ConvertIdsToBrokerServiceIdentities(IList <string> ids, IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache) { IList <BrokerServiceIdentity> brokerServiceIdentities = new List <BrokerServiceIdentity>(); foreach (string id in ids) { brokerServiceIdentities.Add( new BrokerServiceIdentity(id, await deviceScopeIdentitiesCache.GetAuthChain(id))); } return(brokerServiceIdentities); }
protected override void Load(ContainerBuilder builder) { // ISignatureProvider builder.Register( c => { ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map( cs => { IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs); return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider); }) .GetOrElse( () => { string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing")); string workloadUri = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing")); return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, Constants.WorkloadApiVersion) as ISignatureProvider); }); return(signatureProvider); }) .As <ISignatureProvider>() .SingleInstance(); // Detect system environment builder.Register(c => new SystemEnvironment()) .As <ISystemEnvironment>() .SingleInstance(); // DataBase options builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance)) .As <IRocksDbOptionsProvider>() .SingleInstance(); // IDbStoreProvider builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(RoutingModule)); if (this.usePersistentStorage) { // Create partitions for messages and twins var partitionsList = new List <string> { Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey }; try { IDbStoreProvider dbStoreprovider = DbStoreProvider.Create( c.Resolve <IRocksDbOptionsProvider>(), this.storagePath, partitionsList); logger.LogInformation($"Created persistent store at {this.storagePath}"); return(dbStoreprovider); } catch (Exception ex) when(!ExceptionEx.IsFatal(ex)) { logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store."); return(new InMemoryDbStoreProvider()); } } else { logger.LogInformation($"Using in-memory store"); return(new InMemoryDbStoreProvider()); } }) .As <IDbStoreProvider>() .SingleInstance(); // Task<Option<IEncryptionProvider>> builder.Register( async c => { Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri .Map( async uri => { var encryptionProvider = await EncryptionProvider.CreateAsync( this.storagePath, new Uri(uri), Constants.WorkloadApiVersion, this.edgeHubModuleId, this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")), Constants.InitializationVectorFileName) as IEncryptionProvider; return(Option.Some(encryptionProvider)); }) .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>())); return(encryptionProviderOption); }) .As <Task <Option <IEncryptionProvider> > >() .SingleInstance(); // IStoreProvider builder.Register(c => new StoreProvider(c.Resolve <IDbStoreProvider>())) .As <IStoreProvider>() .SingleInstance(); // ITokenProvider builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1))) .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider") .SingleInstance(); // ITokenProvider builder.Register( c => { string deviceId = WebUtility.UrlEncode(this.edgeDeviceId); string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId); return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1))); }) .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider") .SingleInstance(); // Task<IDeviceScopeIdentitiesCache> builder.Register( async c => { IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope) { var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider"); IDeviceScopeApiClient securityScopesApiClient = new DeviceScopeApiClient(this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider); IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClient); IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache"); deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate); } else { deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache(); } return(deviceScopeIdentitiesCache); }) .As <Task <IDeviceScopeIdentitiesCache> >() .AutoActivate() .SingleInstance(); // Task<ICredentialsCache> builder.Register( async c => { ICredentialsCache underlyingCredentialsCache; if (this.persistTokens) { IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache"); return(new PersistedTokenCredentialsCache(encryptedStore)); } else { underlyingCredentialsCache = new NullCredentialsCache(); } ICredentialsCache credentialsCache = new CredentialsCache(underlyingCredentialsCache); return(credentialsCache); }) .As <Task <ICredentialsCache> >() .SingleInstance(); // Task<IAuthenticator> builder.Register( async c => { IAuthenticator tokenAuthenticator; IAuthenticator certificateAuthenticator; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); certificateAuthenticator = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true); switch (this.authenticationMode) { case AuthenticationMode.Cloud: tokenAuthenticator = await this.GetCloudTokenAuthenticator(c); break; case AuthenticationMode.Scope: tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true); break; default: IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c); tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true); break; } ICredentialsCache credentialsCache = await credentialsCacheTask; return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator); }) .As <Task <IAuthenticator> >() .SingleInstance(); // IClientCredentialsFactory builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo)) .As <IClientCredentialsFactory>() .SingleInstance(); // ConnectionReauthenticator builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var authenticatorTask = c.Resolve <Task <IAuthenticator> >(); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await connectionManagerTask; IAuthenticator authenticator = await authenticatorTask; ICredentialsCache credentialsCache = await credentialsCacheTask; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask; var connectionReauthenticator = new ConnectionReauthenticator( connectionManager, authenticator, credentialsCache, deviceScopeIdentitiesCache, TimeSpan.FromMinutes(5), edgeHubCredentials.Identity, deviceConnectivityManager); return(connectionReauthenticator); }) .As <Task <ConnectionReauthenticator> >() .SingleInstance(); base.Load(builder); }
public async Task RefreshCacheWithRefreshRequestTest() { // Arrange var store = new EntityStore <string, string>(new InMemoryDbStore(), "cache"); var serviceAuthentication = new ServiceAuthentication(ServiceAuthenticationType.None); Func <ServiceIdentity> si1 = () => new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si2 = () => new ServiceIdentity("d2", "m1", "2345", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si3 = () => new ServiceIdentity("d3", "5678", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); Func <ServiceIdentity> si4 = () => new ServiceIdentity("d2", "m4", "9898", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); var iterator1 = new Mock <IServiceIdentitiesIterator>(); iterator1.SetupSequence(i => i.HasNext) .Returns(true) .Returns(true) .Returns(false); iterator1.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1(), si2() }) .ReturnsAsync( new List <ServiceIdentity> { si3(), si4() }); var iterator2 = new Mock <IServiceIdentitiesIterator>(); iterator2.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator2.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1(), si2(), si3() }); var iterator3 = new Mock <IServiceIdentitiesIterator>(); iterator3.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator3.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si1(), si2() }); var iterator4 = new Mock <IServiceIdentitiesIterator>(); iterator4.SetupSequence(i => i.HasNext) .Returns(true) .Returns(false); iterator4.SetupSequence(i => i.GetNext()) .ReturnsAsync( new List <ServiceIdentity> { si3(), si4() }); var serviceProxy = new Mock <IServiceProxy>(); serviceProxy.SetupSequence(s => s.GetServiceIdentitiesIterator()) .Returns(iterator1.Object) .Returns(iterator2.Object) .Returns(iterator3.Object) .Returns(iterator4.Object); var updatedIdentities = new List <ServiceIdentity>(); var removedIdentities = new List <string>(); // Act IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy.Object, store, TimeSpan.FromSeconds(7)); deviceScopeIdentitiesCache.ServiceIdentityUpdated += (sender, identity) => updatedIdentities.Add(identity); deviceScopeIdentitiesCache.ServiceIdentityRemoved += (sender, s) => removedIdentities.Add(s); // Wait for refresh to complete await Task.Delay(TimeSpan.FromSeconds(3)); Option <ServiceIdentity> receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); Option <ServiceIdentity> receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); Option <ServiceIdentity> receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3"); Option <ServiceIdentity> receivedServiceIdentity4 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m4"); // Assert Assert.True(si1().Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2().Equals(receivedServiceIdentity2.OrDefault())); Assert.True(si3().Equals(receivedServiceIdentity3.OrDefault())); Assert.True(si4().Equals(receivedServiceIdentity4.OrDefault())); Assert.Equal(0, updatedIdentities.Count); Assert.Equal(0, removedIdentities.Count); // Act - Signal refresh cache multiple times. It should get picked up twice. deviceScopeIdentitiesCache.InitiateCacheRefresh(); deviceScopeIdentitiesCache.InitiateCacheRefresh(); deviceScopeIdentitiesCache.InitiateCacheRefresh(); deviceScopeIdentitiesCache.InitiateCacheRefresh(); // Wait for the 2 refresh cycles to complete, this time because of the refresh request await Task.Delay(TimeSpan.FromSeconds(5)); receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3"); receivedServiceIdentity4 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m4"); // Assert Assert.True(si1().Equals(receivedServiceIdentity1.OrDefault())); Assert.True(si2().Equals(receivedServiceIdentity2.OrDefault())); Assert.False(receivedServiceIdentity3.HasValue); Assert.False(receivedServiceIdentity4.HasValue); Assert.Equal(0, updatedIdentities.Count); Assert.Equal(2, removedIdentities.Count); Assert.True(removedIdentities.Contains("d2/m4")); Assert.True(removedIdentities.Contains("d3")); // Wait for another refresh cycle to complete, this time because timeout await Task.Delay(TimeSpan.FromSeconds(8)); receivedServiceIdentity1 = await deviceScopeIdentitiesCache.GetServiceIdentity("d1"); receivedServiceIdentity2 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m1"); receivedServiceIdentity3 = await deviceScopeIdentitiesCache.GetServiceIdentity("d3"); receivedServiceIdentity4 = await deviceScopeIdentitiesCache.GetServiceIdentity("d2/m4"); // Assert Assert.True(si3().Equals(receivedServiceIdentity3.OrDefault())); Assert.True(si4().Equals(receivedServiceIdentity4.OrDefault())); Assert.False(receivedServiceIdentity1.HasValue); Assert.False(receivedServiceIdentity2.HasValue); Assert.Equal(0, updatedIdentities.Count); Assert.Equal(4, removedIdentities.Count); Assert.True(removedIdentities.Contains("d2/m1")); Assert.True(removedIdentities.Contains("d1")); }