#define TRACE using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Discovery; using System.Xml; using ArchestrAServices.Common; namespace ASBClientAccessLayer; public class ClientAccessUtilities { private Random random = new Random(); public ClientAccessUtilities() { random = new Random(Environment.TickCount); } public EndpointDiscoveryMetadata FindServiceEndpoint(Type ContractType, Uri[] Scopes, out ASBDiscoveryResult1 Result) { Collection scopes = new Collection(Scopes.ToList()); return FindServiceEndpoint(ContractType.Name, scopes, out Result); } public EndpointDiscoveryMetadata FindServiceEndpoint(string ContractTypeName, Collection Scopes, out ASBDiscoveryResult1 Result) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint -- Enter"); Result = ASBDiscoveryResult1.Unknown; string text = SvcUtilities.GetDiscoveryEndpoint(); if (!string.IsNullOrEmpty(text)) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint -- DiscoveryEndPoint {text} method"); if (!text.ToLower().EndsWith("/probe")) { text += "/Probe"; } Uri probeEndpointAddress = new Uri(text); SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint -- calling InternalFindServiceEndpoint() method"); return InternalFindServiceEndpoint(ContractTypeName, Scopes, probeEndpointAddress, out Result); } Result = ASBDiscoveryResult1.DiscoveryNotAvailable; SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint -- Exit"); return null; } private EndpointDiscoveryMetadata InternalFindServiceEndpoint(string ContractName, Collection Scopes, Uri probeEndpointAddress, out ASBDiscoveryResult1 Result) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Warning, 0, $"InternalFindServiceEndpoint() Enter"); if (string.IsNullOrEmpty(ContractName)) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Warning, 0, $"InternalFindServiceEndpoint() Empty contact name"); Result = ASBDiscoveryResult1.DiscoveryBadParameters; return null; } if (probeEndpointAddress == null) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Warning, 0, $"InternalFindServiceEndpoint() probeEndpointAddress is null"); Result = ASBDiscoveryResult1.DiscoveryBadParameters; return null; } SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"InternalFindServiceEndpoint() initializing..."); EndpointAddress endpointAddress = new EndpointAddress(probeEndpointAddress); using (DiscoveryClient discoveryClient = new DiscoveryClient(new DiscoveryEndpoint(SvcUtilities.GetBinding(probeEndpointAddress.ToString()), endpointAddress))) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"InternalFindServiceEndpoint() Creating FindCriteria instance ..."); FindCriteria findCriteria = new FindCriteria(); Result = ASBDiscoveryResult1.Unknown; SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint finding services with interface {ContractName} and {findCriteria.Scopes.Count()} scopes"); try { XmlQualifiedName item = new XmlQualifiedName(ContractName, "http://ArchestrAServices.Contract"); findCriteria.ContractTypeNames.Add(item); foreach (Uri Scope in Scopes) { findCriteria.Scopes.Add(Scope); } SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"FindServiceEndpoint finding services with interface {ContractName} and {findCriteria.Scopes.Count()} scopes"); foreach (Uri scope in findCriteria.Scopes) { SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $" {scope.AbsoluteUri.ToString()}"); } FindResponse findResponse = discoveryClient.Find(findCriteria); if (findResponse != null && findResponse.Endpoints.Count > 0) { Result = ASBDiscoveryResult1.Success; return findResponse.Endpoints[random.Next(findResponse.Endpoints.Count())]; } Result = ASBDiscoveryResult1.DiscoveryReturnedNoEndpoints; } catch (TargetInvocationException) { } catch (UriFormatException) { } SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, $"InternalFindServiceEndpoint() Enter"); } return null; } }