/// <inheritdoc/>
            public async Task ProcessEventsAsync(PartitionContext context,
                                                 IEnumerable <EventData> messages)
            {
                if (messages == null || !messages.Any())
                {
                    return;
                }

                var used = new HashSet <IEventHandler>();

                foreach (var eventData in messages)
                {
                    if (!eventData.Properties.TryGetValue(CommonProperties.kDeviceId,
                                                          out var deviceId) &&
                        !eventData.SystemProperties.TryGetValue(
                            SystemProperties.ConnectionDeviceId, out deviceId))
                    {
                        // Not our content to process
                        continue;
                    }

                    if (!eventData.Properties.TryGetValue(CommonProperties.kContentType,
                                                          out var contentType) &&
                        !eventData.Properties.TryGetValue(EventProperties.kContentType,
                                                          out contentType) &&
                        !eventData.SystemProperties.TryGetValue(
                            SystemProperties.ContentType, out contentType))
                    {
                        // Not our content to process
                        continue;
                    }

                    if (deviceId == null || contentType == null)
                    {
                        // Not our content to process
                        continue;
                    }

                    eventData.Properties.TryGetValue(CommonProperties.kModuleId,
                                                     out var moduleId);
                    if (moduleId == null)
                    {
                        // TODO:  Try get from system properties
                    }

                    if (_factory._handlers.TryGetValue(contentType.ToString().ToLowerInvariant(),
                                                       out var handler))
                    {
                        await handler.HandleAsync(deviceId.ToString(),
                                                  moduleId?.ToString(), eventData.Body.Array,
                                                  () => Try.Async(() => context.CheckpointAsync(eventData)));

                        used.Add(handler);
                    }
                }
                foreach (var handler in used)
                {
                    await Try.Async(handler.OnBatchCompleteAsync);
                }
            }
示例#2
0
 /// <summary>
 /// Process items in queue
 /// </summary>
 /// <returns></returns>
 private async Task WorkAsync()
 {
     while (true)
     {
         if (!Queue.TryTake(out var item, TimeSpan.FromSeconds(20)))
         {
             if (Queue.IsAddingCompleted)
             {
                 return;
             }
             continue;
         }
         try {
             await item.Task().ConfigureAwait(false);
         }
         catch (Exception ex) {
             if (item.Retries == 0)
             {
                 // Give up.
                 _processor._logger.Error("Exception thrown, give up on task!",
                                          () => ex);
                 return;
             }
             _processor._logger.Error($"Processing task failed with exception.",
                                      () => ex);
             item.Retries--;
             _processor.TrySchedule(item);
         }
         await Try.Async(item.Checkpoint);
     }
 }
示例#3
0
        /// <inheritdoc/>
        public async Task UnregisterAsync(EndpointModel endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            var id = new EndpointIdentifier(endpoint);

            _callbacks.TryRemove(id, out _);

            await _lock.WaitAsync();

            try {
                // Remove any session
                if (_clients.TryGetValue(id, out var client))
                {
                    await Try.Async(client.CloseAsync);

                    Try.Op(client.Dispose);

                    _clients.Remove(id);
                    _logger.Debug("Endpoint {id} ({endpoint}) closed.",
                                  id, endpoint.Url);
                }
                else
                {
                    _logger.Debug(
                        "Session for endpoint {id} ({endpoint}) not found.",
                        endpoint.Url, id);
                }
            }
            finally {
                _lock.Release();
            }
        }
示例#4
0
        /// <summary>
        /// Delete all vm resources if possible
        /// </summary>
        /// <returns></returns>
        public async Task TryDeleteStorageAsync(
            IResourceGroupResource resourceGroup, string id)
        {
            var client = await CreateClientAsync(resourceGroup);

            await Try.Async(() => client.StorageAccounts.DeleteByIdAsync(id));
        }
示例#5
0
        /// <inheritdoc/>
        public async Task <TrustGroupRegistrationResultModel> CreateRootAsync(
            TrustGroupRootCreateRequestModel request, CancellationToken ct)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            var result = await _groups.AddAsync(request.ToRegistration(), ct);

            try {
                // Issues new root certificate
                var certificate = await RenewGroupCertificateAsync(result, null, ct);

                _logger.Information("Root {name} {groupId} created.",
                                    request.Name, result.Id);
                return(new TrustGroupRegistrationResultModel {
                    Id = result.Id
                });
            }
            catch {
                // Attempt to remove group
                await Try.Async(() => _groups.DeleteAsync(result.Id, r => true));

                throw;
            }
        }
