/// <summary> /// Deactivate /// </summary> /// <param name="registration"></param> /// <param name="context"></param> /// <param name="ct"></param> /// <returns></returns> private async Task DeactivateAsync(EndpointRegistration registration, RegistryOperationContextModel context, CancellationToken ct = default) { var endpoint = registration.ToServiceModel(); // Deactivate twin in twin settings - do no matter what await ClearSupervisorTwinSecretAsync(registration.DeviceId, registration.SupervisorId, ct); // Call down to supervisor to ensure deactivation is complete - do no matter what await Try.Async(() => _activator.DeactivateEndpointAsync(endpoint.Registration)); try { // Mark as deactivated if (registration.Activated ?? false) { var patch = endpoint.ToEndpointRegistration( _serializer, registration.IsDisabled); // Mark as deactivated patch.Activated = false; await _iothub.PatchAsync(registration.Patch(patch, _serializer), true); } await _broker.NotifyAllAsync(l => l.OnEndpointDeactivatedAsync(context, endpoint)); } catch (Exception ex) { _logger.Error(ex, "Failed to deactivate twin"); throw; } }
public async Task TestActivateDeactivateEndpoint20Times() { using (var harness = new TwinModuleFixture()) { await harness.RunTestAsync(async (device, module, services) => { // Setup var supervisorId = SupervisorModelEx.CreateSupervisorId(device, module); var activation = services.Resolve<IActivationServices<EndpointRegistrationModel>>(); var hub = services.Resolve<IIoTHubTwinServices>(); var twin = EndpointRegistration.Patch(null, EndpointRegistration.FromServiceModel(new EndpointInfoModel { Registration = new EndpointRegistrationModel { Endpoint = new EndpointModel { Url = "opc.tcp://test" }, SupervisorId = supervisorId }, ApplicationId = "ua326029342304923" })); await hub.CreateOrUpdateAsync(twin); var registry = services.Resolve<IEndpointRegistry>(); var endpoints = await registry.ListAllEndpointsAsync(); var ep1 = endpoints.FirstOrDefault(); Assert.NotNull(ep1); for (var i = 0; i < 20; i++) { // Act await registry.ActivateEndpointAsync(ep1.Registration.Id); await registry.DeactivateEndpointAsync(ep1.Registration.Id); } var diagnostics = services.Resolve<ISupervisorDiagnostics>(); endpoints = await registry.ListAllEndpointsAsync(); var ep3 = endpoints.FirstOrDefault(); var status = await diagnostics.GetSupervisorStatusAsync(supervisorId); // Assert Assert.Equal(device, status.DeviceId); Assert.Equal(module, status.ModuleId); Assert.Null(status.SiteId); Assert.Empty(status.Endpoints); Assert.Equal(EndpointActivationState.Deactivated, ep3.ActivationState); Assert.Null(ep3.EndpointState); }); } }
/// <summary> /// Activate /// </summary> /// <param name="registration"></param> /// <param name="context"></param> /// <param name="ct"></param> /// <returns></returns> private async Task ActivateAsync(EndpointRegistration registration, RegistryOperationContextModel context, CancellationToken ct = default) { // Ensure device scope for the registration before getting the secret. // Changing device's scope regenerates the secret. await EnsureDeviceScopeForRegistrationAsync(registration, ct); // Update supervisor settings var secret = await _iothub.GetPrimaryKeyAsync(registration.DeviceId, null, ct); var endpoint = registration.ToServiceModel(); try { // Call down to supervisor to activate - this can fail await _activator.ActivateEndpointAsync(endpoint.Registration, secret, ct); // Update supervisor desired properties await SetSupervisorTwinSecretAsync(registration.SupervisorId, registration.DeviceId, secret, ct); if (!(registration.Activated ?? false)) { // Update twin activation status in twin settings var patch = endpoint.ToEndpointRegistration(_serializer, registration.IsDisabled); patch.Activated = true; // Mark registration as activated await _iothub.PatchAsync(registration.Patch(patch, _serializer), true, ct); } await _broker.NotifyAllAsync(l => l.OnEndpointActivatedAsync(context, endpoint)); } catch (Exception ex) { // Undo activation await Try.Async(() => _activator.DeactivateEndpointAsync( endpoint.Registration)); await Try.Async(() => ClearSupervisorTwinSecretAsync( registration.DeviceId, registration.SupervisorId)); _logger.Error(ex, "Failed to activate twin"); throw; } }
public async Task TestActivateDeactivate20Endpoints5TimesMultiThreaded() { using (var harness = new TwinModuleFixture()) { await harness.RunTestAsync(async (device, module, services) => { // Setup var supervisorId = SupervisorModelEx.CreateSupervisorId(device, module); var activation = services.Resolve<IActivationServices<EndpointRegistrationModel>>(); var hub = services.Resolve<IIoTHubTwinServices>(); for (var i = 0; i < 20; i++) { var twin = EndpointRegistration.Patch(null, EndpointRegistration.FromServiceModel(new EndpointInfoModel { Registration = new EndpointRegistrationModel { Endpoint = new EndpointModel { Url = "opc.tcp://test" }, SupervisorId = supervisorId }, ApplicationId = "uas" + i })); await hub.CreateOrUpdateAsync(twin); } var registry = services.Resolve<IEndpointRegistry>(); var endpoints = await registry.ListAllEndpointsAsync(); for (var i = 0; i < 5; i++) { await Task.WhenAll(endpoints.Select(ep => registry.ActivateEndpointAsync(ep.Registration.Id))); await Task.WhenAll(endpoints.Select(ep => registry.DeactivateEndpointAsync(ep.Registration.Id))); } var diagnostics = services.Resolve<ISupervisorDiagnostics>(); endpoints = await registry.ListAllEndpointsAsync(); var status = await diagnostics.GetSupervisorStatusAsync(supervisorId); // Assert Assert.Equal(device, status.DeviceId); Assert.Equal(module, status.ModuleId); Assert.Null(status.SiteId); Assert.Empty(status.Endpoints); Assert.True(endpoints.All(ep => ep.ActivationState == EndpointActivationState.Deactivated)); Assert.True(endpoints.All(ep => ep.EndpointState == null)); }); } }
/// <summary> /// Activate /// </summary> /// <param name="endpoint"></param> /// <returns></returns> public EndpointRegistrationModel RegisterAndActivateTwinId(EndpointRegistrationModel endpoint) { var twin = EndpointRegistration.Patch(null, EndpointRegistration.FromServiceModel( new EndpointInfoModel { Registration = endpoint, ApplicationId = "uas" + Guid.NewGuid().ToString() })); var result = _hub.CreateOrUpdateAsync(twin).Result; var registry = HubContainer.Resolve <IEndpointRegistry>(); var endpoints = registry.ListAllEndpointsAsync().Result; var ep1 = endpoints.FirstOrDefault(); if (ep1.ActivationState == EndpointActivationState.Deactivated) { // Activate registry.ActivateEndpointAsync(ep1.Registration.Id).Wait(); } return(ep1.Registration); }
/// <summary> /// Helper to create fixtures /// </summary> /// <param name="site"></param> /// <param name="super"></param> /// <param name="existing"></param> /// <param name="found"></param> /// <param name="registry"></param> /// <param name="countDevices"></param> /// <param name="fixup"></param> /// <param name="disable"></param> private static void CreateFixtures(out string site, out string super, out List <ApplicationRegistrationModel> existing, out List <DiscoveryEventModel> found, out IoTHubServices registry, int countDevices = -1, Func <ApplicationRegistrationModel, ApplicationRegistrationModel> fixup = null, bool disable = false) { var fix = new Fixture(); // Create template applications and endpoints fix.Customizations.Add(new TypeRelay(typeof(JToken), typeof(JObject))); var sitex = site = fix.Create <string>(); var module = fix.Create <string>(); var device = fix.Create <string>(); var superx = super = SupervisorModelEx.CreateSupervisorId(device, module); var supervisor = ( SupervisorRegistration.Patch(null, SupervisorRegistration.FromServiceModel(new SupervisorModel { SiteId = site, Id = superx })), new DeviceModel { Id = device, ModuleId = module }); var template = fix .Build <ApplicationRegistrationModel>() .Without(x => x.Application) .Do(c => c.Application = fix .Build <ApplicationInfoModel>() .Without(x => x.NotSeenSince) .With(x => x.SiteId, sitex) .With(x => x.SupervisorId, superx) .Create()) .Without(x => x.Endpoints) .Do(c => c.Endpoints = fix .Build <EndpointRegistrationModel>() .With(x => x.SiteId, sitex) .With(x => x.SupervisorId, superx) .CreateMany(5) .ToList()) .CreateMany(5) .ToList(); template.ForEach(a => a.Application.ApplicationId = ApplicationInfoModelEx.CreateApplicationId(a.Application) ); // Create discovery results from template var i = 0; var now = DateTime.UtcNow; found = template .SelectMany(a => a.Endpoints.Select( e => new DiscoveryEventModel { Application = a.Application, Registration = e, Index = i++, TimeStamp = now })) .ToList(); // Clone and fixup existing applications as per test case existing = template .Select(e => e.Clone()) .Select(fixup ?? (a => a)) .ToList(); // and fill registry with them... var appdevices = existing .Select(a => ApplicationRegistration.FromServiceModel(a.Application, disable)) .Select(a => ApplicationRegistration.Patch(null, a)) .Select(d => (d, new DeviceModel { Id = d.Id })); var epdevices = existing .SelectMany(a => a.Endpoints .Select(e => EndpointRegistration.FromServiceModel( new EndpointInfoModel { ApplicationId = a.Application.ApplicationId, Registration = e }, disable))) .Select(e => EndpointRegistration.Patch(null, e)) .Select(d => (d, new DeviceModel { Id = d.Id })); appdevices = appdevices.Concat(epdevices); if (countDevices != -1) { appdevices = appdevices.Take(countDevices); } registry = new IoTHubServices(appdevices.Concat(supervisor.YieldReturn())); }