public static List EnvoyInformationForPartition()

in sfintegration/ServiceData.cs [948:1105]


        public static List<EnvoyClustersInformation> EnvoyInformationForPartition(Guid partitionId)
        {
            lock (lock_)
            {
                List<EnvoyClustersInformation> ret = new List<EnvoyClustersInformation>();
                if (partitions_ == null)
                {
                    return ret;
                }

                SF_Partition partition;
                if (!partitions_.TryGetValue(partitionId, out partition))
                {
                    return ret;
                }

                //List<RouteData> ret = new List<RouteData>();
                // stateless - partitionId | endpoint Index | -1
                // stateful - partitionId | endpoint Index | replica Index
                string prefix = partition.serviceName_.AbsolutePath;
                if (!prefix.EndsWith("/"))
                {
                    prefix += "/";
                }
                for (int endpointIndex = 0; endpointIndex < partition.listeners_.Count; endpointIndex++)
                {
                    var ep = partition.listeners_[endpointIndex];
                    List<int> replicaIndexes;
                    bool statefulPartition = false;
                    if (partition.serviceKind_ == ServiceKind.Stateless)
                    {
                        // For stateless, path is same for all replicas so we need to iterate just once
                        replicaIndexes = new List<int>() { 0 };
                    }
                    else
                    {
                        replicaIndexes = new List<int>();
                        replicaIndexes.AddRange(Enumerable.Range(0, ep.InstanceCount()));
                        statefulPartition = true;
                    }
                    JObject endpointHeader = null;
                    if (ep.Name != "")
                    {
                        endpointHeader = new JObject();
                        endpointHeader.Add("name", "ListenerName");
                        endpointHeader.Add("value", ep.Name);
                    }

                    for (int index = 0; index < replicaIndexes.Count; index++)
                    {
                        List<EnvoyRoute> routeData = new List<EnvoyRoute>();
                        List<EnvoyHost> hostData = new List<EnvoyHost>();
                        string cluster = partitionId.ToString() + "|" + endpointIndex.ToString() + "|" + replicaIndexes[index].ToString();
                        string prefix_rewrite = ep.GetAt(index).endpoint_.AbsolutePath;
                        List<JObject> headers = new List<JObject>();
                        if (endpointHeader != null)
                        {
                            headers.Add(endpointHeader);
                        }
                        if (ep.GetAt(index).role_ == ServiceEndpointRole.StatefulSecondary)
                        {
                            JObject statefulSecondaryIndex = new JObject();
                            statefulSecondaryIndex.Add("name", "SecondaryReplicaIndex");
                            statefulSecondaryIndex.Add("value", replicaIndexes[index].ToString());
                            headers.Add(statefulSecondaryIndex);
                        }
                        if (statefulPartition)
                        {
                            hostData.Add(new EnvoyHost(ep.GetAt(index).endpoint_.Host, ep.GetAt(index).endpoint_.Port));
                            var partitionKind = partition.partitionInformation_.Kind;
                            if (partitionKind == ServicePartitionKind.Int64Range)
                            {
                                //if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                                //{
                                //    // Remove once Windows has Envoy 1.6
                                //    continue;
                                //}

                                var rangePartitionInformation = (Int64RangePartitionInformation)partition.partitionInformation_;
                                if (rangePartitionInformation.LowKey == Int64.MinValue &&
                                    rangePartitionInformation.HighKey == Int64.MaxValue)
                                {
                                    routeData.Add(new EnvoyRoute(cluster, prefix, prefix_rewrite, headers, EnvoyDefaults.timeout_ms));
                                }
                                else
                                {
                                    // Envoy - start and end of the range using half-open interval semantics [start, end)
                                    var rangeEnd = rangePartitionInformation.HighKey;
                                    if (rangePartitionInformation.HighKey == Int64.MaxValue)
                                    {
                                        JObject maxValHeader = new JObject();
                                        maxValHeader.Add("name", "PartitionKey");
                                        maxValHeader.Add("value", Int64.MaxValue.ToString());

                                        List<JObject> maxValHeaders = new List<JObject>(headers);
                                        maxValHeaders.Add(maxValHeader);
                                        routeData.Add(new EnvoyRoute(cluster, prefix, prefix_rewrite, maxValHeaders, EnvoyDefaults.timeout_ms));
                                    }
                                    else
                                    {
                                        rangeEnd++;
                                    }
                                    JObject partitionKeyHeader = new JObject();
                                    partitionKeyHeader.Add("name", "PartitionKey");

                                    JObject range_match = new JObject();
                                    range_match.Add("start", rangePartitionInformation.LowKey);
                                    range_match.Add("end", rangeEnd);
                                    partitionKeyHeader.Add("range_match", range_match);

                                    List<JObject> keyHeaders = new List<JObject>(headers);
                                    keyHeaders.Add(partitionKeyHeader);
                                    routeData.Add(new EnvoyRoute(cluster, prefix, prefix_rewrite, keyHeaders, EnvoyDefaults.timeout_ms));
                                }
                            }
                            else if (partitionKind == ServicePartitionKind.Named)
                            {
                                var namedPartitionInformation = (NamedPartitionInformation)partition.partitionInformation_;

                                JObject partitionKeyHeader = new JObject();
                                partitionKeyHeader.Add("name", "PartitionKey");
                                partitionKeyHeader.Add("value", namedPartitionInformation.Name);

                                List<JObject> keyHeaders = new List<JObject>(headers);
                                keyHeaders.Add(partitionKeyHeader);
                                routeData.Add(new EnvoyRoute(cluster, prefix, prefix_rewrite, keyHeaders, EnvoyDefaults.timeout_ms));
                            }
                        }
                        else
                        {
                            // For stateless, capture addresses for all listeners for the one route
                            for (int i = 0; i < ep.InstanceCount(); i++)
                            {
                                var address = ep.GetAt(i);
                                hostData.Add(new EnvoyHost(address.endpoint_.Host, address.endpoint_.Port));
                            }
                            routeData.Add(new EnvoyRoute(cluster, prefix, prefix_rewrite, headers, EnvoyDefaults.timeout_ms));
                        }
                        if (ep.GetAt(index).endpoint_.Scheme == "https")
                        {
                            if (EnvoyDefaults.cluster_ssl_context != null)
                            {
                                ret.Add(new EnvoyClustersInformation(cluster, routeData, hostData, true));
                            }
                            else
                            {
                                // Log information indicating that this end point is skipped
                            }
                        }
                        else
                        {
                            ret.Add(new EnvoyClustersInformation(cluster, routeData, hostData, false));
                        }
                    }
                }
                return ret;
            }
        }