示例#6
0
        /// <summary>
        /// Browse all references
        /// </summary>
        private static async Task <BrowseResponseApiModel> NodeBrowseAsync(
            ITwinServiceApi service, string endpoint, BrowseRequestApiModel request)
        {
            while (true)
            {
                var result = await service.NodeBrowseFirstAsync(endpoint, request);

                while (result.ContinuationToken != null)
                {
                    try {
                        var next = await service.NodeBrowseNextAsync(endpoint,
                                                                     new BrowseNextRequestApiModel {
                            ContinuationToken  = result.ContinuationToken,
                            Header             = request.Header,
                            ReadVariableValues = request.ReadVariableValues,
                            TargetNodesOnly    = request.TargetNodesOnly
                        });

                        result.References.AddRange(next.References);
                        result.ContinuationToken = next.ContinuationToken;
                    }
                    catch (Exception) {
                        await Try.Async(() => service.NodeBrowseNextAsync(endpoint,
                                                                          new BrowseNextRequestApiModel {
                            ContinuationToken = result.ContinuationToken,
                            Abort             = true
                        }));

                        throw;
                    }
                }
                return(result);
            }
        }
        /// <summary>
        /// Delete all vm resources if possible
        /// </summary>
        /// <returns></returns>
        public async Task TryDeleteServiceBusAsync(
            IResourceGroupResource resourceGroup, string id)
        {
            var client = await CreateClientAsync(resourceGroup);

            await Try.Async(() => client.ServiceBusNamespaces.DeleteByIdAsync(id));
        }
        /// <summary>
        /// Delete all requests for the given entity
        /// </summary>
        /// <param name="entityId"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task RemoveAllRequestsForEntity(string entityId,
                                                      RegistryOperationContextModel context)
        {
            string nextPageLink = null;
            var    result       = await _requests.QueryRequestsAsync(
                new CertificateRequestQueryRequestModel {
                EntityId = entityId
            });

            while (true)
            {
                nextPageLink = result.NextPageLink;
                foreach (var request in result.Requests)
                {
                    if (request.State != CertificateRequestState.Accepted)
                    {
                        await Try.Async(() => _requests.AcceptRequestAsync(
                                            request.RequestId, new VaultOperationContextModel {
                            AuthorityId = context?.AuthorityId,
                            Time        = context?.Time ?? DateTime.UtcNow
                        }));
                    }
                }
                if (result.NextPageLink == null)
                {
                    break;
                }
                result = await _requests.ListRequestsAsync(result.NextPageLink);
            }
        }
示例#9
0
        /// <inheritdoc/>
        public async Task <KeyHandle> GetKeyHandleAsync(string name, CancellationToken ct)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            // Get key first
            var keyBundle = await Try.Async(() => _keyVaultClient.GetKeyAsync(name, ct));

            if (keyBundle == null)
            {
                // If no key - then try getting cert bundle instead
                var certBundle = await Try.Async(
                    () => _keyVaultClient.GetCertificateAsync(_vaultBaseUrl, name, ct));

                if (certBundle != null)
                {
                    return(KeyVaultKeyHandle.Create(certBundle));
                }
                throw new ResourceNotFoundException("Key with name not found");
            }
            var secretBundle = await Try.Async(() => _keyVaultClient.GetSecretAsync(name, ct));

            return(KeyVaultKeyHandle.Create(keyBundle, secretBundle));
        }
            /// <inheritdoc/>
            public async Task ProcessEventsAsync(PartitionContext context,
                                                 IEnumerable <EventData> messages)
            {
                if (messages == null || !messages.Any())
                {
                    return;
                }
                foreach (var eventData in messages)
                {
                    if (_outer._config.SkipEventsOlderThan != null &&
                        eventData.SystemProperties.TryGetValue("x-opt-enqueued-time", out var enqueued) &&
                        (DateTime)enqueued + _outer._config.SkipEventsOlderThan < DateTime.UtcNow)
                    {
                        continue;
                    }

                    var properties = new EventProperties(eventData.SystemProperties,
                                                         eventData.Properties);
                    if (eventData.Body.Array == null)
                    {
                        _logger.Verbose("WARNING: Received empty message with properties {@properties}",
                                        properties);
                        continue;
                    }
                    await _handler.HandleAsync(eventData.Body.Array, properties,
                                               () => CheckpointAsync(context, eventData));

                    if (context.CancellationToken.IsCancellationRequested)
                    {
                        // Checkpoint to the last processed event.
                        await CheckpointAsync(context, eventData);

                        context.CancellationToken.ThrowIfCancellationRequested();
                    }
                }

                // Checkpoint if needed
                if (_sw.ElapsedMilliseconds >= _interval)
                {
                    try {
                        _logger.Debug("Checkpointing EventProcessor {id} for partition {partitionId}...",
                                      _processorId, context.PartitionId);
                        await context.CheckpointAsync();

                        _sw.Restart();
                    }
                    catch (Exception ex) {
                        _logger.Warning(ex, "Failed checkpointing EventProcessor {id} for partition {partitionId}...",
                                        _processorId, context.PartitionId);
                        kEventProcessorDetails.WithLabels(_processorId, context.PartitionId, "checkpoint_failed").Inc();
                        if (_sw.ElapsedMilliseconds >= 2 * _interval)
                        {
                            // Give up checkpointing after trying a couple more times
                            _sw.Restart();
                        }
                    }
                }
                await Try.Async(_handler.OnBatchCompleteAsync);
            }
