Skip to content

Commit 152e7c7

Browse files
darrelmillerpeombwa
authored andcommitted
Updated to GraphClientFactory
1 parent 40bd471 commit 152e7c7

File tree

3 files changed

+144
-196
lines changed

3 files changed

+144
-196
lines changed

src/Microsoft.Graph.Core/Requests/GraphClientFactory.cs

Lines changed: 82 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ public static class GraphClientFactory
4040
private static readonly string _baseAddress = "https://graph.microsoft.com/";
4141

4242
/// Microsoft Graph service nationa cloud endpoints
43-
private static readonly Dictionary<string, string> cloudList;
44-
43+
private static readonly Dictionary<string, string> cloudList = new Dictionary<string, string>
44+
{
45+
{ Global_Cloud, "https://graph.microsoft.com" },
46+
{ USGOV_Cloud, "https://graph.microsoft.com" },
47+
{ China_Cloud, "https://microsoftgraph.chinacloudapi.cn" },
48+
{ Germany_Cloud, "https://graph.microsoft.de" }
49+
};
4550

4651
/// Global endpoint
4752
public const string Global_Cloud = "Global";
@@ -52,98 +57,22 @@ public static class GraphClientFactory
5257
/// Germany endpoint
5358
public const string Germany_Cloud = "Germany";
5459

55-
static GraphClientFactory()
56-
{
57-
cloudList = new Dictionary<string, string>();
58-
cloudList.Add(Global_Cloud, "https://graph.microsoft.com");
59-
cloudList.Add(USGOV_Cloud, "https://graph.microsoft.com");
60-
cloudList.Add(China_Cloud, "https://microsoftgraph.chinacloudapi.cn");
61-
cloudList.Add(Germany_Cloud, "https://graph.microsoft.de");
62-
}
63-
64-
65-
/// Property Version for version value
66-
public static string Version { set; get; } = "v1.0";
67-
68-
/// <summary>
69-
/// Creates a new <see cref="HttpClient"/> instance configured with the handlers provided.
70-
/// </summary>
71-
/// <param name="handlers">An ordered list of <see cref="DelegatingHandler"/> instances to be invoked as an
72-
/// <see cref="HttpRequestMessage"/> travels from the <see cref="HttpClient"/> to the network and an
73-
/// <see cref="HttpResponseMessage"/> travels from the network back to <see cref="HttpClient"/>.
74-
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
75-
/// an outbound request message but last for an inbound response message.</param>
76-
/// <returns>An <see cref="HttpClient"/> instance with the configured handlers.</returns>
77-
public static HttpClient CreateClient(params DelegatingHandler[] handlers)
78-
{
79-
return Create(null, handlers);
80-
}
81-
82-
/// <summary>
83-
/// Creates a new <see cref="HttpClient"/> instance configured with the handlers provided.
84-
/// </summary>
85-
/// <param name="innerHandler">The inner handler represents the destination of the HTTP message channel.</param>
86-
/// <param name="handlers">An ordered list of <see cref="DelegatingHandler"/> instances to be invoked as an
87-
/// <see cref="HttpRequestMessage"/> travels from the <see cref="HttpClient"/> to the network and an
88-
/// <see cref="HttpResponseMessage"/> travels from the network back to <see cref="HttpClient"/>.
89-
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
90-
/// an outbound request message but last for an inbound response message.</param>
91-
/// <returns>An <see cref="HttpClient"/> instance with the configured handlers.</returns>
92-
public static HttpClient CreateClient(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
93-
{
94-
return Create(innerHandler, handlers);
95-
}
9660
/// <summary>
97-
/// Creates a new <see cref="HttpClient"/> instance configured with the handlers provided.
61+
/// Proxy to be used with created clients
9862
/// </summary>
99-
/// <param name="sovereignCloud">The <see cref="string"/>value to pass the national cloud root endpoint to client.</param>
100-
/// <param name="handlers">An ordered list of <see cref="DelegatingHandler"/> instances to be invoked as an
101-
/// <see cref="HttpRequestMessage"/> travels from the <see cref="HttpClient"/> to the network and an
102-
/// <see cref="HttpResponseMessage"/> travels from the network back to <see cref="HttpClient"/>.
103-
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
104-
/// an outbound request message but last for an inbound response message.</param>
105-
/// <returns>An <see cref="HttpClient"/> instance with the configured handlers.</returns>
106-
public static HttpClient CreateClient(string sovereignCloud, params DelegatingHandler[] handlers)
107-
{
108-
if (sovereignCloud == null)
109-
{
110-
throw new ArgumentNullException(String.Format("{0} is null.", sovereignCloud, "sovereignCloud"));
111-
}
112-
string cloud = "";
113-
if (!cloudList.TryGetValue(sovereignCloud, out cloud))
114-
{
115-
throw new ArgumentException(String.Format("{0} is an unexpected national cloud.", sovereignCloud, "sovereignCloud"));
116-
}
117-
string cloudAddress = cloud + "/" + Version;
118-
Uri address = new Uri(cloudAddress);
119-
HttpClient client = Create(null, handlers);
120-
client.BaseAddress = address;
121-
return client;
122-
}
63+
public static IWebProxy Proxy { get; set; }
12364

12465
/// <summary>
125-
/// Creates a new <see cref="HttpClient"/> instance configured with the handlers, timeout, baseAddress,
126-
/// cacheControlHeaderValue and proxy provided.
66+
/// DefaultHandler is a Func that returns the HttpMessageHandler for actually making the HTTP calls.
67+
/// The default implementation returns a new instance of HttpClientHandler for each HttpClient.
12768
/// </summary>
128-
/// <param name="proxy">A <see cref="IWebProxy"/> object to be passed to client to configure InnderHandler's proxy property.</param>
129-
/// <param name="handlers">An ordered list of <see cref="DelegatingHandler"/> instances to be invoked as an
130-
/// <see cref="HttpRequestMessage"/> travels from the <see cref="HttpClient"/> to the network and an
131-
/// <see cref="HttpResponseMessage"/> travels from the network back to <see cref="HttpClient"/>.
132-
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
133-
/// an outbound request message but last for an inbound response message.</param>
134-
/// <returns>An <see cref="HttpClient"/> instance with the configured handlers.</returns>
135-
public static HttpClient CreateClient(IWebProxy proxy = null, params DelegatingHandler[] handlers)
136-
{
137-
HttpClientHandler handler = new HttpClientHandler();
138-
if (proxy != null)
69+
public static Func<HttpMessageHandler> DefaultHttpHandler = () => {
70+
return new HttpClientHandler
13971
{
140-
handler.Proxy = proxy;
141-
}
142-
143-
return Create(handler, handlers);
144-
145-
}
146-
72+
Proxy = Proxy
73+
};
74+
};
75+
14776

