tgstation-server 6.12.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
16
18{
23 {
28
33
38
49 IDatabaseContext databaseContext,
50 IAuthenticationContext authenticationContext,
51 ILogger<ComponentInterfacingController> logger,
53 IApiHeadersProvider apiHeaders,
55 : base(
56 databaseContext,
57 authenticationContext,
58 apiHeaders,
59 logger,
60 true)
61 {
62 this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
63 this.useInstanceRequestHeader = useInstanceRequestHeader;
64 }
65
67 protected override async ValueTask<IActionResult?> ValidateRequest(CancellationToken cancellationToken)
68 {
70 return null;
71
72 if (!ApiHeaders!.InstanceId.HasValue)
73 return BadRequest(new ErrorMessageResponse(ErrorCode.InstanceHeaderRequired));
74
76 return Forbid();
77
78 var instance = Instance!;
79 if (ValidateInstanceOnlineStatus(instance))
80 await DatabaseContext.Save(cancellationToken);
81
82 using var instanceReferenceCheck = instanceManager.GetInstanceReference(instance);
83 if (instanceReferenceCheck == null)
84 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceOffline));
85
86 return null;
87 }
88
94 protected bool ValidateInstanceOnlineStatus(Api.Models.Instance metadata)
95 {
96 ArgumentNullException.ThrowIfNull(metadata);
97
98 bool online;
99 using (var instanceReferenceCheck = instanceManager.GetInstanceReference(metadata))
100 online = instanceReferenceCheck != null;
101
102 if (metadata.Require(x => x.Online) == online)
103 return false;
104
105 const string OfflineWord = "offline";
106 const string OnlineWord = "online";
107
108 Logger.LogWarning(
109 "Instance {instanceId} is says it's {databaseState} in the database, but it is actually {serviceState} in the service. Updating the database to reflect this...",
110 metadata.Id,
111 online ? OfflineWord : OnlineWord,
112 online ? OnlineWord : OfflineWord);
113
114 metadata.Online = online;
115 return true;
116 }
117
125 protected async ValueTask<IActionResult?> WithComponentInstanceNullable(Func<IInstanceCore, ValueTask<IActionResult?>> action, Models.Instance? instance = null)
126 {
127 ArgumentNullException.ThrowIfNull(action);
128
129 instance ??= Instance ?? throw new InvalidOperationException("ComponentInterfacingController has no Instance!");
130
131 using var instanceReference = instanceManager.GetInstanceReference(instance);
132 using (LogContext.PushProperty(SerilogContextHelper.InstanceReferenceContextProperty, instanceReference?.Uid))
133 {
134 if (instanceReference == null)
135 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceOffline));
136 return await action(instanceReference);
137 }
138 }
139
147 protected async ValueTask<IActionResult> WithComponentInstance(Func<IInstanceCore, ValueTask<IActionResult>> action, Models.Instance? instance = null)
148 => (await WithComponentInstanceNullable(async core => await action(core), instance))!;
149 }
150}
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(Api.Models.Instance metadata)
Get the IInstanceReference associated with given metadata .
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