/// <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; } }
/// <summary> /// Apply activation filter /// </summary> /// <param name="filter"></param> /// <param name="registration"></param> /// <param name="context"></param> /// <param name="ct"></param> /// <returns></returns> private async Task <string> ApplyActivationFilterAsync( EndpointActivationFilterModel filter, EndpointRegistration registration, RegistryOperationContextModel context, CancellationToken ct = default) { if (filter == null || registration == null) { return(null); } // TODO: Get trust list entry and validate endpoint.Certificate var mode = registration.SecurityMode ?? SecurityMode.None; if (!mode.MatchesFilter(filter.SecurityMode ?? SecurityMode.Best)) { return(null); } var policy = registration.SecurityPolicy; if (filter.SecurityPolicies != null) { if (!filter.SecurityPolicies.Any(p => p.EqualsIgnoreCase(registration.SecurityPolicy))) { return(null); } } try { // Ensure device scope for the registration before getting the secret. // Changing device's scope regenerates the secret. await EnsureDeviceScopeForRegistrationAsync(registration, ct); // Get endpoint twin secret var secret = await _iothub.GetPrimaryKeyAsync(registration.DeviceId, null, ct); var endpoint = registration.ToServiceModel(); // Try activate endpoint - if possible... await _activator.ActivateEndpointAsync(endpoint.Registration, secret, ct); // Mark in supervisor await SetSupervisorTwinSecretAsync(registration.SupervisorId, registration.DeviceId, secret, ct); registration.Activated = true; await _broker.NotifyAllAsync( l => l.OnEndpointActivatedAsync(context, endpoint)); return(secret); } catch (Exception ex) { _logger.Information(ex, "Failed activating {eeviceId} based off " + "filter. Manual activation required.", registration.DeviceId); return(null); } }
/// <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; } }