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;
}
}