Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Linq;
12 : using System.Reflection;
13 : using System.Runtime.Serialization;
14 : using System.Web;
15 : using System.Xml;
16 : using Cqrs.Authentication;
17 : using Cqrs.Configuration;
18 : using Cqrs.Domain;
19 : using Cqrs.Events;
20 : using Cqrs.Messages;
21 : using Cqrs.Services;
22 :
23 : namespace Cqrs.WebApi
24 : {
25 : /// <summary>
26 : /// A start-up configuration class for the auto documenting features.
27 : /// </summary>
28 : /// <typeparam name="TAuthenticationToken">The <see cref="Type"/> of the authentication token.</typeparam>
29 : public static class HelpPageConfig<TAuthenticationToken>
30 1 : {
31 : /// <summary>
32 : /// The list of relevant XML files to use with the auto documenting feature.
33 : /// </summary>
34 : public static IList<string> AssemblyXmlFileNames { get; set; }
35 :
36 : static HelpPageConfig()
37 : {
38 : AssemblyXmlFileNames = new List<string>();
39 : }
40 :
41 : /// <summary>
42 : /// A sample <see cref="IEvent{TAuthenticationToken}"/> used for API documentation generation.
43 : /// </summary>
44 : [Serializable]
45 : [DataContract]
46 : public class UserCreatedEvent : IEvent<TAuthenticationToken>
47 1 : {
48 : #region Implementation of IMessageWithAuthenticationToken<TAuthenticationToken>
49 :
50 : /// <summary>
51 : /// The authentication token of the entity that triggered the event to be raised.
52 : /// </summary>
53 : [DataMember]
54 : public TAuthenticationToken AuthenticationToken { get; set; }
55 :
56 : #endregion
57 :
58 : #region Implementation of IMessage
59 :
60 : /// <summary>
61 : /// An identifier used to group together several <see cref="IMessage"/>. Any <see cref="IMessage"/> with the same <see cref="CorrelationId"/> were triggered by the same initiating request.
62 : /// </summary>
63 : [DataMember]
64 : public Guid CorrelationId { get; set; }
65 :
66 : /// <summary>
67 : /// The originating framework this message was sent from.
68 : /// </summary>
69 : [DataMember]
70 : public string OriginatingFramework { get; set; }
71 :
72 : /// <summary>
73 : /// The frameworks this <see cref="IMessage"/> has been delivered to/sent via already.
74 : /// </summary>
75 : [DataMember]
76 : public IEnumerable<string> Frameworks { get; set; }
77 :
78 : #endregion
79 :
80 : #region Implementation of IMessage
81 :
82 : /// <summary>
83 : /// The identifier of the command itself.
84 : /// In some cases this may be the <see cref="IAggregateRoot{TAuthenticationToken}"/> or <see cref="ISaga{TAuthenticationToken}"/> this command targets.
85 : /// </summary>
86 : [DataMember]
87 : public Guid Id { get; set; }
88 :
89 : /// <summary>
90 : /// The new version number the targeted <see cref="IAggregateRoot{TAuthenticationToken}"/> or <see cref="ISaga{TAuthenticationToken}"/> that raised this.
91 : /// </summary>
92 : [DataMember]
93 : public int Version { get; set; }
94 :
95 : /// <summary>
96 : /// The date and time the event was raised or published.
97 : /// </summary>
98 : [DataMember]
99 : public DateTimeOffset TimeStamp { get; set; }
100 :
101 : #endregion
102 :
103 : /// <summary>
104 : /// The identifier of the User to create.
105 : /// </summary>
106 : public Guid Rsn { get; set; }
107 :
108 : /// <summary>
109 : /// The name os the USer to create.
110 : /// </summary>
111 : public string Name { get; set; }
112 :
113 : /// <summary>
114 : /// The email address of the User to create.
115 : /// </summary>
116 : public string EmailAddress { get; set; }
117 : }
118 :
119 : static TAuthenticationToken GenerateAuthenticationToken()
120 : {
121 : string authenticationType;
122 : if (!DependencyResolver.Current.Resolve<IConfigurationManager>().TryGetSetting("Cqrs.AuthenticationTokenType", out authenticationType) || string.IsNullOrWhiteSpace(authenticationType))
123 : authenticationType = "Guid";
124 :
125 : TAuthenticationToken token = default(TAuthenticationToken);
126 :
127 : if (authenticationType.ToLowerInvariant() == "int" || authenticationType.ToLowerInvariant() == "integer")
128 : token = (TAuthenticationToken)(object)123;
129 : else if (authenticationType.ToLowerInvariant() == "guid")
130 : token = (TAuthenticationToken)(object)Guid.NewGuid();
131 : else if (authenticationType.ToLowerInvariant() == "string" || authenticationType.ToLowerInvariant() == "text")
132 : token = (TAuthenticationToken)(object)"UserToken123";
133 : else if (authenticationType == "SingleSignOnToken" || authenticationType == "ISingleSignOnToken")
134 : token = (TAuthenticationToken)(object)new SingleSignOnToken
135 : {
136 : Token = Guid.NewGuid().ToString("N"),
137 : DateIssued = DateTime.Now,
138 : TimeOfExpiry = DateTime.Now.AddMinutes(20)
139 : };
140 : else if (authenticationType == "SingleSignOnTokenWithUserRsn" || authenticationType == "ISingleSignOnTokenWithUserRsn")
141 : token = (TAuthenticationToken)(object)new SingleSignOnTokenWithUserRsn
142 : {
143 : Token = Guid.NewGuid().ToString("N"),
144 : DateIssued = DateTime.Now,
145 : TimeOfExpiry = DateTime.Now.AddMinutes(20),
146 : UserRsn = Guid.NewGuid()
147 : };
148 : else if (authenticationType == "SingleSignOnTokenWithCompanyRsn" || authenticationType == "ISingleSignOnTokenWithCompanyRsn")
149 : token = (TAuthenticationToken)(object)new SingleSignOnTokenWithCompanyRsn
150 : {
151 : Token = Guid.NewGuid().ToString("N"),
152 : DateIssued = DateTime.Now,
153 : TimeOfExpiry = DateTime.Now.AddMinutes(20),
154 : CompanyRsn = Guid.NewGuid()
155 : };
156 : else if (authenticationType == "SingleSignOnTokenWithUserRsnAndCompanyRsn" || authenticationType == "ISingleSignOnTokenWithUserRsnAndCompanyRsn")
157 : token = (TAuthenticationToken)(object)new SingleSignOnTokenWithUserRsnAndCompanyRsn
158 : {
159 : Token = Guid.NewGuid().ToString("N"),
160 : DateIssued = DateTime.Now,
161 : TimeOfExpiry = DateTime.Now.AddMinutes(20),
162 : UserRsn = Guid.NewGuid(),
163 : CompanyRsn = Guid.NewGuid()
164 : };
165 :
166 : return token;
167 : }
168 :
169 : /// <summary>
170 : /// Get a collection of sample objects for the auto documenting features to use.
171 : /// </summary>
172 1 : public static IDictionary<Type, object> GetBasicSampleObjects()
173 : {
174 : var eventCorrelationId = Guid.NewGuid();
175 : var correlationId = Guid.NewGuid();
176 :
177 : var sameplEvent = new UserCreatedEvent
178 : {
179 : CorrelationId = correlationId,
180 : AuthenticationToken = GenerateAuthenticationToken(),
181 : EmailAddress = "john@smith.com",
182 : Frameworks = new List<string> { "Azure", "Amazon EC2" },
183 : Id = Guid.NewGuid(),
184 : Rsn = Guid.NewGuid(),
185 : Name = "John Smith",
186 : OriginatingFramework = "Azure",
187 : TimeStamp = DateTime.Now.AddMinutes(-3),
188 : Version = 1
189 : };
190 :
191 : return new Dictionary<Type, object>
192 : {
193 : {
194 : typeof(string),
195 : "sample string"
196 : },
197 : {
198 : typeof(IServiceResponse),
199 : new ServiceResponse
200 : {
201 : CorrelationId = correlationId,
202 : State = ServiceResponseStateType.Succeeded
203 : }
204 : },
205 : {
206 : typeof(IServiceRequestWithData<TAuthenticationToken, Guid>),
207 : new ServiceRequestWithData<TAuthenticationToken, Guid>
208 : {
209 : AuthenticationToken = GenerateAuthenticationToken(),
210 : CorrelationId = correlationId,
211 : Data = eventCorrelationId
212 : }
213 : },
214 : {
215 : typeof(IServiceResponseWithResultData<IEnumerable<EventData>>),
216 : new ServiceResponseWithResultData<IEnumerable<EventData>>
217 : {
218 : CorrelationId = correlationId,
219 : ResultData = new List<EventData>
220 : {
221 : new EventData
222 : {
223 : AggregateId = string.Format("{0}//{1}", typeof(UserCreatedEvent).FullName, sameplEvent.Rsn),
224 : CorrelationId = eventCorrelationId,
225 : Data = sameplEvent,
226 : AggregateRsn = sameplEvent.Rsn,
227 : EventId = Guid.NewGuid(),
228 : EventType = typeof(UserCreatedEvent).FullName,
229 : Timestamp = sameplEvent.TimeStamp.DateTime,
230 : Version = sameplEvent.Version
231 : }
232 : },
233 : Version = 0,
234 : State = ServiceResponseStateType.Succeeded
235 : }
236 : }
237 : };
238 : }
239 :
240 : /// <summary>
241 : /// Generate a list of relevant XML files to use with the auto documenting feature.
242 : /// </summary>
243 1 : public static void GenerateAssemblyXmlFileNames(Assembly assembly = null)
244 : {
245 : if (AssemblyXmlFileNames.Any())
246 : return;
247 :
248 : string webAssemblyName = (assembly ?? Assembly.GetCallingAssembly()).FullName;
249 : webAssemblyName = webAssemblyName.Substring(0, webAssemblyName.IndexOf(","));
250 : AssemblyXmlFileNames = new List<string> { webAssemblyName };
251 : try
252 : {
253 : string publicAssemblyName = webAssemblyName.Substring(0, webAssemblyName.Length - ".Domain.Host.Web".Length);
254 : AssemblyXmlFileNames.Add(publicAssemblyName);
255 : }
256 : catch (ArgumentOutOfRangeException) { }
257 : try
258 : {
259 : string domainAssemblyName = webAssemblyName.Substring(0, webAssemblyName.Length - ".Host.Web".Length);
260 : AssemblyXmlFileNames.Add(domainAssemblyName);
261 : }
262 : catch (ArgumentOutOfRangeException) { }
263 : }
264 :
265 : /// <summary>
266 : /// Generate the relevant XML file used by the auto documenting feature.
267 : /// </summary>
268 1 : public static void CreateXmlDocumentation(Assembly assembly = null)
269 : {
270 : GenerateAssemblyXmlFileNames(assembly);
271 : var assemblyXmlFileNames = new List<string>(AssemblyXmlFileNames) {"Cqrs", "Cqrs.WebApi"};
272 : var finalDocumentation = new XmlDocument();
273 : for (int i = 0; i < assemblyXmlFileNames.Count; i++)
274 : {
275 : string assemblyXmlFileName = assemblyXmlFileNames[i];
276 :
277 : XmlDocument documentation = new XmlDocument();
278 : if (i == 0)
279 : {
280 : finalDocumentation.Load(HttpContext.Current.Server.MapPath(string.Format("~/bin/{0}.XML", assemblyXmlFileName)));
281 : continue;
282 : }
283 : documentation.Load(HttpContext.Current.Server.MapPath(string.Format("~/bin/{0}.XML", assemblyXmlFileName)));
284 :
285 : foreach (XmlNode childNode in documentation.DocumentElement.ChildNodes)
286 : finalDocumentation.DocumentElement.AppendChild(finalDocumentation.ImportNode(childNode, true));
287 : }
288 :
289 : finalDocumentation.Save(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml"));
290 : }
291 : }
292 : }
|