Imports System.Configuration Imports System.IO Imports System.Net Imports System.Net.Http Imports System.Net.Http.Headers Imports System.Net.Http.Json Imports Microsoft.Extensions.Configuration Imports Microsoft.Extensions.Logging Imports System.Diagnostics Public Class TsNotificacionesClient ' ============================================================ ' LOGGER MULTIPLATAFORMA (Windows → EventLog, Linux → journald) ' ============================================================ Private NotInheritable Class LogProvider Private Shared ReadOnly _factory As ILoggerFactory = LoggerFactory.Create( Sub(builder) builder.AddConsole() ' Linux → journald builder.AddEventLog() ' Windows → Event Viewer End Sub) Public Shared Function CreateLogger(Of T)() As ILogger(Of T) Return _factory.CreateLogger(Of T)() End Function End Class ' ============================================================ ' CAMPOS DE INSTANCIA ' ============================================================ Private ReadOnly _http As HttpClient Private ReadOnly _idAplicacion As Integer Public Sub New(baseUrl As String, idAplicacion As Integer, apiKey As String) _idAplicacion = idAplicacion ServicePointManager.ServerCertificateValidationCallback = Function(s, c, ch, e) True ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11 _http = New HttpClient() With {.BaseAddress = New Uri(baseUrl)} _http.DefaultRequestHeaders.Add("X-Api-Key", apiKey) End Sub ' ============================================================ ' MÉTODO PRINCIPAL: REGISTRAR NOTIFICACIÓN ' ============================================================ Public Shared Async Function RegistrarAsync(titulo As String, descripcion As String, TipoNotificacion As TipoNotificacionEnum, Optional Fichero As Byte() = Nothing, Optional IncluirMensajeEnLogDelSistema As Boolean = True) As Task Try Dim logger = LogProvider.CreateLogger(Of TsNotificacionesClient)() ServicePointManager.ServerCertificateValidationCallback = Function(s, c, ch, e) True ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11 Dim config = New ConfigurationBuilder(). SetBasePath(Directory.GetCurrentDirectory()). AddJsonFile("appsettings.json", [optional]:=False). Build() Dim apiUrl = If(config("TsNotificaciones:ApiUrl"), "http://localhost:7159") Dim idAplicacion = Integer.Parse(If(config("TsNotificaciones:IdAplicacion"), "1")) Dim Origen = If(config("TsNotificaciones:Origen"), "Tecnosis") Dim Aplicacion = If(config("TsNotificaciones:Aplicacion"), idAplicacion.ToString) Dim apiKey = If(config("TsNotificaciones:ApiKey"), String.Empty) Dim nombreServidor = If(config("TsNotificaciones:NombreServidor"), Environment.MachineName) Dim EsWindows = OperatingSystem.IsWindows() If IncluirMensajeEnLogDelSistema Then ' ============================================================ ' LOGGING MULTIPLATAFORMA ' ============================================================ If EsWindows Then ' --- WINDOWS: Event Viewer --- If Not EventLog.SourceExists(Origen) Then EventLog.CreateEventSource(Origen, Aplicacion) End If Dim ele As EventLogEntryType Select Case TipoNotificacion Case TipoNotificacionEnum.INFO ele = EventLogEntryType.Information Case TipoNotificacionEnum.ADVERTENCIA ele = EventLogEntryType.Warning Case TipoNotificacionEnum.ERROR, TipoNotificacionEnum.CRÍTICO ele = EventLogEntryType.Error End Select EventLog.WriteEntry(Origen, $"{titulo} {descripcion}", ele) Else ' --- LINUX: ILogger → journald --- Select Case TipoNotificacion Case TipoNotificacionEnum.INFO logger.LogInformation($"{titulo} {descripcion}") Case TipoNotificacionEnum.ADVERTENCIA logger.LogWarning($"{titulo} {descripcion}") Case TipoNotificacionEnum.ERROR, TipoNotificacionEnum.CRÍTICO logger.LogError($"{titulo} {descripcion}") End Select End If End If ' ============================================================ ' LLAMADA A LA API ' ============================================================ Dim http = New HttpClient() With {.BaseAddress = New Uri(apiUrl)} Dim Tipo = CInt(TipoNotificacion) Dim request = New HttpRequestMessage(HttpMethod.Post, "/api/alertas/registrar") request.Headers.Add("X-Api-Key", apiKey) Dim ipServidor As String = ObtenerIp() request.Content = JsonContent.Create(New With { idAplicacion, nombreServidor, ipServidor, titulo, descripcion, Tipo }) Dim response = Await http.SendAsync(request) Dim body As System.Text.Json.JsonElement = Await response.Content.ReadFromJsonAsync(Of System.Text.Json.JsonElement)() Dim id = body.GetProperty("id").GetInt32() If Fichero IsNot Nothing Then Await SubirFichero(http, apiKey, id, Fichero) End If Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Function ' ============================================================ ' SUBIR FICHERO ' ============================================================ Private Shared Async Function SubirFichero(ByVal http As HttpClient, ByVal apiKey As String, ByVal alertaId As Integer, ByVal datos As Byte()) As Task Try Dim fileContent = New ByteArrayContent(datos) fileContent.Headers.ContentType = New MediaTypeHeaderValue("image/png") Dim multipart = New MultipartFormDataContent() multipart.Add(fileContent, "archivo", "Imagen.png") Dim request = New HttpRequestMessage(HttpMethod.Post, $"/api/alertas/{alertaId}/archivo") request.Headers.Add("X-Api-Key", apiKey) request.Content = multipart Dim response = Await http.SendAsync(request) If Not response.IsSuccessStatusCode Then Throw New Exception($"Subida fallida ({response.StatusCode}): {Await response.Content.ReadAsStringAsync()}") End If Catch httpEx As Exception Throw New Exception(httpEx.Message, httpEx) End Try End Function ' ============================================================ ' OBTENER IP ' ============================================================ Private Shared Function ObtenerIp() As String For Each addr In Dns.GetHostAddresses(Dns.GetHostName()) If addr.AddressFamily = Sockets.AddressFamily.InterNetwork Then Return addr.ToString() Next Return "127.0.0.1" End Function ' ============================================================ ' ENUMERACIÓN ' ============================================================ Public Enum TipoNotificacionEnum INFO = 0 ADVERTENCIA = 1 [ERROR] = 2 CRÍTICO = 3 End Enum End Class