diff --git a/_administration_controller_8cs_source.html b/_administration_controller_8cs_source.html index 2af6f0386d..b662a723d5 100644 --- a/_administration_controller_8cs_source.html +++ b/_administration_controller_8cs_source.html @@ -520,7 +520,7 @@ $(document).ready(function() { init_codefold(0); });
Tgstation.Server.Host.Configuration
Definition ControlPanelConfiguration.cs:4
Tgstation.Server.Host.Controllers.Results
Definition LimitedStreamResult.cs:14
Tgstation.Server.Host.Controllers
Definition AdministrationController.cs:34
-
Tgstation.Server.Host.Core
Definition Application.cs:76
+
Tgstation.Server.Host.Core
Definition Application.cs:77
Tgstation.Server.Host.Core.ServerUpdateResult
ServerUpdateResult
The result of a call to start a server update.
Definition ServerUpdateResult.cs:7
Tgstation.Server.Host.Database
Definition DatabaseCollection.cs:11
Tgstation.Server.Host.Extensions
Definition ApplicationBuilderExtensions.cs:21
diff --git a/_advanced_watchdog_8cs_source.html b/_advanced_watchdog_8cs_source.html index 8b82d83aef..b1cf1e6fed 100644 --- a/_advanced_watchdog_8cs_source.html +++ b/_advanced_watchdog_8cs_source.html @@ -554,7 +554,7 @@ $(document).ready(function() { init_codefold(0); });
Tgstation.Server.Host.Components.Watchdog
Definition AdvancedWatchdog.cs:22
Tgstation.Server.Host.Components.Watchdog.MonitorAction
MonitorAction
The action for the monitor loop to take when control is returned to it.
Definition MonitorAction.cs:7
Tgstation.Server.Host.Components.Watchdog.MonitorActivationReason
MonitorActivationReason
Reasons for the monitor to wake up.
Definition MonitorActivationReason.cs:7
-
Tgstation.Server.Host.Core
Definition Application.cs:76
+
Tgstation.Server.Host.Core
Definition Application.cs:77
Tgstation.Server.Host.IO
Definition BufferedFileStreamProvider.cs:9
Tgstation.Server.Host.Jobs
Definition IJobManager.cs:8
Tgstation.Server.Host.Utils
Definition AbstractHttpClientFactory.cs:10
diff --git a/_api_root_controller_8cs_source.html b/_api_root_controller_8cs_source.html index 306b4e96f7..c6ffc2cb75 100644 --- a/_api_root_controller_8cs_source.html +++ b/_api_root_controller_8cs_source.html @@ -284,7 +284,7 @@ $(document).ready(function() { init_codefold(0); });
Tgstation.Server.Host.Components.Interop
Definition BridgeCommandType.cs:2
Tgstation.Server.Host.Configuration
Definition ControlPanelConfiguration.cs:4
Tgstation.Server.Host.Controllers
Definition AdministrationController.cs:34
-
Tgstation.Server.Host.Core
Definition Application.cs:76
+
Tgstation.Server.Host.Core
Definition Application.cs:77
Tgstation.Server.Host.Core.ServerUpdateResult.UpdateInProgress
@ UpdateInProgress
Another update is already in progress.
Tgstation.Server.Host.Database
Definition DatabaseCollection.cs:11
Tgstation.Server.Host.GraphQL.Mutations.Payloads
Definition LoginPayload.cs:7
diff --git a/_application_8cs_source.html b/_application_8cs_source.html index 81be5b972d..55fcf866d1 100644 --- a/_application_8cs_source.html +++ b/_application_8cs_source.html @@ -93,723 +93,728 @@ $(document).ready(function() { init_codefold(0); });
9using Elastic.CommonSchema.Serilog;
10
11using HotChocolate.AspNetCore;
-
12using HotChocolate.Types;
-
13
-
14using Microsoft.AspNetCore.Authentication;
-
15using Microsoft.AspNetCore.Authentication.JwtBearer;
-
16using Microsoft.AspNetCore.Builder;
-
17using Microsoft.AspNetCore.Cors.Infrastructure;
-
18using Microsoft.AspNetCore.Hosting;
-
19using Microsoft.AspNetCore.Http;
-
20using Microsoft.AspNetCore.Http.Connections;
-
21using Microsoft.AspNetCore.Identity;
-
22using Microsoft.AspNetCore.Mvc.Infrastructure;
-
23using Microsoft.AspNetCore.SignalR;
-
24using Microsoft.Extensions.Configuration;
-
25using Microsoft.Extensions.DependencyInjection;
-
26using Microsoft.Extensions.Hosting;
-
27using Microsoft.Extensions.Logging;
-
28using Microsoft.Extensions.Options;
-
29
-
30using Newtonsoft.Json;
-
31
-
32using Serilog;
-
33using Serilog.Events;
-
34using Serilog.Formatting.Display;
-
35using Serilog.Sinks.Elasticsearch;
-
36
-
37using Tgstation.Server.Api;
-
38using Tgstation.Server.Api.Hubs;
-
39using Tgstation.Server.Api.Models;
-
40using Tgstation.Server.Common.Http;
-
41using Tgstation.Server.Host.Authority;
-
42using Tgstation.Server.Host.Authority.Core;
-
43using Tgstation.Server.Host.Components;
-
44using Tgstation.Server.Host.Components.Chat;
-
45using Tgstation.Server.Host.Components.Deployment.Remote;
-
46using Tgstation.Server.Host.Components.Engine;
-
47using Tgstation.Server.Host.Components.Events;
-
48using Tgstation.Server.Host.Components.Interop;
-
49using Tgstation.Server.Host.Components.Interop.Bridge;
-
50using Tgstation.Server.Host.Components.Repository;
-
51using Tgstation.Server.Host.Components.Session;
-
52using Tgstation.Server.Host.Components.Watchdog;
-
53using Tgstation.Server.Host.Configuration;
-
54using Tgstation.Server.Host.Controllers;
-
55using Tgstation.Server.Host.Controllers.Results;
-
56using Tgstation.Server.Host.Database;
-
57using Tgstation.Server.Host.Extensions;
-
58using Tgstation.Server.Host.GraphQL;
-
59using Tgstation.Server.Host.GraphQL.Subscriptions;
-
60using Tgstation.Server.Host.GraphQL.Types;
-
61using Tgstation.Server.Host.GraphQL.Types.Interceptors;
-
62using Tgstation.Server.Host.GraphQL.Types.Scalars;
-
63using Tgstation.Server.Host.IO;
-
64using Tgstation.Server.Host.Jobs;
-
65using Tgstation.Server.Host.Properties;
-
66using Tgstation.Server.Host.Security;
-
67using Tgstation.Server.Host.Security.OAuth;
-
68using Tgstation.Server.Host.Setup;
-
69using Tgstation.Server.Host.Swarm;
-
70using Tgstation.Server.Host.System;
-
71using Tgstation.Server.Host.Transfer;
-
72using Tgstation.Server.Host.Utils;
-
73using Tgstation.Server.Shared;
-
74
-
-
75namespace Tgstation.Server.Host.Core
-
76{
-
80#pragma warning disable CA1506
-
-
81 public sealed class Application : SetupApplication
-
82 {
-
86 readonly IWebHostEnvironment hostingEnvironment;
-
87
- -
92
-
- -
98 {
-
99 var assemblyInformationProvider = new AssemblyInformationProvider();
-
100 var ioManager = new DefaultIOManager();
-
101 return new ServerFactory(
-
102 assemblyInformationProvider,
-
103 ioManager);
-
104 }
+
12using HotChocolate.Subscriptions;
+
13using HotChocolate.Types;
+
14
+
15using Microsoft.AspNetCore.Authentication;
+
16using Microsoft.AspNetCore.Authentication.JwtBearer;
+
17using Microsoft.AspNetCore.Builder;
+
18using Microsoft.AspNetCore.Cors.Infrastructure;
+
19using Microsoft.AspNetCore.Hosting;
+
20using Microsoft.AspNetCore.Http;
+
21using Microsoft.AspNetCore.Http.Connections;
+
22using Microsoft.AspNetCore.Identity;
+
23using Microsoft.AspNetCore.Mvc.Infrastructure;
+
24using Microsoft.AspNetCore.SignalR;
+
25using Microsoft.Extensions.Configuration;
+
26using Microsoft.Extensions.DependencyInjection;
+
27using Microsoft.Extensions.Hosting;
+
28using Microsoft.Extensions.Logging;
+
29using Microsoft.Extensions.Options;
+
30
+
31using Newtonsoft.Json;
+
32
+
33using Serilog;
+
34using Serilog.Events;
+
35using Serilog.Formatting.Display;
+
36using Serilog.Sinks.Elasticsearch;
+
37
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
75
+
+ +
77{
+
81#pragma warning disable CA1506
+
+
82 public sealed class Application : SetupApplication
+
83 {
+
87 readonly IWebHostEnvironment hostingEnvironment;
+
88
+ +
93
+
+ +
99 {
+
100 var assemblyInformationProvider = new AssemblyInformationProvider();
+
101 var ioManager = new DefaultIOManager();
+
102 return new ServerFactory(
+
103 assemblyInformationProvider,
+
104 ioManager);
+
105 }
-
105
-
-
112 static void AddWatchdog<TSystemWatchdogFactory>(IServiceCollection services, IPostSetupServices postSetupServices)
-
113 where TSystemWatchdogFactory : class, IWatchdogFactory
-
114 {
-
115 if (postSetupServices.GeneralConfiguration.UseBasicWatchdog)
-
116 services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
-
117 else
-
118 services.AddSingleton<IWatchdogFactory, TSystemWatchdogFactory>();
-
119 }
+
106
+
+
113 static void AddWatchdog<TSystemWatchdogFactory>(IServiceCollection services, IPostSetupServices postSetupServices)
+
114 where TSystemWatchdogFactory : class, IWatchdogFactory
+
115 {
+
116 if (postSetupServices.GeneralConfiguration.UseBasicWatchdog)
+
117 services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
+
118 else
+
119 services.AddSingleton<IWatchdogFactory, TSystemWatchdogFactory>();
+
120 }
-
120
-
- -
127 IConfiguration configuration,
-
128 IWebHostEnvironment hostingEnvironment)
-
129 : base(configuration)
-
130 {
-
131 this.hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
-
132 }
+
121
+
+ +
128 IConfiguration configuration,
+
129 IWebHostEnvironment hostingEnvironment)
+
130 : base(configuration)
+
131 {
+
132 this.hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
+
133 }
-
133
-
-
141 public void ConfigureServices(
-
142 IServiceCollection services,
-
143 IAssemblyInformationProvider assemblyInformationProvider,
-
144 IIOManager ioManager,
-
145 IPostSetupServices postSetupServices)
-
146 {
-
147 ConfigureServices(services, assemblyInformationProvider, ioManager);
-
148
-
149 ArgumentNullException.ThrowIfNull(postSetupServices);
-
150
-
151 // configure configuration
-
152 services.UseStandardConfig<UpdatesConfiguration>(Configuration);
-
153 services.UseStandardConfig<ControlPanelConfiguration>(Configuration);
-
154 services.UseStandardConfig<SwarmConfiguration>(Configuration);
-
155 services.UseStandardConfig<SessionConfiguration>(Configuration);
-
156 services.UseStandardConfig<TelemetryConfiguration>(Configuration);
-
157
-
158 // enable options which give us config reloading
-
159 services.AddOptions();
-
160
-
161 // Set the timeout for IHostedService.StopAsync
-
162 services.Configure<HostOptions>(
-
163 opts => opts.ShutdownTimeout = TimeSpan.FromMinutes(postSetupServices.GeneralConfiguration.RestartTimeoutMinutes));
-
164
-
165 static LogEventLevel? ConvertSeriLogLevel(LogLevel logLevel) =>
-
166 logLevel switch
-
167 {
-
168 LogLevel.Critical => LogEventLevel.Fatal,
-
169 LogLevel.Debug => LogEventLevel.Debug,
-
170 LogLevel.Error => LogEventLevel.Error,
-
171 LogLevel.Information => LogEventLevel.Information,
-
172 LogLevel.Trace => LogEventLevel.Verbose,
-
173 LogLevel.Warning => LogEventLevel.Warning,
-
174 LogLevel.None => null,
-
175 _ => throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid log level {0}", logLevel)),
-
176 };
-
177
-
178 var microsoftEventLevel = ConvertSeriLogLevel(postSetupServices.FileLoggingConfiguration.MicrosoftLogLevel);
-
179 var elasticsearchConfiguration = postSetupServices.ElasticsearchConfiguration;
-
180 services.SetupLogging(
-
181 config =>
-
182 {
-
183 if (microsoftEventLevel.HasValue)
-
184 {
-
185 config.MinimumLevel.Override("Microsoft", microsoftEventLevel.Value);
-
186 config.MinimumLevel.Override("System.Net.Http.HttpClient", microsoftEventLevel.Value);
-
187 }
-
188 },
-
189 sinkConfig =>
-
190 {
-
191 if (postSetupServices.FileLoggingConfiguration.Disable)
-
192 return;
-
193
-
194 var logPath = postSetupServices.FileLoggingConfiguration.GetFullLogDirectory(
-
195 ioManager,
-
196 assemblyInformationProvider,
-
197 postSetupServices.PlatformIdentifier);
-
198
-
199 var logEventLevel = ConvertSeriLogLevel(postSetupServices.FileLoggingConfiguration.LogLevel);
-
200
-
201 var formatter = new MessageTemplateTextFormatter(
-
202 "{Timestamp:o} "
- -
204 + "): [{Level:u3}] {SourceContext:l}: {Message} ({EventId:x8}){NewLine}{Exception}",
-
205 null);
-
206
-
207 logPath = ioManager.ConcatPath(logPath, "tgs-.log");
-
208 var rollingFileConfig = sinkConfig.File(
-
209 formatter,
-
210 logPath,
-
211 logEventLevel ?? LogEventLevel.Verbose,
-
212 50 * 1024 * 1024, // 50MB max size
-
213 flushToDiskInterval: TimeSpan.FromSeconds(2),
-
214 rollingInterval: RollingInterval.Day,
-
215 rollOnFileSizeLimit: true);
-
216 },
-
217 elasticsearchConfiguration.Enable
-
218 ? new ElasticsearchSinkOptions(elasticsearchConfiguration.Host ?? throw new InvalidOperationException($"Missing {ElasticsearchConfiguration.Section}:{nameof(elasticsearchConfiguration.Host)}!"))
-
219 {
-
220 // Yes I know this means they cannot use a self signed cert unless they also have authentication, but lets be real here
-
221 // No one is going to be doing one of those but not the other
-
222 ModifyConnectionSettings = connectionConfigration => (!String.IsNullOrWhiteSpace(elasticsearchConfiguration.Username) && !String.IsNullOrWhiteSpace(elasticsearchConfiguration.Password))
-
223 ? connectionConfigration
-
224 .BasicAuthentication(
-
225 elasticsearchConfiguration.Username,
-
226 elasticsearchConfiguration.Password)
-
227 .ServerCertificateValidationCallback((o, certificate, chain, errors) => true)
-
228 : null,
-
229 CustomFormatter = new EcsTextFormatter(),
-
230 AutoRegisterTemplate = true,
-
231 AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
-
232 IndexFormat = "tgs-logs",
-
233 }
-
234 : null,
-
235 postSetupServices.InternalConfiguration,
-
236 postSetupServices.FileLoggingConfiguration);
-
237
-
238 // configure authentication pipeline
- -
240
-
241 // add mvc, configure the json serializer settings
-
242 var jsonVersionConverterList = new List<JsonConverter>
-
243 {
-
244 new VersionConverter(),
-
245 };
-
246
-
247 void ConfigureNewtonsoftJsonSerializerSettingsForApi(JsonSerializerSettings settings)
-
248 {
-
249 settings.NullValueHandling = NullValueHandling.Ignore;
-
250 settings.CheckAdditionalContent = true;
-
251 settings.MissingMemberHandling = MissingMemberHandling.Error;
-
252 settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
-
253 settings.Converters = jsonVersionConverterList;
-
254 }
-
255
-
256 services
-
257 .AddMvc(options =>
-
258 {
-
259 options.ReturnHttpNotAcceptable = true;
-
260 options.RespectBrowserAcceptHeader = true;
-
261 })
-
262 .AddNewtonsoftJson(options =>
-
263 {
-
264 options.AllowInputFormatterExceptionMessages = true;
-
265 ConfigureNewtonsoftJsonSerializerSettingsForApi(options.SerializerSettings);
-
266 });
-
267
-
268 services.AddSignalR(
-
269 options =>
-
270 {
-
271 options.AddFilter<AuthorizationContextHubFilter>();
-
272 })
-
273 .AddNewtonsoftJsonProtocol(options =>
-
274 {
-
275 ConfigureNewtonsoftJsonSerializerSettingsForApi(options.PayloadSerializerSettings);
-
276 });
-
277
-
278 services.AddHub<JobsHub, IJobsHub>();
-
279
-
280 if (postSetupServices.GeneralConfiguration.HostApiDocumentation)
-
281 {
-
282 string GetDocumentationFilePath(string assemblyLocation) => ioManager.ConcatPath(ioManager.GetDirectoryName(assemblyLocation), String.Concat(ioManager.GetFileNameWithoutExtension(assemblyLocation), ".xml"));
-
283 var assemblyDocumentationPath = GetDocumentationFilePath(GetType().Assembly.Location);
-
284 var apiDocumentationPath = GetDocumentationFilePath(typeof(ApiHeaders).Assembly.Location);
-
285 services.AddSwaggerGen(genOptions => SwaggerConfiguration.Configure(genOptions, assemblyDocumentationPath, apiDocumentationPath));
-
286 services.AddSwaggerGenNewtonsoftSupport();
-
287 }
-
288
-
289 // CORS conditionally enabled later
-
290 services.AddCors();
-
291
-
292 // Enable managed HTTP clients
-
293 services.AddHttpClient();
- -
295
-
296 // configure graphql
-
297 if (postSetupServices.InternalConfiguration.EnableGraphQL)
-
298 services
- -
300 .AddGraphQLServer()
-
301 .AddAuthorization()
-
302 .ModifyOptions(options =>
-
303 {
-
304 options.EnsureAllNodesCanBeResolved = true;
-
305 options.EnableFlagEnums = true;
-
306 })
-
307#if DEBUG
-
308 .ModifyCostOptions(options =>
-
309 {
-
310 options.EnforceCostLimits = false;
-
311 })
-
312#endif
-
313 .AddMutationConventions()
-
314 .AddInMemorySubscriptions()
-
315 .AddGlobalObjectIdentification()
-
316 .AddQueryFieldToMutationPayloads()
-
317 .ModifyOptions(options =>
-
318 {
-
319 options.EnableDefer = true;
-
320 })
-
321 .ModifyPagingOptions(pagingOptions =>
-
322 {
-
323 pagingOptions.IncludeTotalCount = true;
-
324 pagingOptions.RequirePagingBoundaries = false;
-
325 pagingOptions.DefaultPageSize = ApiController.DefaultPageSize;
-
326 pagingOptions.MaxPageSize = ApiController.MaximumPageSize;
-
327 })
-
328 .AddFiltering()
-
329 .AddSorting()
-
330 .AddHostTypes()
-
331 .AddErrorFilter<ErrorMessageFilter>()
-
332 .AddType<StandaloneNode>()
-
333 .AddType<LocalGateway>()
-
334 .AddType<RemoteGateway>()
-
335 .AddType<GraphQL.Types.UserName>()
-
336 .AddType<UnsignedIntType>()
-
337 .BindRuntimeType<Version, SemverType>()
-
338 .TryAddTypeInterceptor<RightsTypeInterceptor>()
-
339 .AddQueryType<Query>()
-
340 .AddMutationType<Mutation>()
-
341 .AddSubscriptionType<Subscription>();
-
342
-
343 void AddTypedContext<TContext>()
-
344 where TContext : DatabaseContext
-
345 {
-
346 var configureAction = DatabaseContext.GetConfigureAction<TContext>();
+
134
+
+
142 public void ConfigureServices(
+
143 IServiceCollection services,
+
144 IAssemblyInformationProvider assemblyInformationProvider,
+
145 IIOManager ioManager,
+
146 IPostSetupServices postSetupServices)
+
147 {
+
148 ConfigureServices(services, assemblyInformationProvider, ioManager);
+
149
+
150 ArgumentNullException.ThrowIfNull(postSetupServices);
+
151
+
152 // configure configuration
+
153 services.UseStandardConfig<UpdatesConfiguration>(Configuration);
+
154 services.UseStandardConfig<ControlPanelConfiguration>(Configuration);
+
155 services.UseStandardConfig<SwarmConfiguration>(Configuration);
+
156 services.UseStandardConfig<SessionConfiguration>(Configuration);
+
157 services.UseStandardConfig<TelemetryConfiguration>(Configuration);
+
158
+
159 // enable options which give us config reloading
+
160 services.AddOptions();
+
161
+
162 // Set the timeout for IHostedService.StopAsync
+
163 services.Configure<HostOptions>(
+
164 opts => opts.ShutdownTimeout = TimeSpan.FromMinutes(postSetupServices.GeneralConfiguration.RestartTimeoutMinutes));
+
165
+
166 static LogEventLevel? ConvertSeriLogLevel(LogLevel logLevel) =>
+
167 logLevel switch
+
168 {
+
169 LogLevel.Critical => LogEventLevel.Fatal,
+
170 LogLevel.Debug => LogEventLevel.Debug,
+
171 LogLevel.Error => LogEventLevel.Error,
+
172 LogLevel.Information => LogEventLevel.Information,
+
173 LogLevel.Trace => LogEventLevel.Verbose,
+
174 LogLevel.Warning => LogEventLevel.Warning,
+
175 LogLevel.None => null,
+
176 _ => throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid log level {0}", logLevel)),
+
177 };
+
178
+
179 var microsoftEventLevel = ConvertSeriLogLevel(postSetupServices.FileLoggingConfiguration.MicrosoftLogLevel);
+
180 var elasticsearchConfiguration = postSetupServices.ElasticsearchConfiguration;
+
181 services.SetupLogging(
+
182 config =>
+
183 {
+
184 if (microsoftEventLevel.HasValue)
+
185 {
+
186 config.MinimumLevel.Override("Microsoft", microsoftEventLevel.Value);
+
187 config.MinimumLevel.Override("System.Net.Http.HttpClient", microsoftEventLevel.Value);
+
188 }
+
189 },
+
190 sinkConfig =>
+
191 {
+
192 if (postSetupServices.FileLoggingConfiguration.Disable)
+
193 return;
+
194
+
195 var logPath = postSetupServices.FileLoggingConfiguration.GetFullLogDirectory(
+
196 ioManager,
+
197 assemblyInformationProvider,
+
198 postSetupServices.PlatformIdentifier);
+
199
+
200 var logEventLevel = ConvertSeriLogLevel(postSetupServices.FileLoggingConfiguration.LogLevel);
+
201
+
202 var formatter = new MessageTemplateTextFormatter(
+
203 "{Timestamp:o} "
+ +
205 + "): [{Level:u3}] {SourceContext:l}: {Message} ({EventId:x8}){NewLine}{Exception}",
+
206 null);
+
207
+
208 logPath = ioManager.ConcatPath(logPath, "tgs-.log");
+
209 var rollingFileConfig = sinkConfig.File(
+
210 formatter,
+
211 logPath,
+
212 logEventLevel ?? LogEventLevel.Verbose,
+
213 50 * 1024 * 1024, // 50MB max size
+
214 flushToDiskInterval: TimeSpan.FromSeconds(2),
+
215 rollingInterval: RollingInterval.Day,
+
216 rollOnFileSizeLimit: true);
+
217 },
+
218 elasticsearchConfiguration.Enable
+
219 ? new ElasticsearchSinkOptions(elasticsearchConfiguration.Host ?? throw new InvalidOperationException($"Missing {ElasticsearchConfiguration.Section}:{nameof(elasticsearchConfiguration.Host)}!"))
+
220 {
+
221 // Yes I know this means they cannot use a self signed cert unless they also have authentication, but lets be real here
+
222 // No one is going to be doing one of those but not the other
+
223 ModifyConnectionSettings = connectionConfigration => (!String.IsNullOrWhiteSpace(elasticsearchConfiguration.Username) && !String.IsNullOrWhiteSpace(elasticsearchConfiguration.Password))
+
224 ? connectionConfigration
+
225 .BasicAuthentication(
+
226 elasticsearchConfiguration.Username,
+
227 elasticsearchConfiguration.Password)
+
228 .ServerCertificateValidationCallback((o, certificate, chain, errors) => true)
+
229 : null,
+
230 CustomFormatter = new EcsTextFormatter(),
+
231 AutoRegisterTemplate = true,
+
232 AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
+
233 IndexFormat = "tgs-logs",
+
234 }
+
235 : null,
+
236 postSetupServices.InternalConfiguration,
+
237 postSetupServices.FileLoggingConfiguration);
+
238
+
239 // configure authentication pipeline
+ +
241
+
242 // add mvc, configure the json serializer settings
+
243 var jsonVersionConverterList = new List<JsonConverter>
+
244 {
+
245 new VersionConverter(),
+
246 };
+
247
+
248 void ConfigureNewtonsoftJsonSerializerSettingsForApi(JsonSerializerSettings settings)
+
249 {
+
250 settings.NullValueHandling = NullValueHandling.Ignore;
+
251 settings.CheckAdditionalContent = true;
+
252 settings.MissingMemberHandling = MissingMemberHandling.Error;
+
253 settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
254 settings.Converters = jsonVersionConverterList;
+
255 }
+
256
+
257 services
+
258 .AddMvc(options =>
+
259 {
+
260 options.ReturnHttpNotAcceptable = true;
+
261 options.RespectBrowserAcceptHeader = true;
+
262 })
+
263 .AddNewtonsoftJson(options =>
+
264 {
+
265 options.AllowInputFormatterExceptionMessages = true;
+
266 ConfigureNewtonsoftJsonSerializerSettingsForApi(options.SerializerSettings);
+
267 });
+
268
+
269 services.AddSignalR(
+
270 options =>
+
271 {
+
272 options.AddFilter<AuthorizationContextHubFilter>();
+
273 })
+
274 .AddNewtonsoftJsonProtocol(options =>
+
275 {
+
276 ConfigureNewtonsoftJsonSerializerSettingsForApi(options.PayloadSerializerSettings);
+
277 });
+
278
+
279 services.AddHub<JobsHub, IJobsHub>();
+
280
+
281 if (postSetupServices.GeneralConfiguration.HostApiDocumentation)
+
282 {
+
283 string GetDocumentationFilePath(string assemblyLocation) => ioManager.ConcatPath(ioManager.GetDirectoryName(assemblyLocation), String.Concat(ioManager.GetFileNameWithoutExtension(assemblyLocation), ".xml"));
+
284 var assemblyDocumentationPath = GetDocumentationFilePath(GetType().Assembly.Location);
+
285 var apiDocumentationPath = GetDocumentationFilePath(typeof(ApiHeaders).Assembly.Location);
+
286 services.AddSwaggerGen(genOptions => SwaggerConfiguration.Configure(genOptions, assemblyDocumentationPath, apiDocumentationPath));
+
287 services.AddSwaggerGenNewtonsoftSupport();
+
288 }
+
289
+
290 // CORS conditionally enabled later
+
291 services.AddCors();
+
292
+
293 // Enable managed HTTP clients
+
294 services.AddHttpClient();
+ +
296
+
297 // configure graphql
+
298 if (postSetupServices.InternalConfiguration.EnableGraphQL)
+
299 services
+
300 .AddScoped<GraphQL.Subscriptions.ITopicEventReceiver, ShutdownAwareTopicEventReceiver>()
+
301 .AddGraphQLServer()
+
302 .AddAuthorization()
+
303 .ModifyOptions(options =>
+
304 {
+
305 options.EnsureAllNodesCanBeResolved = true;
+
306 options.EnableFlagEnums = true;
+
307 })
+
308#if DEBUG
+
309 .ModifyCostOptions(options =>
+
310 {
+
311 options.EnforceCostLimits = false;
+
312 })
+
313#endif
+
314 .AddMutationConventions()
+
315 .AddInMemorySubscriptions(
+
316 new SubscriptionOptions
+
317 {
+
318 TopicBufferCapacity = 1024, // mainly so high for tests, not possible to DoS the server without authentication and some other access to generate messages
+
319 })
+
320 .AddGlobalObjectIdentification()
+
321 .AddQueryFieldToMutationPayloads()
+
322 .ModifyOptions(options =>
+
323 {
+
324 options.EnableDefer = true;
+
325 })
+
326 .ModifyPagingOptions(pagingOptions =>
+
327 {
+
328 pagingOptions.IncludeTotalCount = true;
+
329 pagingOptions.RequirePagingBoundaries = false;
+
330 pagingOptions.DefaultPageSize = ApiController.DefaultPageSize;
+
331 pagingOptions.MaxPageSize = ApiController.MaximumPageSize;
+
332 })
+
333 .AddFiltering()
+
334 .AddSorting()
+
335 .AddHostTypes()
+
336 .AddErrorFilter<ErrorMessageFilter>()
+
337 .AddType<StandaloneNode>()
+
338 .AddType<LocalGateway>()
+
339 .AddType<RemoteGateway>()
+
340 .AddType<GraphQL.Types.UserName>()
+
341 .AddType<UnsignedIntType>()
+
342 .BindRuntimeType<Version, SemverType>()
+
343 .TryAddTypeInterceptor<RightsTypeInterceptor>()
+
344 .AddQueryType<Query>()
+
345 .AddMutationType<Mutation>()
+
346 .AddSubscriptionType<Subscription>();
347
-
348 services.AddDbContextPool<TContext>((serviceProvider, builder) =>
-
349 {
-
350 if (hostingEnvironment.IsDevelopment())
-
351 builder.EnableSensitiveDataLogging();
+
348 void AddTypedContext<TContext>()
+
349 where TContext : DatabaseContext
+
350 {
+
351 var configureAction = DatabaseContext.GetConfigureAction<TContext>();
352
-
353 var databaseConfigOptions = serviceProvider.GetRequiredService<IOptions<DatabaseConfiguration>>();
-
354 var databaseConfig = databaseConfigOptions.Value ?? throw new InvalidOperationException("DatabaseConfiguration missing!");
-
355 configureAction(builder, databaseConfig);
-
356 });
-
357 services.AddScoped<IDatabaseContext>(x => x.GetRequiredService<TContext>());
-
358 }
-
359
-
360 // add the correct database context type
-
361 var dbType = postSetupServices.DatabaseConfiguration.DatabaseType;
-
362 switch (dbType)
-
363 {
-
364 case DatabaseType.MySql:
-
365 case DatabaseType.MariaDB:
-
366 AddTypedContext<MySqlDatabaseContext>();
-
367 break;
-
368 case DatabaseType.SqlServer:
-
369 AddTypedContext<SqlServerDatabaseContext>();
-
370 break;
-
371 case DatabaseType.Sqlite:
-
372 AddTypedContext<SqliteDatabaseContext>();
-
373 break;
-
374 case DatabaseType.PostgresSql:
-
375 AddTypedContext<PostgresSqlDatabaseContext>();
-
376 break;
-
377 default:
-
378 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid {0}: {1}!", nameof(DatabaseType), dbType));
-
379 }
-
380
-
381 // configure other database services
-
382 services.AddSingleton<IDatabaseContextFactory, DatabaseContextFactory>();
-
383 services.AddSingleton<IDatabaseSeeder, DatabaseSeeder>();
-
384
-
385 // configure other security services
-
386 services.AddSingleton<IOAuthProviders, OAuthProviders>();
-
387 services.AddSingleton<IIdentityCache, IdentityCache>();
-
388 services.AddSingleton<ICryptographySuite, CryptographySuite>();
-
389 services.AddSingleton<ITokenFactory, TokenFactory>();
- -
391 services.AddSingleton<IPasswordHasher<Models.User>, PasswordHasher<Models.User>>();
-
392
-
393 // configure platform specific services
-
394 if (postSetupServices.PlatformIdentifier.IsWindows)
-
395 {
-
396 AddWatchdog<WindowsWatchdogFactory>(services, postSetupServices);
- - -
399 services.AddSingleton<ByondInstallerBase, WindowsByondInstaller>();
-
400 services.AddSingleton<OpenDreamInstaller, WindowsOpenDreamInstaller>();
-
401 services.AddSingleton<IPostWriteHandler, WindowsPostWriteHandler>();
-
402 services.AddSingleton<IProcessFeatures, WindowsProcessFeatures>();
-
403
-
404 services.AddSingleton<WindowsNetworkPromptReaper>();
-
405 services.AddSingleton<INetworkPromptReaper>(x => x.GetRequiredService<WindowsNetworkPromptReaper>());
-
406 services.AddSingleton<IHostedService>(x => x.GetRequiredService<WindowsNetworkPromptReaper>());
-
407 }
-
408 else
-
409 {
-
410 AddWatchdog<PosixWatchdogFactory>(services, postSetupServices);
-
411 services.AddSingleton<ISystemIdentityFactory, PosixSystemIdentityFactory>();
-
412 services.AddSingleton<IFilesystemLinkFactory, PosixFilesystemLinkFactory>();
-
413 services.AddSingleton<ByondInstallerBase, PosixByondInstaller>();
-
414 services.AddSingleton<OpenDreamInstaller>();
-
415 services.AddSingleton<IPostWriteHandler, PosixPostWriteHandler>();
-
416
-
417 services.AddSingleton<IProcessFeatures, PosixProcessFeatures>();
-
418 services.AddHostedService<PosixProcessFeatures>();
-
419
-
420 // PosixProcessFeatures also needs a IProcessExecutor for gcore
-
421 services.AddSingleton(x => new Lazy<IProcessExecutor>(() => x.GetRequiredService<IProcessExecutor>(), true));
-
422 services.AddSingleton<INetworkPromptReaper, PosixNetworkPromptReaper>();
-
423
-
424 services.AddHostedService<PosixSignalHandler>();
-
425 }
-
426
-
427 // only global repo manager should be for the OD repo
-
428 // god help me if we need more
-
429 var openDreamRepositoryDirectory = ioManager.ConcatPath(
-
430 ioManager.GetPathInLocalDirectory(assemblyInformationProvider),
-
431 "OpenDreamRepository");
-
432 services.AddSingleton(
-
433 services => services
-
434 .GetRequiredService<IRepositoryManagerFactory>()
-
435 .CreateRepositoryManager(
- -
437 services.GetRequiredService<IIOManager>(),
-
438 openDreamRepositoryDirectory),
-
439 new NoopEventConsumer()));
-
440
-
441 services.AddSingleton(
-
442 serviceProvider => new Dictionary<EngineType, IEngineInstaller>
-
443 {
-
444 { EngineType.Byond, serviceProvider.GetRequiredService<ByondInstallerBase>() },
-
445 { EngineType.OpenDream, serviceProvider.GetRequiredService<OpenDreamInstaller>() },
-
446 }
-
447 .ToFrozenDictionary());
-
448 services.AddSingleton<IEngineInstaller, DelegatingEngineInstaller>();
-
449
-
450 if (postSetupServices.InternalConfiguration.UsingSystemD)
-
451 services.AddHostedService<SystemDManager>();
-
452
-
453 // configure file transfer services
-
454 services.AddSingleton<FileTransferService>();
-
455 services.AddSingleton<IFileTransferStreamHandler>(x => x.GetRequiredService<FileTransferService>());
-
456 services.AddSingleton<IFileTransferTicketProvider>(x => x.GetRequiredService<FileTransferService>());
- -
458
-
459 // configure swarm service
-
460 services.AddSingleton<SwarmService>();
-
461 services.AddSingleton<ISwarmService>(x => x.GetRequiredService<SwarmService>());
-
462 services.AddSingleton<ISwarmOperations>(x => x.GetRequiredService<SwarmService>());
-
463 services.AddSingleton<ISwarmServiceController>(x => x.GetRequiredService<SwarmService>());
-
464
-
465 // configure component services
-
466 services.AddSingleton<IPortAllocator, PortAllocator>();
-
467 services.AddSingleton<IInstanceFactory, InstanceFactory>();
-
468 services.AddSingleton<IGitRemoteFeaturesFactory, GitRemoteFeaturesFactory>();
-
469 services.AddSingleton<ILibGit2RepositoryFactory, LibGit2RepositoryFactory>();
-
470 services.AddSingleton<ILibGit2Commands, LibGit2Commands>();
-
471 services.AddSingleton<IRepositoryManagerFactory, RepostoryManagerFactory>();
- -
473 services.AddChatProviderFactory();
-
474 services.AddSingleton<IChatManagerFactory, ChatManagerFactory>();
-
475 services.AddSingleton<IServerUpdater, ServerUpdater>();
-
476 services.AddSingleton<IServerUpdateInitiator, ServerUpdateInitiator>();
-
477 services.AddSingleton<IDotnetDumpService, DotnetDumpService>();
-
478
-
479 // configure authorities
-
480 services.AddScoped(typeof(IRestAuthorityInvoker<>), typeof(RestAuthorityInvoker<>));
-
481 services.AddScoped(typeof(IGraphQLAuthorityInvoker<>), typeof(GraphQLAuthorityInvoker<>));
-
482 services.AddScoped<ILoginAuthority, LoginAuthority>();
-
483 services.AddScoped<IUserAuthority, UserAuthority>();
-
484 services.AddScoped<IUserGroupAuthority, UserGroupAuthority>();
-
485 services.AddScoped<IPermissionSetAuthority, PermissionSetAuthority>();
-
486
-
487 // configure misc services
-
488 services.AddSingleton<IProcessExecutor, ProcessExecutor>();
-
489 services.AddSingleton<ISynchronousIOManager, SynchronousIOManager>();
-
490 services.AddSingleton<IServerPortProvider, ServerPortProivder>();
-
491 services.AddSingleton<ITopicClientFactory, TopicClientFactory>();
-
492 services.AddHostedService<CommandPipeManager>();
-
493 services.AddHostedService<VersionReportingService>();
-
494
-
495 services.AddFileDownloader();
-
496 services.AddGitHub();
-
497
-
498 // configure root services
-
499 services.AddSingleton<JobService>();
-
500 services.AddSingleton<IJobService>(provider => provider.GetRequiredService<JobService>());
-
501 services.AddSingleton<IJobsHubUpdater>(provider => provider.GetRequiredService<JobService>());
-
502 services.AddSingleton<IJobManager>(x => x.GetRequiredService<IJobService>());
-
503 services.AddSingleton<JobsHubGroupMapper>();
-
504 services.AddSingleton<IPermissionsUpdateNotifyee>(provider => provider.GetRequiredService<JobsHubGroupMapper>());
-
505 services.AddSingleton<IHostedService>(x => x.GetRequiredService<JobsHubGroupMapper>()); // bit of a hack, but we need this to load immediated
-
506
-
507 services.AddSingleton<InstanceManager>();
-
508 services.AddSingleton<IBridgeDispatcher>(x => x.GetRequiredService<InstanceManager>());
-
509 services.AddSingleton<IInstanceManager>(x => x.GetRequiredService<InstanceManager>());
-
510 }
-
+
353 services.AddDbContextPool<TContext>((serviceProvider, builder) =>
+
354 {
+
355 if (hostingEnvironment.IsDevelopment())
+
356 builder.EnableSensitiveDataLogging();
+
357
+
358 var databaseConfigOptions = serviceProvider.GetRequiredService<IOptions<DatabaseConfiguration>>();
+
359 var databaseConfig = databaseConfigOptions.Value ?? throw new InvalidOperationException("DatabaseConfiguration missing!");
+
360 configureAction(builder, databaseConfig);
+
361 });
+
362 services.AddScoped<IDatabaseContext>(x => x.GetRequiredService<TContext>());
+
363 }
+
364
+
365 // add the correct database context type
+
366 var dbType = postSetupServices.DatabaseConfiguration.DatabaseType;
+
367 switch (dbType)
+
368 {
+
369 case DatabaseType.MySql:
+
370 case DatabaseType.MariaDB:
+
371 AddTypedContext<MySqlDatabaseContext>();
+
372 break;
+
373 case DatabaseType.SqlServer:
+
374 AddTypedContext<SqlServerDatabaseContext>();
+
375 break;
+
376 case DatabaseType.Sqlite:
+
377 AddTypedContext<SqliteDatabaseContext>();
+
378 break;
+
379 case DatabaseType.PostgresSql:
+
380 AddTypedContext<PostgresSqlDatabaseContext>();
+
381 break;
+
382 default:
+
383 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid {0}: {1}!", nameof(DatabaseType), dbType));
+
384 }
+
385
+
386 // configure other database services
+
387 services.AddSingleton<IDatabaseContextFactory, DatabaseContextFactory>();
+
388 services.AddSingleton<IDatabaseSeeder, DatabaseSeeder>();
+
389
+
390 // configure other security services
+
391 services.AddSingleton<IOAuthProviders, OAuthProviders>();
+
392 services.AddSingleton<IIdentityCache, IdentityCache>();
+
393 services.AddSingleton<ICryptographySuite, CryptographySuite>();
+
394 services.AddSingleton<ITokenFactory, TokenFactory>();
+ +
396 services.AddSingleton<IPasswordHasher<Models.User>, PasswordHasher<Models.User>>();
+
397
+
398 // configure platform specific services
+
399 if (postSetupServices.PlatformIdentifier.IsWindows)
+
400 {
+
401 AddWatchdog<WindowsWatchdogFactory>(services, postSetupServices);
+ + +
404 services.AddSingleton<ByondInstallerBase, WindowsByondInstaller>();
+
405 services.AddSingleton<OpenDreamInstaller, WindowsOpenDreamInstaller>();
+
406 services.AddSingleton<IPostWriteHandler, WindowsPostWriteHandler>();
+
407 services.AddSingleton<IProcessFeatures, WindowsProcessFeatures>();
+
408
+
409 services.AddSingleton<WindowsNetworkPromptReaper>();
+
410 services.AddSingleton<INetworkPromptReaper>(x => x.GetRequiredService<WindowsNetworkPromptReaper>());
+
411 services.AddSingleton<IHostedService>(x => x.GetRequiredService<WindowsNetworkPromptReaper>());
+
412 }
+
413 else
+
414 {
+
415 AddWatchdog<PosixWatchdogFactory>(services, postSetupServices);
+
416 services.AddSingleton<ISystemIdentityFactory, PosixSystemIdentityFactory>();
+
417 services.AddSingleton<IFilesystemLinkFactory, PosixFilesystemLinkFactory>();
+
418 services.AddSingleton<ByondInstallerBase, PosixByondInstaller>();
+
419 services.AddSingleton<OpenDreamInstaller>();
+
420 services.AddSingleton<IPostWriteHandler, PosixPostWriteHandler>();
+
421
+
422 services.AddSingleton<IProcessFeatures, PosixProcessFeatures>();
+
423 services.AddHostedService<PosixProcessFeatures>();
+
424
+
425 // PosixProcessFeatures also needs a IProcessExecutor for gcore
+
426 services.AddSingleton(x => new Lazy<IProcessExecutor>(() => x.GetRequiredService<IProcessExecutor>(), true));
+
427 services.AddSingleton<INetworkPromptReaper, PosixNetworkPromptReaper>();
+
428
+
429 services.AddHostedService<PosixSignalHandler>();
+
430 }
+
431
+
432 // only global repo manager should be for the OD repo
+
433 // god help me if we need more
+
434 var openDreamRepositoryDirectory = ioManager.ConcatPath(
+
435 ioManager.GetPathInLocalDirectory(assemblyInformationProvider),
+
436 "OpenDreamRepository");
+
437 services.AddSingleton(
+
438 services => services
+
439 .GetRequiredService<IRepositoryManagerFactory>()
+
440 .CreateRepositoryManager(
+ +
442 services.GetRequiredService<IIOManager>(),
+
443 openDreamRepositoryDirectory),
+
444 new NoopEventConsumer()));
+
445
+
446 services.AddSingleton(
+
447 serviceProvider => new Dictionary<EngineType, IEngineInstaller>
+
448 {
+
449 { EngineType.Byond, serviceProvider.GetRequiredService<ByondInstallerBase>() },
+
450 { EngineType.OpenDream, serviceProvider.GetRequiredService<OpenDreamInstaller>() },
+
451 }
+
452 .ToFrozenDictionary());
+
453 services.AddSingleton<IEngineInstaller, DelegatingEngineInstaller>();
+
454
+
455 if (postSetupServices.InternalConfiguration.UsingSystemD)
+
456 services.AddHostedService<SystemDManager>();
+
457
+
458 // configure file transfer services
+
459 services.AddSingleton<FileTransferService>();
+
460 services.AddSingleton<IFileTransferStreamHandler>(x => x.GetRequiredService<FileTransferService>());
+
461 services.AddSingleton<IFileTransferTicketProvider>(x => x.GetRequiredService<FileTransferService>());
+ +
463
+
464 // configure swarm service
+
465 services.AddSingleton<SwarmService>();
+
466 services.AddSingleton<ISwarmService>(x => x.GetRequiredService<SwarmService>());
+
467 services.AddSingleton<ISwarmOperations>(x => x.GetRequiredService<SwarmService>());
+
468 services.AddSingleton<ISwarmServiceController>(x => x.GetRequiredService<SwarmService>());
+
469
+
470 // configure component services
+
471 services.AddSingleton<IPortAllocator, PortAllocator>();
+
472 services.AddSingleton<IInstanceFactory, InstanceFactory>();
+
473 services.AddSingleton<IGitRemoteFeaturesFactory, GitRemoteFeaturesFactory>();
+
474 services.AddSingleton<ILibGit2RepositoryFactory, LibGit2RepositoryFactory>();
+
475 services.AddSingleton<ILibGit2Commands, LibGit2Commands>();
+
476 services.AddSingleton<IRepositoryManagerFactory, RepostoryManagerFactory>();
+ +
478 services.AddChatProviderFactory();
+
479 services.AddSingleton<IChatManagerFactory, ChatManagerFactory>();
+
480 services.AddSingleton<IServerUpdater, ServerUpdater>();
+
481 services.AddSingleton<IServerUpdateInitiator, ServerUpdateInitiator>();
+
482 services.AddSingleton<IDotnetDumpService, DotnetDumpService>();
+
483
+
484 // configure authorities
+
485 services.AddScoped(typeof(IRestAuthorityInvoker<>), typeof(RestAuthorityInvoker<>));
+
486 services.AddScoped(typeof(IGraphQLAuthorityInvoker<>), typeof(GraphQLAuthorityInvoker<>));
+
487 services.AddScoped<ILoginAuthority, LoginAuthority>();
+
488 services.AddScoped<IUserAuthority, UserAuthority>();
+
489 services.AddScoped<IUserGroupAuthority, UserGroupAuthority>();
+
490 services.AddScoped<IPermissionSetAuthority, PermissionSetAuthority>();
+
491
+
492 // configure misc services
+
493 services.AddSingleton<IProcessExecutor, ProcessExecutor>();
+
494 services.AddSingleton<ISynchronousIOManager, SynchronousIOManager>();
+
495 services.AddSingleton<IServerPortProvider, ServerPortProivder>();
+
496 services.AddSingleton<ITopicClientFactory, TopicClientFactory>();
+
497 services.AddHostedService<CommandPipeManager>();
+
498 services.AddHostedService<VersionReportingService>();
+
499
+
500 services.AddFileDownloader();
+
501 services.AddGitHub();
+
502
+
503 // configure root services
+
504 services.AddSingleton<JobService>();
+
505 services.AddSingleton<IJobService>(provider => provider.GetRequiredService<JobService>());
+
506 services.AddSingleton<IJobsHubUpdater>(provider => provider.GetRequiredService<JobService>());
+
507 services.AddSingleton<IJobManager>(x => x.GetRequiredService<IJobService>());
+
508 services.AddSingleton<JobsHubGroupMapper>();
+
509 services.AddSingleton<IPermissionsUpdateNotifyee>(provider => provider.GetRequiredService<JobsHubGroupMapper>());
+
510 services.AddSingleton<IHostedService>(x => x.GetRequiredService<JobsHubGroupMapper>()); // bit of a hack, but we need this to load immediated
511
-
-
525 public void Configure(
-
526 IApplicationBuilder applicationBuilder,
-
527 IServerControl serverControl,
- -
529 IServerPortProvider serverPortProvider,
-
530 IAssemblyInformationProvider assemblyInformationProvider,
-
531 IOptions<ControlPanelConfiguration> controlPanelConfigurationOptions,
-
532 IOptions<GeneralConfiguration> generalConfigurationOptions,
-
533 IOptions<SwarmConfiguration> swarmConfigurationOptions,
-
534 IOptions<InternalConfiguration> internalConfigurationOptions,
-
535 ILogger<Application> logger)
-
536 {
-
537 ArgumentNullException.ThrowIfNull(applicationBuilder);
-
538 ArgumentNullException.ThrowIfNull(serverControl);
-
539
-
540 this.tokenFactory = tokenFactory ?? throw new ArgumentNullException(nameof(tokenFactory));
-
541
-
542 ArgumentNullException.ThrowIfNull(serverPortProvider);
-
543 ArgumentNullException.ThrowIfNull(assemblyInformationProvider);
+
512 services.AddSingleton<InstanceManager>();
+
513 services.AddSingleton<IBridgeDispatcher>(x => x.GetRequiredService<InstanceManager>());
+
514 services.AddSingleton<IInstanceManager>(x => x.GetRequiredService<InstanceManager>());
+
515 }
+
+
516
+
+
530 public void Configure(
+
531 IApplicationBuilder applicationBuilder,
+
532 IServerControl serverControl,
+ +
534 IServerPortProvider serverPortProvider,
+
535 IAssemblyInformationProvider assemblyInformationProvider,
+
536 IOptions<ControlPanelConfiguration> controlPanelConfigurationOptions,
+
537 IOptions<GeneralConfiguration> generalConfigurationOptions,
+
538 IOptions<SwarmConfiguration> swarmConfigurationOptions,
+
539 IOptions<InternalConfiguration> internalConfigurationOptions,
+
540 ILogger<Application> logger)
+
541 {
+
542 ArgumentNullException.ThrowIfNull(applicationBuilder);
+
543 ArgumentNullException.ThrowIfNull(serverControl);
544
-
545 var controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
-
546 var generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
-
547 var swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions));
-
548 var internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions));
+
545 this.tokenFactory = tokenFactory ?? throw new ArgumentNullException(nameof(tokenFactory));
+
546
+
547 ArgumentNullException.ThrowIfNull(serverPortProvider);
+
548 ArgumentNullException.ThrowIfNull(assemblyInformationProvider);
549
-
550 ArgumentNullException.ThrowIfNull(logger);
-
551
-
552 logger.LogDebug("Content Root: {contentRoot}", hostingEnvironment.ContentRootPath);
-
553 logger.LogTrace("Web Root: {webRoot}", hostingEnvironment.WebRootPath);
+
550 var controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
+
551 var generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
+
552 var swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions));
+
553 var internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions));
554
-
555 // setup the HTTP request pipeline
-
556 // Add additional logging context to the request
-
557 applicationBuilder.UseAdditionalRequestLoggingContext(swarmConfiguration);
-
558
-
559 // Wrap exceptions in a 500 (ErrorMessage) response
-
560 applicationBuilder.UseServerErrorHandling();
-
561
-
562 // Add the X-Powered-By response header
-
563 applicationBuilder.UseServerBranding(assemblyInformationProvider);
-
564
-
565 // Add the X-Accel-Buffering response header
-
566 applicationBuilder.UseDisabledNginxProxyBuffering();
-
567
-
568 // suppress OperationCancelledExceptions, they are just aborted HTTP requests
-
569 applicationBuilder.UseCancelledRequestSuppression();
-
570
-
571 // 503 requests made while the application is starting
-
572 applicationBuilder.UseAsyncInitialization<IInstanceManager>(
-
573 (instanceManager, cancellationToken) => instanceManager.Ready.WaitAsync(cancellationToken));
-
574
-
575 if (generalConfiguration.HostApiDocumentation)
-
576 {
-
577 var siteDocPath = Routes.ApiRoot + $"doc/{SwaggerConfiguration.DocumentName}.json";
-
578 if (!String.IsNullOrWhiteSpace(controlPanelConfiguration.PublicPath))
-
579 siteDocPath = controlPanelConfiguration.PublicPath.TrimEnd('/') + siteDocPath;
-
580
-
581 applicationBuilder.UseSwagger(options =>
-
582 {
-
583 options.RouteTemplate = Routes.ApiRoot + "doc/{documentName}.{json|yaml}";
-
584 });
-
585 applicationBuilder.UseSwaggerUI(options =>
-
586 {
- -
588 options.SwaggerEndpoint(siteDocPath, "TGS API");
+
555 ArgumentNullException.ThrowIfNull(logger);
+
556
+
557 logger.LogDebug("Content Root: {contentRoot}", hostingEnvironment.ContentRootPath);
+
558 logger.LogTrace("Web Root: {webRoot}", hostingEnvironment.WebRootPath);
+
559
+
560 // setup the HTTP request pipeline
+
561 // Add additional logging context to the request
+
562 applicationBuilder.UseAdditionalRequestLoggingContext(swarmConfiguration);
+
563
+
564 // Wrap exceptions in a 500 (ErrorMessage) response
+
565 applicationBuilder.UseServerErrorHandling();
+
566
+
567 // Add the X-Powered-By response header
+
568 applicationBuilder.UseServerBranding(assemblyInformationProvider);
+
569
+
570 // Add the X-Accel-Buffering response header
+
571 applicationBuilder.UseDisabledNginxProxyBuffering();
+
572
+
573 // suppress OperationCancelledExceptions, they are just aborted HTTP requests
+
574 applicationBuilder.UseCancelledRequestSuppression();
+
575
+
576 // 503 requests made while the application is starting
+
577 applicationBuilder.UseAsyncInitialization<IInstanceManager>(
+
578 (instanceManager, cancellationToken) => instanceManager.Ready.WaitAsync(cancellationToken));
+
579
+
580 if (generalConfiguration.HostApiDocumentation)
+
581 {
+
582 var siteDocPath = Routes.ApiRoot + $"doc/{SwaggerConfiguration.DocumentName}.json";
+
583 if (!String.IsNullOrWhiteSpace(controlPanelConfiguration.PublicPath))
+
584 siteDocPath = controlPanelConfiguration.PublicPath.TrimEnd('/') + siteDocPath;
+
585
+
586 applicationBuilder.UseSwagger(options =>
+
587 {
+
588 options.RouteTemplate = Routes.ApiRoot + "doc/{documentName}.{json|yaml}";
589 });
-
590 logger.LogTrace("Swagger API generation enabled");
-
591 }
-
592
-
593 // spa loading if necessary
-
594 if (controlPanelConfiguration.Enable)
-
595 {
-
596 logger.LogInformation("Web control panel enabled.");
-
597 applicationBuilder.UseFileServer(new FileServerOptions
-
598 {
- -
600 EnableDefaultFiles = true,
-
601 EnableDirectoryBrowsing = false,
-
602 RedirectToAppendTrailingSlash = false,
-
603 });
-
604 }
-
605 else
-
606#if NO_WEBPANEL
-
607 logger.LogDebug("Web control panel was not included in TGS build!");
-
608#else
-
609 logger.LogTrace("Web control panel disabled!");
-
610#endif
-
611
-
612 // Enable endpoint routing
-
613 applicationBuilder.UseRouting();
-
614
-
615 // Set up CORS based on configuration if necessary
-
616 Action<CorsPolicyBuilder>? corsBuilder = null;
-
617 if (controlPanelConfiguration.AllowAnyOrigin)
-
618 {
-
619 logger.LogTrace("Access-Control-Allow-Origin: *");
-
620 corsBuilder = builder => builder.SetIsOriginAllowed(_ => true);
-
621 }
-
622 else if (controlPanelConfiguration.AllowedOrigins?.Count > 0)
+
590 applicationBuilder.UseSwaggerUI(options =>
+
591 {
+ +
593 options.SwaggerEndpoint(siteDocPath, "TGS API");
+
594 });
+
595 logger.LogTrace("Swagger API generation enabled");
+
596 }
+
597
+
598 // spa loading if necessary
+
599 if (controlPanelConfiguration.Enable)
+
600 {
+
601 logger.LogInformation("Web control panel enabled.");
+
602 applicationBuilder.UseFileServer(new FileServerOptions
+
603 {
+ +
605 EnableDefaultFiles = true,
+
606 EnableDirectoryBrowsing = false,
+
607 RedirectToAppendTrailingSlash = false,
+
608 });
+
609 }
+
610 else
+
611#if NO_WEBPANEL
+
612 logger.LogDebug("Web control panel was not included in TGS build!");
+
613#else
+
614 logger.LogTrace("Web control panel disabled!");
+
615#endif
+
616
+
617 // Enable endpoint routing
+
618 applicationBuilder.UseRouting();
+
619
+
620 // Set up CORS based on configuration if necessary
+
621 Action<CorsPolicyBuilder>? corsBuilder = null;
+
622 if (controlPanelConfiguration.AllowAnyOrigin)
623 {
-
624 logger.LogTrace("Access-Control-Allow-Origin: {allowedOrigins}", String.Join(',', controlPanelConfiguration.AllowedOrigins));
-
625 corsBuilder = builder => builder.WithOrigins([.. controlPanelConfiguration.AllowedOrigins]);
+
624 logger.LogTrace("Access-Control-Allow-Origin: *");
+
625 corsBuilder = builder => builder.SetIsOriginAllowed(_ => true);
626 }
-
627
-
628 var originalBuilder = corsBuilder;
-
629 corsBuilder = builder =>
-
630 {
-
631 builder
-
632 .AllowAnyHeader()
-
633 .AllowAnyMethod()
-
634 .AllowCredentials()
-
635 .SetPreflightMaxAge(TimeSpan.FromDays(1));
-
636 originalBuilder?.Invoke(builder);
-
637 };
-
638 applicationBuilder.UseCors(corsBuilder);
-
639
-
640 // validate the API version
-
641 applicationBuilder.UseApiCompatibility();
-
642
-
643 // authenticate JWT tokens using our security pipeline if present, returns 401 if bad
-
644 applicationBuilder.UseAuthentication();
-
645
-
646 // enable authorization on endpoints
-
647 applicationBuilder.UseAuthorization();
-
648
-
649 // suppress and log database exceptions
-
650 applicationBuilder.UseDbConflictHandling();
-
651
-
652 // setup endpoints
-
653 applicationBuilder.UseEndpoints(endpoints =>
-
654 {
-
655 // access to the signalR jobs hub
-
656 endpoints.MapHub<JobsHub>(
- -
658 options =>
-
659 {
-
660 options.Transports = HttpTransportType.ServerSentEvents;
-
661 options.CloseOnAuthenticationExpiration = true;
-
662 })
-
663 .RequireAuthorization()
-
664 .RequireCors(corsBuilder);
-
665
-
666 // majority of handling is done in the controllers
-
667 endpoints.MapControllers();
-
668
-
669 if (internalConfiguration.EnableGraphQL)
-
670 {
-
671 logger.LogWarning("Enabling GraphQL. This API is experimental and breaking changes may occur at any time!");
-
672 var gqlOptions = new GraphQLServerOptions
-
673 {
-
674 EnableBatching = true,
-
675 };
-
676
-
677 gqlOptions.Tool.Enable = generalConfiguration.HostApiDocumentation;
-
678
-
679 endpoints
-
680 .MapGraphQL(Routes.GraphQL)
-
681 .WithOptions(gqlOptions);
-
682 }
-
683 });
-
684
-
685 // 404 anything that gets this far
-
686 // End of request pipeline setup
-
687 logger.LogTrace("Configuration version: {configVersion}", GeneralConfiguration.CurrentConfigVersion);
-
688 logger.LogTrace("DMAPI Interop version: {interopVersion}", DMApiConstants.InteropVersion);
-
689 if (controlPanelConfiguration.Enable)
-
690 logger.LogTrace("Webpanel version: {webCPVersion}", MasterVersionsAttribute.Instance.RawWebpanelVersion);
-
691
-
692 logger.LogDebug("Starting hosting on port {httpApiPort}...", serverPortProvider.HttpApiPort);
-
693 }
+
627 else if (controlPanelConfiguration.AllowedOrigins?.Count > 0)
+
628 {
+
629 logger.LogTrace("Access-Control-Allow-Origin: {allowedOrigins}", String.Join(',', controlPanelConfiguration.AllowedOrigins));
+
630 corsBuilder = builder => builder.WithOrigins([.. controlPanelConfiguration.AllowedOrigins]);
+
631 }
+
632
+
633 var originalBuilder = corsBuilder;
+
634 corsBuilder = builder =>
+
635 {
+
636 builder
+
637 .AllowAnyHeader()
+
638 .AllowAnyMethod()
+
639 .AllowCredentials()
+
640 .SetPreflightMaxAge(TimeSpan.FromDays(1));
+
641 originalBuilder?.Invoke(builder);
+
642 };
+
643 applicationBuilder.UseCors(corsBuilder);
+
644
+
645 // validate the API version
+
646 applicationBuilder.UseApiCompatibility();
+
647
+
648 // authenticate JWT tokens using our security pipeline if present, returns 401 if bad
+
649 applicationBuilder.UseAuthentication();
+
650
+
651 // enable authorization on endpoints
+
652 applicationBuilder.UseAuthorization();
+
653
+
654 // suppress and log database exceptions
+
655 applicationBuilder.UseDbConflictHandling();
+
656
+
657 // setup endpoints
+
658 applicationBuilder.UseEndpoints(endpoints =>
+
659 {
+
660 // access to the signalR jobs hub
+
661 endpoints.MapHub<JobsHub>(
+ +
663 options =>
+
664 {
+
665 options.Transports = HttpTransportType.ServerSentEvents;
+
666 options.CloseOnAuthenticationExpiration = true;
+
667 })
+
668 .RequireAuthorization()
+
669 .RequireCors(corsBuilder);
+
670
+
671 // majority of handling is done in the controllers
+
672 endpoints.MapControllers();
+
673
+
674 if (internalConfiguration.EnableGraphQL)
+
675 {
+
676 logger.LogWarning("Enabling GraphQL. This API is experimental and breaking changes may occur at any time!");
+
677 var gqlOptions = new GraphQLServerOptions
+
678 {
+
679 EnableBatching = true,
+
680 };
+
681
+
682 gqlOptions.Tool.Enable = generalConfiguration.HostApiDocumentation;
+
683
+
684 endpoints
+
685 .MapGraphQL(Routes.GraphQL)
+
686 .WithOptions(gqlOptions);
+
687 }
+
688 });
+
689
+
690 // 404 anything that gets this far
+
691 // End of request pipeline setup
+
692 logger.LogTrace("Configuration version: {configVersion}", GeneralConfiguration.CurrentConfigVersion);
+
693 logger.LogTrace("DMAPI Interop version: {interopVersion}", DMApiConstants.InteropVersion);
+
694 if (controlPanelConfiguration.Enable)
+
695 logger.LogTrace("Webpanel version: {webCPVersion}", MasterVersionsAttribute.Instance.RawWebpanelVersion);
+
696
+
697 logger.LogDebug("Starting hosting on port {httpApiPort}...", serverPortProvider.HttpApiPort);
+
698 }
-
694
-
696 protected override void ConfigureHostedService(IServiceCollection services)
-
697 => services.AddSingleton<IHostedService>(x => x.GetRequiredService<InstanceManager>());
-
698
-
-
703 void ConfigureAuthenticationPipeline(IServiceCollection services)
-
704 {
-
705 services.AddHttpContextAccessor();
-
706 services.AddScoped<IApiHeadersProvider, ApiHeadersProvider>();
-
707 services.AddScoped<AuthenticationContextFactory>();
-
708 services.AddScoped<ITokenValidator>(provider => provider.GetRequiredService<AuthenticationContextFactory>());
-
709
-
710 // what if you
-
711 // wanted to just do this:
-
712 // return provider.GetRequiredService<AuthenticationContextFactory>().CurrentAuthenticationContext
-
713 // But M$ said
-
714 // https://stackoverflow.com/questions/56792917/scoped-services-in-asp-net-core-with-signalr-hubs
-
715 services.AddScoped(provider => (provider
-
716 .GetRequiredService<IHttpContextAccessor>()
-
717 .HttpContext ?? throw new InvalidOperationException($"Unable to resolve {nameof(IAuthenticationContext)} due to no HttpContext being available!"))
-
718 .RequestServices
-
719 .GetRequiredService<AuthenticationContextFactory>()
-
720 .CurrentAuthenticationContext);
- -
722
-
723 services
-
724 .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
-
725 .AddJwtBearer(jwtBearerOptions =>
-
726 {
-
727 // this line isn't actually run until the first request is made
-
728 // at that point tokenFactory will be populated
-
729 jwtBearerOptions.TokenValidationParameters = tokenFactory?.ValidationParameters ?? throw new InvalidOperationException("tokenFactory not initialized!");
-
730 jwtBearerOptions.MapInboundClaims = false;
-
731 jwtBearerOptions.Events = new JwtBearerEvents
-
732 {
-
733 OnMessageReceived = context =>
-
734 {
-
735 if (String.IsNullOrWhiteSpace(context.Token))
-
736 {
-
737 var accessToken = context.Request.Query["access_token"];
-
738 var path = context.HttpContext.Request.Path;
-
739
-
740 if (!String.IsNullOrWhiteSpace(accessToken) &&
-
741 path.StartsWithSegments(Routes.HubsRoot, StringComparison.OrdinalIgnoreCase))
-
742 {
-
743 context.Token = accessToken;
-
744 }
-
745 }
-
746
-
747 return Task.CompletedTask;
-
748 },
-
749 OnTokenValidated = context => context
-
750 .HttpContext
-
751 .RequestServices
-
752 .GetRequiredService<ITokenValidator>()
-
753 .ValidateToken(
-
754 context,
-
755 context
-
756 .HttpContext
-
757 .RequestAborted),
-
758 };
-
759 });
-
760 }
+
699
+
701 protected override void ConfigureHostedService(IServiceCollection services)
+
702 => services.AddSingleton<IHostedService>(x => x.GetRequiredService<InstanceManager>());
+
703
+
+
708 void ConfigureAuthenticationPipeline(IServiceCollection services)
+
709 {
+
710 services.AddHttpContextAccessor();
+
711 services.AddScoped<IApiHeadersProvider, ApiHeadersProvider>();
+
712 services.AddScoped<AuthenticationContextFactory>();
+
713 services.AddScoped<ITokenValidator>(provider => provider.GetRequiredService<AuthenticationContextFactory>());
+
714
+
715 // what if you
+
716 // wanted to just do this:
+
717 // return provider.GetRequiredService<AuthenticationContextFactory>().CurrentAuthenticationContext
+
718 // But M$ said
+
719 // https://stackoverflow.com/questions/56792917/scoped-services-in-asp-net-core-with-signalr-hubs
+
720 services.AddScoped(provider => (provider
+
721 .GetRequiredService<IHttpContextAccessor>()
+
722 .HttpContext ?? throw new InvalidOperationException($"Unable to resolve {nameof(IAuthenticationContext)} due to no HttpContext being available!"))
+
723 .RequestServices
+
724 .GetRequiredService<AuthenticationContextFactory>()
+
725 .CurrentAuthenticationContext);
+ +
727
+
728 services
+
729 .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+
730 .AddJwtBearer(jwtBearerOptions =>
+
731 {
+
732 // this line isn't actually run until the first request is made
+
733 // at that point tokenFactory will be populated
+
734 jwtBearerOptions.TokenValidationParameters = tokenFactory?.ValidationParameters ?? throw new InvalidOperationException("tokenFactory not initialized!");
+
735 jwtBearerOptions.MapInboundClaims = false;
+
736 jwtBearerOptions.Events = new JwtBearerEvents
+
737 {
+
738 OnMessageReceived = context =>
+
739 {
+
740 if (String.IsNullOrWhiteSpace(context.Token))
+
741 {
+
742 var accessToken = context.Request.Query["access_token"];
+
743 var path = context.HttpContext.Request.Path;
+
744
+
745 if (!String.IsNullOrWhiteSpace(accessToken) &&
+
746 path.StartsWithSegments(Routes.HubsRoot, StringComparison.OrdinalIgnoreCase))
+
747 {
+
748 context.Token = accessToken;
+
749 }
+
750 }
+
751
+
752 return Task.CompletedTask;
+
753 },
+
754 OnTokenValidated = context => context
+
755 .HttpContext
+
756 .RequestServices
+
757 .GetRequiredService<ITokenValidator>()
+
758 .ValidateToken(
+
759 context,
+
760 context
+
761 .HttpContext
+
762 .RequestAborted),
+
763 };
+
764 });
+
765 }
-
761 }
+
766 }
-
762}
+
767}
@@ -866,16 +871,16 @@ $(document).ready(function() { init_codefold(0); });
const string ControlPanelRoute
Route to the ControlPanelController.
-
Sets up dependency injection.
+
Sets up dependency injection.
override void ConfigureHostedService(IServiceCollection services)
Configures the IHostedService.
-
static void AddWatchdog< TSystemWatchdogFactory >(IServiceCollection services, IPostSetupServices postSetupServices)
Adds the IWatchdogFactory implementation.
-
void ConfigureServices(IServiceCollection services, IAssemblyInformationProvider assemblyInformationProvider, IIOManager ioManager, IPostSetupServices postSetupServices)
Configure the Application's services .
-
static IServerFactory CreateDefaultServerFactory()
Create the default IServerFactory.
-
void ConfigureAuthenticationPipeline(IServiceCollection services)
Configure the services for the authentication pipeline.
-
ITokenFactory? tokenFactory
The ITokenFactory for the Application.
-
Application(IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
Initializes a new instance of the Application class.
-
void Configure(IApplicationBuilder applicationBuilder, IServerControl serverControl, ITokenFactory tokenFactory, IServerPortProvider serverPortProvider, IAssemblyInformationProvider assemblyInformationProvider, IOptions< ControlPanelConfiguration > controlPanelConfigurationOptions, IOptions< GeneralConfiguration > generalConfigurationOptions, IOptions< SwarmConfiguration > swarmConfigurationOptions, IOptions< InternalConfiguration > internalConfigurationOptions, ILogger< Application > logger)
Configure the Application.
-
readonly IWebHostEnvironment hostingEnvironment
The IWebHostEnvironment for the Application.
+
static void AddWatchdog< TSystemWatchdogFactory >(IServiceCollection services, IPostSetupServices postSetupServices)
Adds the IWatchdogFactory implementation.
+
void ConfigureServices(IServiceCollection services, IAssemblyInformationProvider assemblyInformationProvider, IIOManager ioManager, IPostSetupServices postSetupServices)
Configure the Application's services .
+
static IServerFactory CreateDefaultServerFactory()
Create the default IServerFactory.
+
void ConfigureAuthenticationPipeline(IServiceCollection services)
Configure the services for the authentication pipeline.
+
ITokenFactory? tokenFactory
The ITokenFactory for the Application.
+
Application(IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
Initializes a new instance of the Application class.
+
void Configure(IApplicationBuilder applicationBuilder, IServerControl serverControl, ITokenFactory tokenFactory, IServerPortProvider serverPortProvider, IAssemblyInformationProvider assemblyInformationProvider, IOptions< ControlPanelConfiguration > controlPanelConfigurationOptions, IOptions< GeneralConfiguration > generalConfigurationOptions, IOptions< SwarmConfiguration > swarmConfigurationOptions, IOptions< InternalConfiguration > internalConfigurationOptions, ILogger< Application > logger)
Configure the Application.
+
readonly IWebHostEnvironment hostingEnvironment
The IWebHostEnvironment for the Application.
Reads from the command pipe opened by the host watchdog.
@@ -965,7 +970,6 @@ $(document).ready(function() { init_codefold(0); });
Factory for scoping usage of IDatabaseContexts. Meant for use by Components.
For initially setting up a database.
-
Implementation of HotChocolate.Subscriptions.ITopicEventReceiver that works around the global::System...
Interface for using filesystems.
Definition IIOManager.cs:13
string ConcatPath(params string[] paths)
Combines an array of strings into a path.
@@ -1027,7 +1031,7 @@ $(document).ready(function() { init_codefold(0); });
DatabaseType
Type of database to user.
- + diff --git a/_basic_watchdog_8cs_source.html b/_basic_watchdog_8cs_source.html index 451f7d91f4..874240ae46 100644 --- a/_basic_watchdog_8cs_source.html +++ b/_basic_watchdog_8cs_source.html @@ -446,7 +446,7 @@ $(document).ready(function() { init_codefold(0); });
MonitorAction
The action for the monitor loop to take when control is returned to it.
@ Restart
The monitor should kill and restart both servers.
MonitorActivationReason
Reasons for the monitor to wake up.
- + diff --git a/_chat_manager_8cs_source.html b/_chat_manager_8cs_source.html index e31494d51b..e8692b8d7d 100644 --- a/_chat_manager_8cs_source.html +++ b/_chat_manager_8cs_source.html @@ -1196,7 +1196,7 @@ $(document).ready(function() { init_codefold(0); }); - +
diff --git a/_chat_manager_factory_8cs_source.html b/_chat_manager_factory_8cs_source.html index eb4013963d..de00caee37 100644 --- a/_chat_manager_factory_8cs_source.html +++ b/_chat_manager_factory_8cs_source.html @@ -144,7 +144,7 @@ $(document).ready(function() { init_codefold(0); }); - +
diff --git a/_command_pipe_manager_8cs_source.html b/_command_pipe_manager_8cs_source.html index e73a2a078d..7a086c968d 100644 --- a/_command_pipe_manager_8cs_source.html +++ b/_command_pipe_manager_8cs_source.html @@ -232,7 +232,7 @@ $(document).ready(function() { init_codefold(0); }); - +