示例#11
0
        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            Try.Async(StopAsync).Wait();

            // Dispose
            _cts.Dispose();
            _lock.Dispose();
        }
示例#12
0
 /// <inheritdoc/>
 public async Task OnBatchCompleteAsync()
 {
     foreach (var handler in _used.ToList())
     {
         await Try.Async(handler.OnBatchCompleteAsync);
     }
     _used.Clear();
 }
示例#13
0
 /// <inheritdoc/>
 public async Task OnBatchCompleteAsync()
 {
     foreach (var handler in _used)
     {
         await Try.Async(_handlers[handler].OnBatchCompleteAsync);
     }
     _used.Clear();
 }
示例#14
0
        /// <summary>
        /// Get or add crl to cache database
        /// </summary>
        /// <param name="serialNumber"></param>
        /// <param name="validatyPeriod"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task <CrlDocument> TryGetOrAddCrlAsync(SerialNumber serialNumber,
                                                            TimeSpan validatyPeriod, CancellationToken ct)
        {
            while (true)
            {
                var crl = await _crls.FindAsync <CrlDocument>(serialNumber.ToString(), ct);

                if (crl != null &&
                    crl.Value.NextUpdate > (DateTime.UtcNow - validatyPeriod))
                {
                    return(crl.Value);
                }

                // Find issuer certificate.
                var issuer = await _certificates.FindCertificateAsync(serialNumber.Value, ct);

                if (issuer?.IssuerPolicies == null || issuer.Revoked != null)
                {
                    if (crl != null)
                    {
                        // Get rid of crl
                        await Try.Async(() => _crls.DeleteAsync(crl, ct));
                    }
                    if (issuer == null)
                    {
                        return(null);  // Unknown certificate
                    }
                    // Not an issuer cert
                    return(new CrlDocument {
                        IssuerSerialNumber = issuer.GetIssuerSerialNumberAsString(),
                        SerialNumber = issuer.GetSerialNumberAsString(),
                    });
                }

                // Get all revoked but still valid certificates issued by issuer
                var revoked = await _certificates.GetIssuedCertificatesAsync(
                    issuer, null, true, true, ct);

                System.Diagnostics.Debug.Assert(revoked.All(r => r.Revoked != null));

                // Build crl

                var result = await _factory.CreateCrlAsync(issuer,
                                                           issuer.IssuerPolicies.SignatureType.Value, revoked, null, ct);

                var document = result.ToDocument(
                    issuer.GetSerialNumberAsString(), issuer.GetIssuerSerialNumberAsString());
                try {
                    // Add crl
                    crl = await _crls.UpsertAsync(document, ct, null, null, crl?.Etag);

                    return(crl.Value);
                }
                catch (ResourceOutOfDateException) {
                    continue;
                }
            }
        }
示例#15
0
        /// <inheritdoc/>
        public void Dispose()
        {
            Try.Async(StopDiscoveryRequestProcessingAsync).Wait();

            // Dispose
            _cts.Dispose();
            _timer.Dispose();
            _lock.Dispose();
        }
        /// <summary>
        /// Close connection
        /// </summary>
        /// <returns></returns>
        private async Task DisposeAsync(HubConnection connection)
        {
            if (connection == null)
            {
                return;
            }
            await Try.Async(() => connection?.StopAsync());

            await Try.Async(() => connection?.DisposeAsync());
        }
