Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.ServiceModel.Discovery / System / ServiceModel / Discovery / DiscoveryService.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4
5 namespace System.ServiceModel.Discovery
6 {
7     using System.Runtime;
8     using System.ServiceModel;
9     using System.ServiceModel.Discovery.Version11;
10     using System.ServiceModel.Discovery.VersionApril2005;
11     using System.ServiceModel.Discovery.VersionCD1;
12     using System.Xml;
13     using System.Globalization;
14     using System.Runtime.Diagnostics;
15     using System.ServiceModel.Diagnostics;
16
17     [Fx.Tag.XamlVisible(false)]
18     public abstract class DiscoveryService :
19         IDiscoveryContractAdhocApril2005,
20         IDiscoveryContractManagedApril2005,
21         IDiscoveryContractAdhoc11,
22         IDiscoveryContractManaged11,
23         IDiscoveryContractAdhocCD1,
24         IDiscoveryContractManagedCD1,
25         IDiscoveryServiceImplementation
26     {
27         DiscoveryMessageSequenceGenerator messageSequenceGenerator;
28         DuplicateDetector<UniqueId> duplicateDetector;
29
30         protected DiscoveryService()
31             : this(new DiscoveryMessageSequenceGenerator())
32         {
33         }
34
35         protected DiscoveryService(DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator)
36             : this(discoveryMessageSequenceGenerator, DiscoveryDefaults.DuplicateMessageHistoryLength)
37         {
38         }
39
40         protected DiscoveryService(
41             DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator,
42             int duplicateMessageHistoryLength)
43         {
44             if (discoveryMessageSequenceGenerator == null)
45             {
46                 throw FxTrace.Exception.ArgumentNull("messageSequenceGenerator");
47             }
48             if (duplicateMessageHistoryLength < 0)
49             {
50                 throw FxTrace.Exception.ArgumentOutOfRange(
51                     "duplicateMessageHistoryLength",
52                     duplicateMessageHistoryLength,
53                     SR.DiscoveryNegativeDuplicateMessageHistoryLength);
54             }
55             if (duplicateMessageHistoryLength > 0)
56             {
57                 this.duplicateDetector = new DuplicateDetector<UniqueId>(duplicateMessageHistoryLength);
58             }
59             this.messageSequenceGenerator = discoveryMessageSequenceGenerator;
60         }
61
62         internal DiscoveryMessageSequenceGenerator MessageSequenceGenerator
63         {
64             get
65             {
66                 return this.messageSequenceGenerator;
67             }
68         }
69
70         void IDiscoveryContractApril2005.ProbeOperation(ProbeMessageApril2005 request)
71         {
72             Fx.Assert("The sync method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
73         }
74
75         IAsyncResult IDiscoveryContractApril2005.BeginProbeOperation(ProbeMessageApril2005 request, AsyncCallback callback, object state)
76         {
77             return new ProbeDuplexApril2005AsyncResult(request, this, null, callback, state);
78         }
79
80         void IDiscoveryContractApril2005.EndProbeOperation(IAsyncResult result)
81         {
82             ProbeDuplexApril2005AsyncResult.End(result);
83         }
84
85         void IDiscoveryContractApril2005.ResolveOperation(ResolveMessageApril2005 request)
86         {
87             Fx.Assert("The sync method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
88         }
89
90         IAsyncResult IDiscoveryContractApril2005.BeginResolveOperation(ResolveMessageApril2005 request, AsyncCallback callback, object state)
91         {
92             return new ResolveDuplexApril2005AsyncResult(request, this, null, callback, state);
93         }
94
95         void IDiscoveryContractApril2005.EndResolveOperation(IAsyncResult result)
96         {
97             ResolveDuplexApril2005AsyncResult.End(result);
98         }
99
100         void IDiscoveryContractAdhoc11.ProbeOperation(ProbeMessage11 request)
101         {
102             Fx.Assert("The sync method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
103         }
104
105         IAsyncResult IDiscoveryContractAdhoc11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state)
106         {
107             return new ProbeDuplex11AsyncResult(request, this, null, callback, state);
108         }
109
110         void IDiscoveryContractAdhoc11.EndProbeOperation(IAsyncResult result)
111         {
112             ProbeDuplex11AsyncResult.End(result);
113         }
114
115         void IDiscoveryContractAdhoc11.ResolveOperation(ResolveMessage11 request)
116         {
117             Fx.Assert("The sync method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
118         }
119
120         IAsyncResult IDiscoveryContractAdhoc11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state)
121         {
122             return new ResolveDuplex11AsyncResult(request, this, null, callback, state);
123         }
124
125         void IDiscoveryContractAdhoc11.EndResolveOperation(IAsyncResult result)
126         {
127             ResolveDuplex11AsyncResult.End(result);
128         }
129
130         ProbeMatchesMessage11 IDiscoveryContractManaged11.ProbeOperation(ProbeMessage11 request)
131         {
132             Fx.Assert("The sync method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
133             return null;
134         }
135
136         IAsyncResult IDiscoveryContractManaged11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state)
137         {
138             return new ProbeRequestResponse11AsyncResult(request, this, callback, state);
139         }
140
141         ProbeMatchesMessage11 IDiscoveryContractManaged11.EndProbeOperation(IAsyncResult result)
142         {
143             return ProbeRequestResponse11AsyncResult.End(result);
144         }
145
146         ResolveMatchesMessage11 IDiscoveryContractManaged11.ResolveOperation(ResolveMessage11 request)
147         {
148             Fx.Assert("The sync method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
149
150             return null;
151         }
152
153         IAsyncResult IDiscoveryContractManaged11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state)
154         {
155             return new ResolveRequestResponse11AsyncResult(request, this, callback, state);
156         }
157
158         ResolveMatchesMessage11 IDiscoveryContractManaged11.EndResolveOperation(IAsyncResult result)
159         {
160             return ResolveRequestResponse11AsyncResult.End(result);
161         }
162
163         void IDiscoveryContractAdhocCD1.ProbeOperation(ProbeMessageCD1 request)
164         {
165             Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
166         }
167
168         IAsyncResult IDiscoveryContractAdhocCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state)
169         {
170             return new ProbeDuplexCD1AsyncResult(request, this, null, callback, state);
171         }
172
173         void IDiscoveryContractAdhocCD1.EndProbeOperation(IAsyncResult result)
174         {
175             ProbeDuplexCD1AsyncResult.End(result);
176         }
177
178         void IDiscoveryContractAdhocCD1.ResolveOperation(ResolveMessageCD1 request)
179         {
180             Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
181         }
182
183         IAsyncResult IDiscoveryContractAdhocCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state)
184         {
185             return new ResolveDuplexCD1AsyncResult(request, this, null, callback, state);
186         }
187
188         void IDiscoveryContractAdhocCD1.EndResolveOperation(IAsyncResult result)
189         {
190             ResolveDuplexCD1AsyncResult.End(result);
191         }
192
193         ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.ProbeOperation(ProbeMessageCD1 request)
194         {
195             Fx.Assert("The sync method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
196             return null;
197         }
198
199         IAsyncResult IDiscoveryContractManagedCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state)
200         {
201             return new ProbeRequestResponseCD1AsyncResult(request, this, callback, state);
202         }
203
204         ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.EndProbeOperation(IAsyncResult result)
205         {
206             return ProbeRequestResponseCD1AsyncResult.End(result);
207         }
208
209         ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.ResolveOperation(ResolveMessageCD1 request)
210         {
211             Fx.Assert("The sync method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
212             return null;
213         }
214
215         IAsyncResult IDiscoveryContractManagedCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state)
216         {
217             return new ResolveRequestResponseCD1AsyncResult(request, this, callback, state);
218         }
219
220         ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.EndResolveOperation(IAsyncResult result)
221         {
222             return ResolveRequestResponseCD1AsyncResult.End(result);
223         }
224
225         bool IDiscoveryServiceImplementation.IsDuplicate(UniqueId messageId)
226         {
227             return (this.duplicateDetector != null) && (!this.duplicateDetector.AddIfNotDuplicate(messageId));
228         }
229
230         DiscoveryMessageSequence IDiscoveryServiceImplementation.GetNextMessageSequence()
231         {
232             return this.messageSequenceGenerator.Next();
233         }
234
235         IAsyncResult IDiscoveryServiceImplementation.BeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state)
236         {
237             return this.OnBeginFind(findRequestContext, callback, state);
238         }
239
240         void IDiscoveryServiceImplementation.EndFind(IAsyncResult result)
241         {
242             this.OnEndFind(result);
243         }
244
245         IAsyncResult IDiscoveryServiceImplementation.BeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state)
246         {
247             return this.OnBeginResolve(resolveCriteria, callback, state);
248         }
249
250         EndpointDiscoveryMetadata IDiscoveryServiceImplementation.EndResolve(IAsyncResult result)
251         {
252             return this.OnEndResolve(result);
253         }
254
255         internal static bool EnsureMessageId()
256         {
257             if (OperationContext.Current.IncomingMessageHeaders.MessageId == null)
258             {
259                 if (TD.DiscoveryMessageWithNullMessageIdIsEnabled())
260                 {
261                     TD.DiscoveryMessageWithNullMessageId(
262                         null,
263                         string.Format(
264                             CultureInfo.InvariantCulture,
265                             "{0}/{1}",
266                             ProtocolStrings.TracingStrings.Probe,
267                             ProtocolStrings.TracingStrings.Resolve));
268                 }
269
270                 return false;
271             }
272
273             return true;
274         }
275
276         internal static bool EnsureReplyTo()
277         {
278             OperationContext context = OperationContext.Current;
279             if (context.IncomingMessageHeaders.ReplyTo == null)
280             {
281                 if (TD.DiscoveryMessageWithNullReplyToIsEnabled())
282                 {
283                     EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(context.IncomingMessage);
284                     TD.DiscoveryMessageWithNullReplyTo(eventTraceActivity, context.IncomingMessageHeaders.MessageId.ToString());
285                 }
286
287                 return false;
288             }
289
290             return true;
291         }
292
293         protected abstract IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state);
294         protected abstract void OnEndFind(IAsyncResult result);
295
296         protected abstract IAsyncResult OnBeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state);
297         protected abstract EndpointDiscoveryMetadata OnEndResolve(IAsyncResult result);
298     }
299 }