tgstation-server 6.19.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
ComponentInterfacingController.cs
Go to the documentation of this file.
1using System;
2using System.Threading;
3using System.Threading.Tasks;
4
5using Microsoft.AspNetCore.Mvc;
6using Microsoft.Extensions.Logging;
7using Serilog.Context;
8
17
19{
24 {
29
34
39
50 IDatabaseContext databaseContext,
51 IAuthenticationContext authenticationContext,
52 ILogger<ComponentInterfacingController> logger,
54 IApiHeadersProvider apiHeaders,
56 : base(
57 databaseContext,
58 authenticationContext,
59 apiHeaders,
60 logger,
61 true)
62 {
63 this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
64 this.useInstanceRequestHeader = useInstanceRequestHeader;
65 }
66
68 protected override async ValueTask<IActionResult?> ValidateRequest(CancellationToken cancellationToken)
69 {
71 return null;
72
73 if (!ApiHeaders!.InstanceId.HasValue)
74 return BadRequest(new ErrorMessageResponse(ErrorCode.InstanceHeaderRequired));
75
77 return Forbid();
78
79 var instance = Instance!;
80 if (ValidateInstanceOnlineStatus(instance))
81 await DatabaseContext.Save(cancellationToken);
82
83 using var instanceReferenceCheck = instanceManager.GetInstanceReference(instance);
84 if (instanceReferenceCheck == null)
85 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceOffline));
86
87 return null;
88 }
89
95 protected bool ValidateInstanceOnlineStatus(Api.Models.Instance metadata)
96 {
97 ArgumentNullException.ThrowIfNull(metadata);
98
99 bool online;
100 using (var instanceReferenceCheck = instanceManager.GetInstanceReference(metadata))
101 online = instanceReferenceCheck != null;
102
103 if (metadata.Require(x => x.Online) == online)
104 return false;
105
106 const string OfflineWord = "offline";
107 const string OnlineWord = "online";
108
109 Logger.LogWarning(
110 "Instance {instanceId} is says it's {databaseState} in the database, but it is actually {serviceState} in the service. Updating the database to reflect this...",
111 metadata.Id,
112 online ? OfflineWord : OnlineWord,
113 online ? OnlineWord : OfflineWord);
114
115 metadata.Online = online;
116 return true;
117 }
118
126 protected async ValueTask<IActionResult?> WithComponentInstanceNullable(Func<IInstanceCore, ValueTask<IActionResult?>> action, Models.Instance? instance = null)
127 {
128 ArgumentNullException.ThrowIfNull(action);
129
130 instance ??= Instance ?? throw new InvalidOperationException("ComponentInterfacingController has no Instance!");
131
132 using var instanceReference = instanceManager.GetInstanceReference(instance);
133 using (LogContext.PushProperty(SerilogContextHelper.InstanceReferenceContextProperty, instanceReference?.Uid))
134 {
135 if (instanceReference == null)
136 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceOffline));
137 return await action(instanceReference);
138 }
139 }
140
148 protected async ValueTask<IActionResult> WithComponentInstance(Func<IInstanceCore, ValueTask<IActionResult>> action, Models.Instance? instance = null)
149 => (await WithComponentInstanceNullable(async core => await action(core), instance))!;
150 }
151}
Represents the header that must be present for every server request.
Definition ApiHeaders.cs:25
Metadata about a server instance.
Definition Instance.cs:9
Represents an error message returned by the server.
Base Controller for API functions.
ILogger< ApiController > Logger
The ILogger for the ApiController.
async ValueTask< IActionResult?> WithComponentInstanceNullable(Func< IInstanceCore, ValueTask< IActionResult?> > action, Models.Instance? instance=null)
Run a given action with the relevant IInstance.
ComponentInterfacingController(IDatabaseContext databaseContext, IAuthenticationContext authenticationContext, ILogger< ComponentInterfacingController > logger, IInstanceManager instanceManager, IApiHeadersProvider apiHeaders, bool useInstanceRequestHeader)
Initializes a new instance of the ComponentInterfacingController class.
override async ValueTask< IActionResult?> ValidateRequest(CancellationToken cancellationToken)
Performs validation a request.A ValueTask<TResult> resulting in an appropriate IActionResult on valid...
readonly bool useInstanceRequestHeader
If the Api.ApiHeaders.InstanceId header should be checked and used to perform validation for every re...
IInstanceOperations InstanceOperations
Access the IInstanceOperations instance.
readonly IInstanceManager instanceManager
The IInstanceManager for the ComponentInterfacingController.
async ValueTask< IActionResult > WithComponentInstance(Func< IInstanceCore, ValueTask< IActionResult > > action, Models.Instance? instance=null)
Run a given action with the relevant IInstance.
bool ValidateInstanceOnlineStatus(Api.Models.Instance metadata)
Corrects discrepencies between the Api.Models.Instance.Online status of IInstances in the database vs...
Backend abstract implementation of IDatabaseContext.
Task Save(CancellationToken cancellationToken)
Saves changes made to the IDatabaseContext.A Task representing the running operation.
InstancePermissionSet? InstancePermissionSet
The User's effective Models.InstancePermissionSet if applicable.
Helpers for manipulating the Serilog.Context.LogContext.
const string InstanceReferenceContextProperty
The Serilog.Context.LogContext property name for Components.IInstanceReference.Uids.
For interacting with the instance services.
IInstanceReference? GetInstanceReference(long instanceId)
Get the IInstanceReference associated with given instanceId .
Operations that can be performed on a given Models.Instance.
For creating and accessing authentication contexts.
ErrorCode
Types of Response.ErrorMessageResponses that the API may return.
Definition ErrorCode.cs:12