Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DatabaseConfiguration.cs
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Threading.Tasks;
5using Waher.Content;
17using Waher.Events;
18
20{
25 {
26 private static DatabaseConfiguration instance = null;
27 private static string[] repairedCollections = null;
28
29 private HttpResource selectDatabase = null;
30 private HttpResource testDatabase = null;
31
32 private IDatabasePlugin databasePlugin = null;
33 private string databasePluginName = null;
34 private DatabaseSettings databasePluginSettings = null;
35
36 private SniffableDatabase sniffableDatabase = null;
37 private SniffableLedger sniffableLedger = null;
38
42 [DefaultValueNull]
43 public string DatabasePluginName
44 {
45 get => this.databasePluginName;
46 set => this.databasePluginName = value;
47 }
48
52 [DefaultValueNull]
54 {
55 get => this.databasePluginSettings;
56 set => this.databasePluginSettings = value;
57 }
58
63 {
64 get
65 {
66 if (this.databasePlugin is null)
67 {
68 if (this.databasePluginName is null)
69 return null;
70
71 Type T = Types.GetType(this.databasePluginName);
72 if (!(T is null))
73 this.databasePlugin = Types.Instantiate(T) as IDatabasePlugin;
74 }
75
76 return this.databasePlugin;
77 }
78 }
79
84 {
85 get
86 {
87 if (this.sniffableDatabase is null)
88 this.sniffableDatabase = new SniffableDatabase();
89
90 return this.sniffableDatabase;
91 }
92 }
93
98 {
99 get
100 {
101 if (this.sniffableLedger is null)
102 this.sniffableLedger = new SniffableLedger();
103
104 return this.sniffableLedger;
105 }
106 }
107
111 public static DatabaseConfiguration Instance => instance;
112
116 public static string[] RepairedCollections
117 {
118 get => repairedCollections;
119 internal set => repairedCollections = value;
120 }
121
125 public override string Resource => "/Settings/Database.md";
126
130 public override int Priority => 0;
131
137 public override Task<string> Title(Language Language)
138 {
139 return Language.GetStringAsync(typeof(Gateway), 1, "Database");
140 }
141
145 public override async Task ConfigureSystem()
146 {
148
149 if (!(Plugin is null))
150 await Plugin.ConfigureSettings(this.databasePluginSettings);
151 }
152
157 public override void SetStaticInstance(ISystemConfiguration Configuration)
158 {
159 instance = Configuration as DatabaseConfiguration;
160 }
161
166 public override Task InitSetup(HttpServer WebServer)
167 {
168 this.selectDatabase = WebServer.Register("/Settings/SelectDatabase", null, this.SelectDatabase, true, false, true);
169 this.testDatabase = WebServer.Register("/Settings/TestDatabase", null, this.TestDatabase, true, false, true);
170
171 return base.InitSetup(WebServer);
172 }
173
178 public override Task UnregisterSetup(HttpServer WebServer)
179 {
180 WebServer.Unregister(this.selectDatabase);
181 WebServer.Unregister(this.testDatabase);
182
183 return base.UnregisterSetup(WebServer);
184 }
185
189 protected override string ConfigPrivilege => "Admin.Data.Database";
190
191 private async Task SelectDatabase(HttpRequest Request, HttpResponse Response)
192 {
193 Gateway.AssertUserAuthenticated(Request, this.ConfigPrivilege);
194
195 if (!Request.HasData)
196 throw new BadRequestException();
197
198 object Obj = await Request.DecodeDataAsync();
199 if (!(Obj is string PluginName))
200 throw new BadRequestException();
201
202 Type PluginType = Types.GetType(PluginName)
203 ?? throw new NotFoundException("Database plugin not found: " + PluginName);
204
205 if (!(Types.Instantiate(PluginType) is IDatabasePlugin Plugin))
206 throw new BadRequestException();
207
208 if (this.databasePluginName != PluginName)
209 {
210 this.databasePlugin = Plugin;
211 this.databasePluginName = PluginName;
212 this.databasePluginSettings = Plugin.CreateNewSettings();
213
214 if (string.IsNullOrEmpty(Plugin.SettingsResource))
215 this.Step = 1;
216 else
217 {
218 this.Step = 0;
219 this.Complete = false;
220 }
221 }
222
223 Response.ContentType = JsonCodec.DefaultContentType;
224
225 string Html = string.Empty;
226 bool HasSettings = false;
227 string ResourceName = Plugin?.SettingsResource;
228 if (!string.IsNullOrEmpty(ResourceName))
229 {
230 if (ResourceName.StartsWith("/"))
231 ResourceName = ResourceName.Substring(1);
232
233 ResourceName = ResourceName.Replace('/', Path.DirectorySeparatorChar);
234 ResourceName = Path.Combine(Gateway.RootFolder, ResourceName);
235 if (File.Exists(ResourceName))
236 {
237 string Markdown = await Resources.ReadAllTextAsync(ResourceName);
238 MarkdownSettings Settings = new MarkdownSettings()
239 {
240 Variables = Request.Session
241 };
242 MarkdownDocument Doc = await MarkdownDocument.CreateAsync(Markdown, Settings);
243
244 Html = await Doc.GenerateHTML();
245 Html = HtmlDocument.GetBody(Html);
246 HasSettings = true;
247 }
248 }
249
250 await Response.Write(JSON.Encode(new Dictionary<string, object>()
251 {
252 { "html", Html },
253 { "isDone", this.Step >= 1 },
254 { "hasSettings", HasSettings },
255 { "restart", Database.Locked }
256 }, false));
257 }
258
259 private async Task TestDatabase(HttpRequest Request, HttpResponse Response)
260 {
261 Gateway.AssertUserAuthenticated(Request, this.ConfigPrivilege);
262
263 if (!Request.HasData)
264 throw new BadRequestException();
265
266 object Obj = await Request.DecodeDataAsync();
267 if (!(Obj is Dictionary<string, object> Form))
268 throw new BadRequestException();
269
270 if (!Form.TryGetValue("save", out Obj) ||
271 !(Obj is bool Save) ||
272 !Form.TryGetValue("Plugin", out Obj) ||
273 !(Obj is string PluginName) ||
274 this.databasePluginName != PluginName ||
275 this.databasePlugin is null ||
276 this.databasePluginSettings is null)
277 {
278 throw new BadRequestException();
279 }
280
281 await this.databasePlugin.Test(Form, Save, this.databasePluginSettings);
282
283 if (Save)
284 {
285 this.Step = 1;
286 await Gateway.InternalDatabase.Update(this);
287 }
288
289 Response.ContentType = PlainTextCodec.DefaultContentType;
290
291 if (Database.Locked)
292 await Response.Write("2");
293 else
294 await Response.Write("1");
295
296 await Response.SendResponse();
297 }
298
303 public override Task<bool> SimplifiedConfiguration()
304 {
306
307 this.databasePlugin = Plugin;
308 this.databasePluginName = Plugin.GetType().FullName;
309 this.databasePluginSettings = Plugin.CreateNewSettings();
310 this.Step = 1;
311
312 return Task.FromResult(true);
313 }
314
318 public const string GATEWAY_DB_PROVIDER = nameof(GATEWAY_DB_PROVIDER);
319
324 public override async Task<bool> EnvironmentConfiguration()
325 {
326 string ProviderType = Environment.GetEnvironmentVariable(GATEWAY_DB_PROVIDER);
327 if (string.IsNullOrEmpty(ProviderType))
328 return false;
329
330 Type T = Types.GetType(ProviderType);
331 if (T is null)
332 {
333 this.LogEnvironmentError("Database plugin not found.", GATEWAY_DB_PROVIDER, ProviderType);
334 return false;
335 }
336
338
339 try
340 {
342 }
343 catch (Exception ex)
344 {
345 this.LogEnvironmentError(ex.Message, GATEWAY_DB_PROVIDER, ProviderType);
346 return false;
347 }
348
349 if (Plugin is null)
350 {
351 this.LogEnvironmentError("Unable to instantiate database plugin.", GATEWAY_DB_PROVIDER, ProviderType);
352 return false;
353 }
354
355 DatabaseSettings Settings = Plugin.CreateNewSettings();
356
357 try
358 {
359 if (!await Plugin.TestEnvironmentVariables(this, Settings))
360 return false;
361 }
362 catch (Exception ex)
363 {
364 Log.Exception(ex);
365 return false;
366 }
367
368 this.databasePlugin = Plugin;
369 this.databasePluginName = ProviderType;
370 this.databasePluginSettings = Settings;
371 this.Step = 1;
372
373 return true;
374 }
375
376 }
377}
static string GetBody(string Html)
Extracts the contents of the BODY element in a HTML string.
Helps with common JSON-related tasks.
Definition: JSON.cs:14
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:507
const string DefaultContentType
application/json
Definition: JsonCodec.cs:19
Contains a markdown document. This markdown document class supports original markdown,...
async Task< string > GenerateHTML()
Generates HTML from the markdown text.
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
Contains settings that the Markdown parser uses to customize its behavior.
Static class managing loading of resources stored as embedded resources or in content files.
Definition: Resources.cs:15
static async Task< string > ReadAllTextAsync(string FileName)
Reads a text file asynchronously.
Definition: Resources.cs:205
Plain text encoder/decoder.
const string DefaultContentType
text/plain
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:126
static IUser AssertUserAuthenticated(HttpRequest Request, string Privilege)
Makes sure a request is being made from a session with a successful user login.
Definition: Gateway.cs:3041
static IDatabaseProvider InternalDatabase
Local Internal Encrypted Object Database provider.
Definition: Gateway.cs:2408
static string RootFolder
Web root folder.
Definition: Gateway.cs:2379
static DatabaseConfiguration Instance
Current instance of configuration.
SniffableLedger SniffableLedger
Makes ledger activity sniffable.
override string ConfigPrivilege
Minimum required privilege for a user to be allowed to change the configuration defined by the class.
override int Priority
Priority of the setting. Configurations are sorted in ascending order.
override string Resource
Resource to be redirected to, to perform the configuration.
IDatabasePlugin DatabasePlugin
Current database plugin, if defined, null otherwise.
override Task InitSetup(HttpServer WebServer)
Initializes the setup object.
override async Task< bool > EnvironmentConfiguration()
Environment configuration by configuring values available in environment variables.
override async Task ConfigureSystem()
Is called during startup to configure the system.
static string[] RepairedCollections
Collections repaired during startup.
string DatabasePluginName
Full name of database plugin class.
override void SetStaticInstance(ISystemConfiguration Configuration)
Sets the static instance of the configuration.
SniffableDatabase SniffableDatabase
Makes database activity sniffable.
override Task< bool > SimplifiedConfiguration()
Simplified configuration by configuring simple default values.
override Task UnregisterSetup(HttpServer WebServer)
Unregisters the setup object.
override Task< string > Title(Language Language)
Gets a title for the system configuration.
DatabaseSettings DatabasePluginSettings
Settings for database plugin.
Class that can be used to sniff on database updates.
Class that can be used to sniff on ledger activity.
Abstract base class for multi-step system configurations.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
Represents an HTTP request.
Definition: HttpRequest.cs:18
bool HasData
If the request has data.
Definition: HttpRequest.cs:74
async Task< object > DecodeDataAsync()
Decodes data sent in request.
Definition: HttpRequest.cs:95
Base class for all HTTP resources.
Definition: HttpResource.cs:23
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:21
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
async Task Write(byte[] Data)
Returns binary data in the response.
Implements an HTTP server.
Definition: HttpServer.cs:36
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
Definition: HttpServer.cs:1287
bool Unregister(HttpResource Resource)
Unregisters a resource from the server.
Definition: HttpServer.cs:1438
The server has not found anything matching the Request-URI. No indication is given of whether the con...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static bool Locked
If the datbase provider has been locked for the rest of the run-time of the application.
Definition: Database.cs:87
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static Type GetType(string FullName)
Gets a type, given its full name.
Definition: Types.cs:41
static object Instantiate(Type Type, params object[] Arguments)
Returns an instance of the type Type . If one needs to be created, it is. If the constructor requires...
Definition: Types.cs:1353
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
Interface for system configurations. The gateway will scan all module for system configuration classe...
Task Update(object Object)
Updates an object in the database.