Exemple #1
0
        private async Task DistributeToService(Service service, InflightMessage message, CancellationToken cancelToken)
        {
            //here we have to identify APIs - ultimately by name but naming is not consistent at the moment

            //single partition only
            var parts = await QueryManager.GetPartitionListAsync(service.ServiceName);

            if (parts.Count == 0 && IsNullOrWhiteSpace(parts.ContinuationToken))
            {
                return;
            }

            if (parts.Count > 1 || !IsNullOrWhiteSpace(parts.ContinuationToken)) //there is more than 1 partition
            {
                return;
            }

            var partition = parts.First();

            cancelToken.ThrowIfCancellationRequested();

            var replicas = await QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id); //stateless service - so no secondary replicas

            if (replicas == null || replicas.Count == 0 || !replicas.All(r =>
                                                                         r.HealthState == HealthState.Ok ||
                                                                         r.HealthState == HealthState.Warning))
            {
                //all considered unhealthy, do not try to ping them even

                _bb?.Publish(GetServiceReplicaAlert(service, "No healthy replica found"));
                return;
            }

            await Task.WhenAll(replicas.Select(r => DistributeToReplica(service, r, message, cancelToken)));
        }
Exemple #2
0
 private async Task DistributeToReplica(Service service, Replica replica, InflightMessage message, CancellationToken cancelToken)
 {
     //find http endpoints
     var endpointObject = JObject.Parse(replica.ReplicaAddress);
     await Task.WhenAll(endpointObject["Endpoints"].ToList()
                        .Where(e => e.First().ToString().StartsWith("http", StringComparison.OrdinalIgnoreCase))           //TODO: do http(s) regexp, I guess
                        .Select(e => DistributeToEndpoint(service, replica, e.First().ToString(), message, cancelToken))); //Select vs First - replica could have multiple endpoints in theory
 }
Exemple #3
0
        public virtual async Task DistributeToCluster(InflightMessage message, CancellationToken cancelToken, string itselfAppName)
        {
            ApplicationList apps;

            do
            {
                cancelToken.ThrowIfCancellationRequested();
                //distribute to apps
                apps = await QueryManager.GetApplicationListAsync();

                await Task.WhenAll(apps.Where(a => !a.ApplicationName.AbsoluteUri.Equals(itselfAppName, StringComparison.OrdinalIgnoreCase)) //do not sent to itself //TODO: debug
                                   .Select(a => DistributeToApp(a, message, cancelToken)));
            } while (!IsNullOrWhiteSpace(apps.ContinuationToken));
        }
Exemple #4
0
        private async Task DistributeToApp(Application application, InflightMessage message, CancellationToken cancelToken)
        {
            ServiceList serviceList;

            do
            {
                cancelToken.ThrowIfCancellationRequested();

                //now distribute to services
                serviceList = await QueryManager.GetServiceListAsync(application.ApplicationName);

                await Task.WhenAll(serviceList.Where(s => s.ServiceKind == ServiceKind.Stateless)
                                   .Select(s => DistributeToService(s, message, cancelToken)));
            } while (!IsNullOrWhiteSpace(serviceList.ContinuationToken));
        }
Exemple #5
0
        private async Task DistributeToEndpoint(Service service, Replica replica, string endpoint, InflightMessage message, CancellationToken cancelToken)
        {
            //TODO: security

            var failureDetected = false;
            var failureReason   = Empty;

            try
            {
                var uriBuilder = new UriBuilder(new Uri(endpoint))
                {
                    Path = Format(CultureInfo.InvariantCulture, MessageIngestUrlFormat,
                                  HttpUtility.UrlEncode(message.Type))
                };

                var resp = await HttpClient.PostAsync(uriBuilder.Uri,
                                                      new StringContent(message.Payload, Encoding.UTF8, "application/json"),
                                                      cancelToken);

                if (!resp.IsSuccessStatusCode && resp.StatusCode != HttpStatusCode.NotFound)
                {
                    failureDetected = true;
                    failureReason   = $"Status Code returned - {resp.StatusCode}";
                }
            }
            catch (Exception e)
            {
                failureDetected = true;
                failureReason   = e.Message;
            }
            finally
            {
                if (failureDetected)
                {
                    _bb?.Publish(GetEndpointFailureMessage(service, replica, endpoint, failureReason));
                }
                else
                {
                    _bb?.Publish(GetEndpointSuccessMessage(service, replica, endpoint));
                }
            }
        }