14877
/// <summary>
14978
/// Creates a new <see cref="HttpClient"/> instance configured with the handlers provided and with the
@@ -156,19 +85,49 @@ public static HttpClient CreateClient(IWebProxy proxy = null, params DelegatingH
15685
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
15786
/// an outbound request message but last for an inbound response message.</param>
15887
/// <returns>An <see cref="HttpClient"/> instance with the configured handlers.</returns>
159-
private static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
88+
public static HttpClient Create(string version = "v1.0", string nationalCloud = Global_Cloud, IEnumerable<DelegatingHandler> handlers = null)
16089
{
161-
HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers);
90+
HttpMessageHandler pipeline;
91+
if (handlers == null)
92+
{
93+
pipeline = CreatePipeline(CreateDefaultHandlers(), DefaultHttpHandler());
94+
} else
95+
{
96+
pipeline = CreatePipeline(handlers,DefaultHttpHandler());
97+
}
98+
16299
HttpClient client = new HttpClient(pipeline);
163100
client.DefaultRequestHeaders.Add(SdkVersionHeaderName, SdkVersionHeaderValue);
164101
client.Timeout = defaultTimeout;
165-
string address = _baseAddress + Version;
166-
client.BaseAddress = new Uri(address);
102+
client.BaseAddress = DetermineBaseAddress(nationalCloud, version);
167103
client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true, NoStore = true };
168104
return client;
169105
}
170106

