/// <summary> /// Gets the endpoint from the array of endpoints using the listener name. /// </summary> /// <param name="rse">ResolvedServiceEndpoint instance.</param> /// <param name="name">Listener name.</param> /// <returns>String containing the replica address.</returns> /// <exception cref="ArgumentException">ResolvedServiceEndpoint address list coudln't be parsed.</exception> /// <exception cref="InvalidProgramException">ResolvedServiceEndpoint address list coudln't be parsed.</exception> public static string GetEndpoint(this ResolvedServiceEndpoint rse, string name) { ServiceEndpointCollection sec = null; if (ServiceEndpointCollection.TryParseEndpointsString(rse.Address, out sec)) { string replicaAddress; if (sec.TryGetEndpointAddress(name, out replicaAddress)) { return(replicaAddress); } else { throw new ArgumentException(nameof(name)); } } else { throw new InvalidProgramException("ResolvedServiceEndpoint had invalid address"); } }
/// <summary> /// Selects and endpoint (aka "listener") from a presented <paramref name="endpoints"/> collection /// that satisfies all constraints of <paramref name="fabricServiceEndpoint"/>. /// </summary> /// <param name="fabricServiceEndpoint">User-defined info and constraints for the selecting an endpoint from <paramref name="fabricServiceEndpoint"/>.</param> /// <param name="endpoints">Collection of endpoints to choose from.</param> /// <param name="endpointUri">The endpoint URI to extract.</param> /// <returns>Boolean indicating whether an endpoint URI was successfully retrieved.</returns> public static bool TryGetEndpoint( FabricServiceEndpoint fabricServiceEndpoint, ServiceEndpointCollection endpoints, out Uri endpointUri) { _ = fabricServiceEndpoint ?? throw new ArgumentNullException(nameof(fabricServiceEndpoint)); _ = endpoints ?? throw new ArgumentNullException(nameof(endpoints)); endpointUri = null; string endpointAddress = null; foreach (var listenerName in fabricServiceEndpoint.ListenerNames) { // SF Reverse Proxy endpoint selection logic: https://msazure.visualstudio.com/One/_git/WindowsFabric?path=%2Fsrc%2Fprod%2Fsrc%2FManagement%2FApplicationGateway%2FHttp%2FServiceEndpointsList.cpp&version=GBrelease_6.5&line=52&lineStyle=plain&lineEnd=53&lineStartColumn=1&lineEndColumn=1 if (listenerName == string.Empty && fabricServiceEndpoint.EmptyStringMatchesAnyListener) { endpointUri = endpoints.ToReadOnlyDictionary() // NOTE: Ordinal comparison used to match sort order of Service Fabric Reverse Proxy .OrderBy(listenerAddressPair => listenerAddressPair.Key, StringComparer.Ordinal) // From the endpoints above, select endpoints with valid URIs .Select(listenerAddressPair => { if (Uri.TryCreate(listenerAddressPair.Value, UriKind.Absolute, out var uri)) { return(uri); } return(null); }) .Where(replicaAddress => replicaAddress != null) // Pick first endpoint that matches scheme predicate. .FirstOrDefault(replicaAddress => { if (fabricServiceEndpoint.AllowedSchemePredicate(replicaAddress.Scheme)) { return(true); } return(false); }); // Bail as soon as first valid endpoint is found. if (endpointUri != null) { // CoreFrameworkFabricTrace.Instance.TraceVerbose("Located endpoint URI is '{0}'", endpointUri); return(true); } } else { // Pick named listener endpoint if (endpoints.TryGetEndpointAddress(listenerName: listenerName, endpointAddress: out endpointAddress)) { if (!Uri.TryCreate(endpointAddress, UriKind.Absolute, out var endpointUri_)) { continue; } // Match the Uri against allowed scheme predicate. if (!fabricServiceEndpoint.AllowedSchemePredicate(endpointUri_.Scheme)) { continue; } endpointUri = endpointUri_; // CoreFrameworkFabricTrace.Instance.TraceVerbose("Located endpoint URI is '{0}'", endpointUri); return(true); } } } return(false); }
/// <summary> /// Selects and endpoint (aka "listener") from a presented <paramref name="endpoints"/> collection /// that satisfies all constraints of <paramref name="fabricServiceEndpoint"/>. /// </summary> /// <param name="fabricServiceEndpoint">User-defined info and constraints for the selecting an endpoint from <paramref name="fabricServiceEndpoint"/>.</param> /// <param name="endpoints">Collection of endpoints to choose from.</param> /// <param name="endpointUri">The endpoint URI to extract.</param> /// <returns>Boolean indicating whether an endpoint URI was successfully retrieved.</returns> public static bool TryGetEndpoint( FabricServiceEndpoint fabricServiceEndpoint, ServiceEndpointCollection endpoints, out Uri endpointUri) { _ = fabricServiceEndpoint ?? throw new ArgumentNullException(nameof(fabricServiceEndpoint)); _ = endpoints ?? throw new ArgumentNullException(nameof(endpoints)); endpointUri = null; string endpointAddress = null; foreach (var listenerName in fabricServiceEndpoint.ListenerNames) { // SF Reverse Proxy endpoint selection logic: https://github.com/microsoft/service-fabric/blob/1e118f02294c99b61e676c07ac97283ee12197d4/src/prod/src/Management/ApplicationGateway/Http/ServiceEndpointsList.cpp#L52 if (listenerName == string.Empty && fabricServiceEndpoint.EmptyStringMatchesAnyListener) { endpointUri = endpoints.ToReadOnlyDictionary() // NOTE: Ordinal comparison used to match sort order of Service Fabric Reverse Proxy .OrderBy(listenerAddressPair => listenerAddressPair.Key, StringComparer.Ordinal) // From the endpoints above, select endpoints with valid URIs .Select(listenerAddressPair => { if (Uri.TryCreate(listenerAddressPair.Value, UriKind.Absolute, out var uri)) { return(uri); } return(null); }) .Where(replicaAddress => replicaAddress != null) // Pick first endpoint that matches scheme predicate. .FirstOrDefault(replicaAddress => { if (fabricServiceEndpoint.AllowedSchemePredicate(replicaAddress.Scheme)) { return(true); } return(false); }); // Bail as soon as first valid endpoint is found. if (endpointUri != null) { // CoreFrameworkFabricTrace.Instance.TraceVerbose("Located endpoint URI is '{0}'", endpointUri); return(true); } } else { // Pick named listener endpoint if (endpoints.TryGetEndpointAddress(listenerName: listenerName, endpointAddress: out endpointAddress)) { if (!Uri.TryCreate(endpointAddress, UriKind.Absolute, out var endpointUri_)) { continue; } // Match the Uri against allowed scheme predicate. if (!fabricServiceEndpoint.AllowedSchemePredicate(endpointUri_.Scheme)) { continue; } endpointUri = endpointUri_; // CoreFrameworkFabricTrace.Instance.TraceVerbose("Located endpoint URI is '{0}'", endpointUri); return(true); } } } return(false); }