public async Task <HttpResponseMessage> InvokeAsync(WakeOnLanCommandInfo commandInfo, TargetId targetId, TaskExecutionContext context, CancellationToken cancellationToken) { if (targetId.IsServer) { return(NotExecuted("The server cannot execute this command as it must be already running which renders this command useless.")); } if (_connectionManager.ClientConnections.ContainsKey(targetId.ClientId)) { this.LogInformation("The client is already connected."); return(Log(HttpStatusCode.OK)); } var client = await _context.Clients.FindAsync(targetId.ClientId); var macAddress = PhysicalAddress.Parse(client.MacAddress); this.LogInformation("Send magic package from server to {address}", macAddress); context.ReportStatus("Send magic package from server..."); WakeOnLan(macAddress); if (commandInfo.TryOverClient) { this.LogDebug("Querying clients that had the same ip address like the targeted client..."); var clientsInSameNetwork = await _context.Query <ClientReference>().FromSql($"SELECT CS1.ClientId FROM ClientSession AS CS1 INNER JOIN ClientSession AS CS2 ON CS1.IpAddress = CS2.IpAddress WHERE CS1.ClientId = {targetId.ClientId} AND CS2.ClientId != {targetId.ClientId} GROUP BY CS2.ClientId ORDER BY CS2.CreatedOn DESC").ToListAsync(); if (clientsInSameNetwork.Any()) { context.ReportStatus("Send magic package over clients network..."); } this.LogInformation("{amount} clients with the same ip address were found.", clientsInSameNetwork.Count); foreach (var clientInSameNetwork in clientsInSameNetwork) { if (_connectionManager.ClientConnections.TryGetValue(clientInSameNetwork.ClientId, out var connection)) { this.LogDebug("Send magic package from client #{id}", clientInSameNetwork.ClientId); try { await WakeOnLanResource.WakeOnLan(macAddress, connection); } catch (Exception e) { this.LogWarning(e, "Sending magic package from client #{id} failed.", clientInSameNetwork.ClientId); continue; } this.LogInformation("Magic package sent from client #{id}.", clientInSameNetwork.ClientId); } } } return(Log(HttpStatusCode.OK)); }
public Task <HttpResponseMessage> InvokeAsync(ShutdownCommandInfo commandInfo, TaskExecutionContext context, CancellationToken cancellationToken) { context.ReportStatus("Shutting down..."); context.AfterExecutionCallback = ExecuteShutdown; return(Task.FromResult(Ok())); }
public async Task <HttpResponseMessage> InvokeAsync(ServerTestCommandInfo commandInfo, TaskExecutionContext context, CancellationToken cancellationToken) { for (int i = 0; i < 100; i++) { await Task.Delay(400, cancellationToken); context.ReportProgress(i / 100d); context.ReportStatus($"Doing some stuff ({i}%)"); } return(new HttpResponseMessage(HttpStatusCode.OK)); }
private static async Task <bool> WriteData(Stream targetStream, FileSource fileSource, TaskExecutionContext context, ILogger logger) { if (fileSource.Data.Scheme == FileSource.Base64Scheme) { logger?.LogDebug("Write Base64 binary to file"); context.ReportStatus("Write Base64 to file..."); var buffer = Convert.FromBase64String(fileSource.Data.AbsolutePath); targetStream.Write(buffer, 0, buffer.Length); return(true); } if (fileSource.Data.Scheme == "http" || fileSource.Data.Scheme == "https") { context.ReportStatus("Download headers..."); var httpClient = context.Services.GetRequiredService <IHttpClientService>().Client; using (var response = await httpClient.GetAsync(fileSource.Data, HttpCompletionOption.ResponseHeadersRead)) { if (!response.IsSuccessStatusCode) { logger?.LogError("Requesting {uri} failed with status {status}.", fileSource.Data, response.StatusCode); return(false); } using (var contentStream = await response.Content.ReadAsStreamAsync()) { var buffer = ArrayPool <byte> .Shared.Rent(8192); try { var contentLength = response.Content.Headers.ContentLength; var totalDataLoaded = 0; while (true) { var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); if (read == 0) { break; } targetStream.Write(buffer, 0, read); totalDataLoaded += read; if (contentLength != null) { context.ReportProgress((double)totalDataLoaded / contentLength); } context.ReportStatus($"Downloading... ({DataSizeFormatter.BytesToString(totalDataLoaded)})"); } } finally { ArrayPool <byte> .Shared.Return(buffer); } } return(true); } } throw new ArgumentOutOfRangeException(nameof(fileSource), fileSource.Data.Scheme, "The scheme is not supported as file source."); }