示例#17
0
        /// <inheritdoc/>
        public void Dispose()
        {
            Try.Async(StopAsync).Wait();
            System.Diagnostics.Debug.Assert(_jobProcess == null);
            _jobProcess?.Dispose();

            _cts?.Dispose();
            _heartbeatTimer.Dispose();
            _lock.Dispose();
        }
        /// <inheritdoc/>
        public async Task <FinishNewKeyPairRequestResultModel> FinishNewKeyPairRequestAsync(
            string requestId, VaultOperationContextModel context, CancellationToken ct)
        {
            if (string.IsNullOrEmpty(requestId))
            {
                throw new ArgumentNullException(nameof(requestId));
            }
            var request = await _repo.FindAsync(requestId, ct);

            if (request == null)
            {
                throw new ResourceNotFoundException("Request not found");
            }
            try {
                var entity = await _entities.FindEntityAsync(request.Entity.Id);

                if (entity != null)
                {
                    throw new ResourceInvalidStateException("Entity removed.");
                }
                var result = new FinishNewKeyPairRequestResultModel {
                    Request = request.Record
                };
                if (request.Record.State == CertificateRequestState.Completed)
                {
                    result.Certificate = request.Certificate;
                    // get private key
                    if (request.KeyHandle != null)
                    {
                        var handle = Try.Op(
                            () => _serializer.DeserializeHandle(request.KeyHandle));
                        if (handle != null)
                        {
                            var privateKey = await Try.Async(
                                () => _keys.ExportKeyAsync(handle, ct));

                            result.PrivateKey = privateKey.ToServiceModel();
                            await Try.Async(
                                () => _keys.DeleteKeyAsync(handle, ct));
                        }
                    }
                }
                return(result);
            }
            finally {
                if (request.Record.State == CertificateRequestState.Completed)
                {
                    // Accept
                    await _broker.NotifyAllAsync(
                        l => l.OnCertificateRequestAcceptedAsync(request));

                    _logger.Information("Key pair response accepted and finished.");
                }
            }
        }
        /// <summary>
        /// Unregister all applications and endpoints
        /// </summary>
        /// <param name="service"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public static async Task UnregisterAllApplicationsAsync(
            this IApplicationRegistry service, CancellationToken ct = default)
        {
            var apps = await service.ListAllApplicationsAsync(ct);

            foreach (var app in apps)
            {
                await Try.Async(() => service.UnregisterApplicationAsync(
                                    app.ApplicationId, null, ct));
            }
        }
        /// <inheritdoc/>
        public async Task HandleAsync(string deviceId, string moduleId, byte[] payload,
                                      IDictionary <string, string> properties, Func <Task> checkpoint)
        {
            var completed = await HandleEventAsync(deviceId, moduleId,
                                                   payload, properties);

            if (completed)
            {
                await Try.Async(() => checkpoint?.Invoke());
            }
        }
