forked from openstacknetsdk/openstack.net
-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathOpenStackNet.cs
More file actions
171 lines (155 loc) · 6.84 KB
/
OpenStackNet.cs
File metadata and controls
171 lines (155 loc) · 6.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Extensions;
using System.Net.Http.Headers;
using Flurl.Http;
using Flurl.Http.Configuration;
using net.openstack.Core;
using Newtonsoft.Json;
using OpenStack.Authentication;
using OpenStack.Serialization;
namespace OpenStack
{
/// <summary>
/// A static container for global configuration settings affecting OpenStack.NET behavior.
/// </summary>
/// <threadsafety static="true" instance="false"/>
public static class OpenStackNet
{
/// <summary>
/// Global configuration which affects OpenStack.NET's behavior.
/// <para>Modify using <see cref="Configure"/>.</para>
/// </summary>
public static readonly OpenStackNetConfigurationOptions Configuration = new OpenStackNetConfigurationOptions();
private static readonly object ConfigureLock = new object();
/// <summary>
/// Provides thread-safe accesss to OpenStack.NET's global configuration options.
/// <para>
/// Can only be called once at application start-up, before instantiating any OpenStack.NET objects.
/// </para>
/// </summary>
/// <param name="configureFlurl">Addtional configuration of Flurl's global settings <seealso cref="Flurl.Http.FlurlHttp.Configure" />.</param>
/// <param name="configureJson">Additional configuration of Json.NET's global settings <seealso cref="Newtonsoft.Json.JsonConvert.DefaultSettings" />.</param>
/// <param name="configure">Additional configuration of OpenStack.NET's global settings.</param>
public static void Configure(Action<FlurlHttpConfigurationOptions> configureFlurl = null, Action<JsonSerializerSettings> configureJson = null, Action<OpenStackNetConfigurationOptions> configure = null)
{
lock (ConfigureLock)
{
if(configure != null)
configure(Configuration);
JsonConvert.DefaultSettings = () =>
{
// Apply our default settings
var settings = new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new OpenStackContractResolver()
};
// Apply application's default settings
if (configureJson != null)
configureJson(settings);
return settings;
};
FlurlHttp.Configure(c =>
{
// Apply the application's default settings
if (configureFlurl != null)
configureFlurl(c);
//
// Apply our default settings
//
if(c.HttpClientFactory is DefaultHttpClientFactory)
c.HttpClientFactory = new AuthenticatedHttpClientFactory();
// Apply our event handling without clobbering any application level handlers
var applicationBeforeCall = c.BeforeCall;
c.BeforeCall = call =>
{
SetUserAgentHeader(call);
if (applicationBeforeCall != null)
applicationBeforeCall(call);
};
var applicationAfterCall = c.AfterCall;
c.AfterCall = call =>
{
Tracing.TraceHttpCall(call);
if (applicationAfterCall != null)
applicationAfterCall(call);
};
var applicationOnError = c.OnError;
c.OnError = call =>
{
Tracing.TraceFailedHttpCall(call);
if (applicationOnError != null)
applicationOnError(call);
};
});
}
}
private static void SetUserAgentHeader(HttpCall call)
{
foreach (var userAgent in Configuration.UserAgents)
{
call.Request.Headers.UserAgent.Add(userAgent);
}
}
/// <summary>
/// Provides global point for programmatically configuraing tracing
/// </summary>
public static class Tracing
{
/// <summary>
/// Trace source for all HTTP requests. Default level is Error.
/// <para>
/// In your app or web.config the trace soruce name is "Flurl.Http".
/// </para>
/// </summary>
public static readonly TraceSource Http = new TraceSource("Flurl.Http", SourceLevels.Error);
/// <summary>
/// Traces a failed HTTP request
/// </summary>
/// <param name="httpCall">The Flurl HTTP call instance, containing information about the request and response.</param>
public static void TraceFailedHttpCall(HttpCall httpCall)
{
Http.TraceData(TraceEventType.Error, 0, JsonConvert.SerializeObject(httpCall, Formatting.Indented));
Http.Flush();
}
/// <summary>
/// Traces an HTTP request
/// </summary>
/// <param name="httpCall">The Flurl HTTP call instance, containing information about the request and response.</param>
public static void TraceHttpCall(HttpCall httpCall)
{
Http.TraceData(TraceEventType.Information, 0, JsonConvert.SerializeObject(httpCall, Formatting.Indented));
}
}
}
/// <summary>
/// A set of properties that affect OpenStack.NET's behavior.
/// <para>Generally set via the static <see cref="OpenStack.OpenStackNet.Configure"/> method.</para>
/// </summary>
public class OpenStackNetConfigurationOptions
{
/// <summary/>
protected internal OpenStackNetConfigurationOptions()
{
ResetDefaults();
}
/// <summary>
/// Additional application specific user agents which should be set in the UserAgent header on all requests.
/// </summary>
public List<ProductInfoHeaderValue> UserAgents { get; private set; }
/// <summary>
/// Clear all custom global options and set default values.
/// </summary>
public virtual void ResetDefaults()
{
UserAgents = new List<ProductInfoHeaderValue>
{
new ProductInfoHeaderValue("openstack.net", GetType().GetAssemblyFileVersion())
};
}
}
}