107+
/// <summary>
108+
/// Create a default set of middleware for calling Microsoft Graph
109+
/// </summary>
110+
/// <returns></returns>
111+
public static IEnumerable<DelegatingHandler> CreateDefaultHandlers()
112+
{
113+
return new List<DelegatingHandler> {
114+
new RetryHandler(),
115+
new RedirectHandler()
116+
};
117+
}
118+
119+
private static Uri DetermineBaseAddress(string nationalCloud, string version)
120+
{
121+
string cloud = "";
122+
if (!cloudList.TryGetValue(nationalCloud, out cloud))
123+
{
124+
throw new ArgumentException(String.Format("{0} is an unexpected national cloud.", nationalCloud, "nationalCloud"));
125+
}
126+
string cloudAddress = cloud + "/" + version;
127+
return new Uri(cloudAddress);
171128

129+
}
130+
172131
/// <summary>
173132
/// Creates an instance of an <see cref="HttpMessageHandler"/> using the <see cref="DelegatingHandler"/> instances
174133
/// provided by <paramref name="handlers"/>. The resulting pipeline can be used to manually create <see cref="HttpClient"/>
@@ -180,11 +139,11 @@ private static HttpClient Create(HttpMessageHandler innerHandler, params Delegat
180139
/// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for
181140
/// an outbound request message but last for an inbound response message.</param>
182141
/// <returns>The HTTP message channel.</returns>
183-
public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler, IEnumerable<DelegatingHandler> handlers)
142+
public static HttpMessageHandler CreatePipeline(IEnumerable<DelegatingHandler> handlers, HttpMessageHandler innerHandler = null )
184143
{
185144
if (innerHandler == null)
186145
{
187-
innerHandler = new HttpClientHandler();
146+
innerHandler = DefaultHttpHandler();
188147
}
189148

190149
if (handlers == null)
@@ -214,35 +173,36 @@ public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler,
214173
}
215174

216175

217-
/// <summary>
218-
/// Configure an instance of an <see cref="HttpClient"/>
219-
/// </summary>
220-
/// <param name="client">The <see cref="HttpClient"/> client instance need to be configured.</param>
221-
/// <param name="timeout">A <see cref="TimeSpan"/> value for the HTTP client timeout property.</param>
222-
/// <param name="baseAddress">A <see cref="Uri"/> value to set the HTTP client BaseAddress property.</param>
223-
/// <param name="cacheControlHeaderValue">A <see cref="CacheControlHeaderValue"/> value to set HTTP client DefaultRequestHeaders property.</param>
224-
/// <returns></returns>
225-
public static HttpClient Configure(HttpClient client, TimeSpan timeout, Uri baseAddress, CacheControlHeaderValue cacheControlHeaderValue)
226-
{
227-
try
228-
{
229-
client.Timeout = timeout;
230-
}
231-
catch (InvalidOperationException exception)
232-
{
233-
throw new ServiceException(
234-
new Error
235-
{
236-
Code = ErrorConstants.Codes.NotAllowed,
237-
Message = ErrorConstants.Messages.OverallTimeoutCannotBeSet,
238-
},
239-
exception);
240-
}
241176

242-
client.BaseAddress = baseAddress == null ? new Uri(_baseAddress + Version) : baseAddress;
243-
client.DefaultRequestHeaders.CacheControl = cacheControlHeaderValue ?? new CacheControlHeaderValue { NoCache = true, NoStore = true };
244-
return client;
245-
}
177+
///// <summary>
178+
///// Configure an instance of an <see cref="HttpClient"/>
179+
///// </summary>
180+
///// <param name="client">The <see cref="HttpClient"/> client instance need to be configured.</param>
181+
///// <param name="timeout">A <see cref="TimeSpan"/> value for the HTTP client timeout property.</param>
182+
///// <param name="baseAddress">A <see cref="Uri"/> value to set the HTTP client BaseAddress property.</param>
183+
///// <param name="cacheControlHeaderValue">A <see cref="CacheControlHeaderValue"/> value to set HTTP client DefaultRequestHeaders property.</param>
184+
///// <returns></returns>
185+
//public static HttpClient Configure(HttpClient client, TimeSpan timeout, Uri baseAddress, CacheControlHeaderValue cacheControlHeaderValue)
186+
//{
187+
// try
188+
// {
189+
// client.Timeout = timeout;
190+
// }
191+
// catch (InvalidOperationException exception)
192+
// {
193+
// throw new ServiceException(
194+
// new Error
195+
// {
196+
// Code = ErrorConstants.Codes.NotAllowed,
197+
// Message = ErrorConstants.Messages.OverallTimeoutCannotBeSet,
198+
// },
199+
// exception);
200+
// }
201+
202+
// client.BaseAddress = baseAddress == null ? new Uri(_baseAddress + Version) : baseAddress;
203+
// client.DefaultRequestHeaders.CacheControl = cacheControlHeaderValue ?? new CacheControlHeaderValue { NoCache = true, NoStore = true };
204+
// return client;
205+
//}
246206

247207
}
248208
}

0 commit comments

Comments
 (0)