Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
WebHookEventSink.cs
1using System;
3using System.Security.Cryptography.X509Certificates;
4using System.Text;
5using System.Threading;
6using System.Threading.Tasks;
7using Waher.Content;
10using Waher.Security;
11
13{
18 {
19 private Cache<string, Rec> eventCache = null;
20 private X509Certificate certificate;
21 private readonly SemaphoreSlim synchObj = new SemaphoreSlim(1);
22 private readonly Uri callbackUrl;
23 private readonly int maxSecondsUsed;
24 private readonly int maxSecondsUnused;
25 private readonly bool collectOnType;
26 private readonly bool collectOnLevel;
27 private readonly bool collectOnEventId;
28 private readonly bool collectOnObject;
29 private readonly bool collectOnActor;
30 private readonly bool collectOnFacility;
31 private readonly bool collectOnModule;
32 private readonly bool collected;
33
39 public WebHookEventSink(string ObjectID, string CallbackUrl)
40 : this(ObjectID, CallbackUrl, null)
41 {
42 }
43
50 public WebHookEventSink(string ObjectID, string CallbackUrl,
51 X509Certificate Certificate)
52 : this(ObjectID, CallbackUrl, Certificate, 0, 0, false, false,
53 false, false, false, false, false)
54 {
55 }
56
72 public WebHookEventSink(string ObjectID, string CallbackUrl, X509Certificate Certificate,
73 int MaxSecondsUsed, int MaxSecondsUnused, bool CollectOnType,
74 bool CollectOnLevel, bool CollectOnEventId, bool CollectOnObject,
75 bool CollectOnActor, bool CollectOnFacility, bool CollectOnModule)
76 : base(ObjectID)
77 {
78 if (MaxSecondsUsed < MaxSecondsUnused)
79 throw new ArgumentException("MaxSecondsUsed must be greater than, or equal to, MaxSecondsUnused.", nameof(MaxSecondsUsed));
80
81 this.collected = MaxSecondsUnused > 0;
82 this.callbackUrl = new Uri(CallbackUrl);
83 this.certificate = Certificate;
84 this.maxSecondsUsed = MaxSecondsUsed;
85 this.maxSecondsUnused = MaxSecondsUnused;
86 this.collectOnType = CollectOnType;
87 this.collectOnLevel = CollectOnLevel;
88 this.collectOnEventId = CollectOnEventId;
89 this.collectOnObject = CollectOnObject;
90 this.collectOnActor = CollectOnActor;
91 this.collectOnFacility = CollectOnFacility;
92 this.collectOnModule = CollectOnModule;
93
94 if (this.collected)
95 {
96 this.eventCache = new Cache<string, Rec>(int.MaxValue,
97 TimeSpan.FromSeconds(this.maxSecondsUsed),
98 TimeSpan.FromSeconds(this.maxSecondsUnused));
99
100 this.eventCache.Removed += this.EventCache_Removed;
101 }
102 }
103
107 public override Task DisposeAsync()
108 {
109 this.eventCache?.Clear();
110 this.eventCache?.Dispose();
111 this.eventCache = null;
112
113 return base.DisposeAsync();
114 }
115
120 public void UpdateCertificate(X509Certificate Certificate)
121 {
122 this.certificate = Certificate;
123 }
124
129 public override async Task Queue(Event Event)
130 {
131 Dictionary<string, object> Payload = new Dictionary<string, object>()
132 {
133 { "Timestamp", Event.Timestamp.ToUniversalTime() },
134 { "Type", Event.Type },
135 { "Level", Event.Level },
136 { "EventId", Event.EventId },
137 { "Object", Event.Object },
138 { "Actor", Event.Actor },
139 { "Facility", Event.Facility },
140 { "Module", Event.Module },
141 { "Message", Event.Message },
142 { "Tags", Event.Tags },
143 { "StackTrace", Event.StackTrace }
144 };
145
146 if (this.collected)
147 {
148 await this.synchObj.WaitAsync();
149 try
150 {
151 StringBuilder sb = new StringBuilder();
152 bool First = true;
153
154 if (this.collectOnType)
155 Append(sb, Event.Type.ToString(), ref First);
156
157 if (this.collectOnLevel)
158 Append(sb, Event.Level.ToString(), ref First);
159
160 if (this.collectOnEventId)
161 Append(sb, Event.EventId, ref First);
162
163 if (this.collectOnObject)
164 Append(sb, Event.Object, ref First);
165
166 if (this.collectOnActor)
167 Append(sb, Event.Actor, ref First);
168
169 if (this.collectOnFacility)
170 Append(sb, Event.Facility, ref First);
171
172 if (this.collectOnModule)
173 Append(sb, Event.Module, ref First);
174
175 string Key = sb.ToString();
176
177 if (!this.eventCache.TryGetValue(Key, out Rec Rec))
178 {
179 Rec = new Rec()
180 {
181 First = Event.Timestamp
182 };
183
184 this.eventCache[Key] = Rec;
185 }
186
187 Rec.Events.Add(Payload);
188 Rec.Last = Event.Timestamp;
189 }
190 finally
191 {
192 this.synchObj.Release();
193 }
194 }
195 else
196 await InternetContent.PostAsync(this.callbackUrl, Payload, this.certificate);
197 }
198
199 private static void Append(StringBuilder sb, string Value, ref bool First)
200 {
201 if (First)
202 First = false;
203 else
204 sb.AppendLine();
205
206 sb.Append(Value);
207 }
208
209 private class Rec
210 {
212 public DateTime First;
213 public DateTime Last;
214 }
215
216 private async Task EventCache_Removed(object Sender, CacheItemEventArgs<string, Rec> e)
217 {
218 await this.synchObj.WaitAsync();
219 try
220 {
221 Rec Rec = e.Value;
222 Dictionary<string, object> Payload = new Dictionary<string, object>()
223 {
224 { "First", Rec.First },
225 { "Last", Rec.Last },
226 { "Count", Rec.Events.Count },
227 { "Collect", new Dictionary<string, object>()
228 {
229 { "OnType", this.collectOnType },
230 { "OnLevel", this.collectOnLevel },
231 { "OnEventId", this.collectOnEventId },
232 { "OnObject", this.collectOnObject },
233 { "OnActor", this.collectOnActor },
234 { "OnFacility", this.collectOnFacility },
235 { "OnModule", this.collectOnModule }
236 }
237 },
238 { "Events", Rec.Events.ToArray() }
239 };
240
241 await InternetContent.PostAsync(this.callbackUrl, Payload, this.certificate);
242 }
243 catch (Exception ex)
244 {
245 Event Event = new Event(EventType.Critical, ex, this.ObjectID, string.Empty, string.Empty,
246 EventLevel.Minor, string.Empty, string.Empty);
247 Event.Avoid(this);
248
249 Log.Event(Event);
250 }
251 finally
252 {
253 this.synchObj.Release();
254 }
255 }
256 }
257}
Static class managing encoding and decoding of internet content.
static Task< ContentResponse > PostAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
Class representing an event.
Definition: Event.cs:11
EventType Type
Type of event.
Definition: Event.cs:122
string Object
Object related to the event.
Definition: Event.cs:137
EventLevel Level
Event Level.
Definition: Event.cs:127
string Actor
Actor responsible for the action causing the event.
Definition: Event.cs:142
string Module
Module where the event is reported.
Definition: Event.cs:157
DateTime Timestamp
Timestamp of event.
Definition: Event.cs:117
string EventId
Computer-readable Event ID identifying type of even.
Definition: Event.cs:147
string Facility
Facility can be either a facility in the network sense or in the system sense.
Definition: Event.cs:152
Base class for event sinks.
Definition: EventSink.cs:9
virtual string ObjectID
Object ID, used when logging events.
Definition: LogObject.cs:26
Event sink sending events to a remote service using POST.
void UpdateCertificate(X509Certificate Certificate)
Updates the certificate used in mTLS negotiation.
WebHookEventSink(string ObjectID, string CallbackUrl, X509Certificate Certificate, int MaxSecondsUsed, int MaxSecondsUnused, bool CollectOnType, bool CollectOnLevel, bool CollectOnEventId, bool CollectOnObject, bool CollectOnActor, bool CollectOnFacility, bool CollectOnModule)
Event sink sending events to a remote service using POST.
WebHookEventSink(string ObjectID, string CallbackUrl)
Event sink sending events to a remote service using POST.
WebHookEventSink(string ObjectID, string CallbackUrl, X509Certificate Certificate)
Event sink sending events to a remote service using POST.
override async Task Queue(Event Event)
Queues an event to be output.
override Task DisposeAsync()
IDisposableAsync.DisposeAsync()
Implements an in-memory cache.
Definition: Cache.cs:17
void Dispose()
IDisposable.Dispose
Definition: Cache.cs:99
bool TryGetValue(KeyType Key, out ValueType Value)
Tries to get a value from the cache.
Definition: Cache.cs:311
void Add(KeyType Key, ValueType Value)
Adds an item to the cache.
Definition: Cache.cs:446
void Clear()
Clears the cache.
Definition: Cache.cs:679
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
Interface for Mutual TLS (mTLS) Clients or TLS servers.
EventLevel
Event level.
Definition: EventLevel.cs:7
EventType
Type of event.
Definition: EventType.cs:7