示例#21
0
        /// <inheritdoc/>
        public async Task <Certificate> NewIssuerCertificateAsync(string rootCertificate,
                                                                  string certificateName, X500DistinguishedName subjectName, DateTime?notBefore,
                                                                  CreateKeyParams keyParams, IssuerPolicies policies,
                                                                  Func <byte[], IEnumerable <X509Extension> > extensions,
                                                                  CancellationToken ct)
        {
            if (string.IsNullOrEmpty(certificateName))
            {
                throw new ArgumentNullException(nameof(certificateName));
            }

            // Get CA certificate
            var caCertificate = await _store.GetLatestCertificateAsync(rootCertificate, ct);

            if (caCertificate.IssuerPolicies == null)
            {
                throw new ArgumentException("root certificate is not an issuer");
            }

            // Validate policies
            policies = policies.Validate(caCertificate.IssuerPolicies, keyParams);

            // Create new key
            var keyHandle = await _keys.CreateKeyAsync(Guid.NewGuid().ToString(),
                                                       keyParams, new KeyStoreProperties {
                Exportable = false
            }, ct);

            try {
                // Get public key for the key
                var publicKey = await _keys.GetPublicKeyAsync(keyHandle, ct);

                var signedcert = await _factory.CreateCertificateAsync(_keys, caCertificate,
                                                                       subjectName, publicKey,
                                                                       GetNotAfter(notBefore, caCertificate.IssuerPolicies.IssuedLifetime.Value,
                                                                                   caCertificate.NotAfterUtc, out var notAfter),
                                                                       notAfter,
                                                                       caCertificate.IssuerPolicies.SignatureType.Value, true, extensions, ct);

                using (signedcert) {
                    // Import new issued certificate
                    var result = signedcert.ToCertificate(policies, keyHandle);
                    await _repo.AddCertificateAsync(certificateName, result, null, ct);

                    return(result);
                }
            }
            catch (Exception ex) {
                _logger.Verbose(ex, "Failed to add certificate, delete key");
                await Try.Async(() => _keys.DeleteKeyAsync(keyHandle, ct));

                throw;
            }
        }
 /// <inheritdoc/>
 public void Dispose()
 {
     if (_ensureWorkerRunningTimer != null)
     {
         _ensureWorkerRunningTimer.Enabled  = false;
         _ensureWorkerRunningTimer.Elapsed -= EnsureWorkerRunningTimer_ElapsedAsync;
         _ensureWorkerRunningTimer.Dispose();
         _ensureWorkerRunningTimer = null;
     }
     Try.Async(StopAsync).GetAwaiter().GetResult();
 }
        /// <summary>
        /// Unregister all applications and endpoints
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public static async Task UnregisterAllApplicationsAsync(
            this IApplicationRegistry service)
        {
            var apps = await service.ListAllApplicationsAsync();

            foreach (var app in apps)
            {
                await Try.Async(() => service.UnregisterApplicationAsync(
                                    app.ApplicationId));
            }
        }
        /// <summary>
        /// Delete all vm resources if possible
        /// </summary>
        /// <returns></returns>
        public async Task TryDeleteResourcesAsync(
            IResourceGroupResource resourceGroup, string id)
        {
            var client = await CreateClientAsync(resourceGroup);

            await Try.Async(() => client.VirtualMachines.DeleteByIdAsync(id));

            await Try.Async(() => client.Networks.DeleteByIdAsync(id));

            await Try.Async(() => client.PublicIPAddresses.DeleteByIdAsync(id));
        }
        /// <summary>
        /// Get or create new vm in a resource group.
        /// </summary>
        /// <param name="service"></param>
        /// <param name="resourceGroup"></param>
        /// <param name="name"></param>
        /// <param name="network"></param>
        /// <param name="image"></param>
        /// <returns></returns>
        public static async Task <IVirtualMachineResource> GetOrCreateAsync(
            this IVirtualMachineFactory service, IResourceGroupResource resourceGroup,
            string name, INetworkResource network = null, VirtualMachineImage image = null)
        {
            var resource = await Try.Async(() => service.GetAsync(resourceGroup, name));

            if (resource == null)
            {
                resource = await service.CreateAsync(resourceGroup, name, network, image, null);
            }
            return(resource);
        }
 /// <inheritdoc/>
 public async Task OnCertificateRequestApprovedAsync(CertificateRequestModel request)
 {
     try {
         if (request.Record.Type == CertificateRequestType.KeyPairRequest)
         {
             await CreateNewKeyPairAsync(request);
         }
     }
     catch (Exception ex) {
         await Try.Async(() => _workflow.FailRequestAsync(request.Record.RequestId, ex));
     }
 }
示例#27
0
        /// <inheritdoc/>
        public void Dispose()
        {
            Try.Async(StopAsync).Wait();

            _updateTimer.Dispose();

            // _cts might be null if StartAsync() was never called.
            if (!(_cts is null))
            {
                _cts.Dispose();
            }
        }
示例#28
0
 /// <inheritdoc/>
 public async Task OnCertificateRequestApprovedAsync(CertificateRequestModel request)
 {
     try {
         if (request.Record.Type == CertificateRequestType.SigningRequest)
         {
             await ProcessSigningRequestAsync(request);
         }
     }
     catch (Exception ex) {
         await Try.Async(() => _workflow.FailRequestAsync(request.Record.RequestId, ex));
     }
 }
        /// <summary>
        /// Get or create new storage in a resource group.
        /// </summary>
        /// <param name="service"></param>
        /// <param name="resourceGroup"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static async Task <IStorageResource> GetOrCreateAsync(
            this IStorageFactory service, IResourceGroupResource resourceGroup,
            string name)
        {
            var resource = await Try.Async(() => service.GetAsync(resourceGroup,
                                                                  name));

            if (resource == null)
            {
                resource = await service.CreateAsync(resourceGroup, name);
            }
            return(resource);
        }
        /// <summary>
        /// Get or create new storage in a resource group.
        /// </summary>
        /// <param name="service"></param>
        /// <param name="resourceGroup"></param>
        /// <param name="name"></param>
        /// <param name="addressSpace"></param>
        /// <param name="secure"></param>
        /// <returns></returns>
        public static async Task <INetworkResource> GetOrCreateAsync(
            this INetworkFactory service, IResourceGroupResource resourceGroup,
            string name, string addressSpace = null, bool secure = false)
        {
            var resource = await Try.Async(() => service.GetAsync(resourceGroup,
                                                                  name));

            if (resource == null)
            {
                resource = await service.CreateAsync(resourceGroup, name,
                                                     addressSpace, secure);
            }
            return(resource);
        }