diff --git a/server/src/config/services.worker.ts b/server/src/config/services.worker.ts index 82481a162..fdab162f8 100644 --- a/server/src/config/services.worker.ts +++ b/server/src/config/services.worker.ts @@ -13,7 +13,7 @@ import mongoose from "mongoose"; import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; import { SharedServices } from "@/config/services.shared.js"; -import { INetworkService, NetworkService } from "@/service/networkService.js"; +import { IProviderRegistry, ProviderRegistry } from "@/service/networkProviders/providerRegistry.js"; import { IBufferService, BufferService } from "@/service/bufferService.js"; import { IStatusService, StatusService } from "@/service/statusService.js"; import { SecretsRotationService } from "@/service/encryption/secretsRotationService.js"; @@ -24,25 +24,25 @@ import { NotificationReactor } from "@/worker/reactors/reactor.notification.js"; import { IncidentReactor } from "@/worker/reactors/reactor.incident.js"; import { ReactorDispatcher } from "@/worker/reactors/reactor.dispatcher.js"; import { DBQueueWorker } from "@/worker/worker.db-queue.js"; -import { ProxyResolver } from "@/service/network/ProxyResolver.js"; +import { ProxyResolver } from "@/service/networkProviders/ProxyResolver.js"; import { IEgressService, EgressService } from "@/domain/egress/egress.service.js"; // Network providers -import { PingProvider } from "@/service/network/PingProvider.js"; -import { HttpProvider } from "@/service/network/HttpProvider.js"; -import { AdvancedMatcher } from "@/service/network/AdvancedMatcher.js"; -import { PageSpeedProvider } from "@/service/network/PageSpeedProvider.js"; -import { HardwareProvider } from "@/service/network/HardwareProvider.js"; -import { DockerProvider } from "@/service/network/DockerProvider.js"; -import { PortProvider } from "@/service/network/PortProvider.js"; -import { GameProvider } from "@/service/network/GameProvider.js"; -import { GrpcProvider } from "@/service/network/GrpcProvider.js"; -import { WebSocketProvider } from "@/service/network/WebSocketProvider.js"; -import { DNSProvider } from "@/service/network/DNSProvider.js"; +import { PingProvider } from "@/service/networkProviders/PingProvider.js"; +import { HttpProvider } from "@/service/networkProviders/HttpProvider.js"; +import { AdvancedMatcher } from "@/service/networkProviders/AdvancedMatcher.js"; +import { PageSpeedProvider } from "@/service/networkProviders/PageSpeedProvider.js"; +import { HardwareProvider } from "@/service/networkProviders/HardwareProvider.js"; +import { DockerProvider } from "@/service/networkProviders/DockerProvider.js"; +import { PortProvider } from "@/service/networkProviders/PortProvider.js"; +import { GameProvider } from "@/service/networkProviders/GameProvider.js"; +import { GrpcProvider } from "@/service/networkProviders/GrpcProvider.js"; +import { WebSocketProvider } from "@/service/networkProviders/WebSocketProvider.js"; +import { DNSProvider } from "@/service/networkProviders/DNSProvider.js"; import { AppError } from "@/utils/AppError.js"; import { WorkerPipeline } from "@/worker/worker.pipeline.js"; export interface WorkerServices { worker: IQueueWorker; - networkService: INetworkService; + networkService: IProviderRegistry; bufferService: IBufferService; statusService: IStatusService; egressService: IEgressService; @@ -87,7 +87,7 @@ export const buildWorker = async (shared: SharedServices, envSettings: EnvConfig const webSocketProvider = new WebSocketProvider(WebSocket); const dnsProvider = new DNSProvider(() => new Resolver()); - const networkService = new NetworkService(axios, logger, [ + const providerRegistry = new ProviderRegistry([ pingProvider, httpProvider, pageSpeedProvider, @@ -105,7 +105,7 @@ export const buildWorker = async (shared: SharedServices, envSettings: EnvConfig pipeline.ingestChecks(checks) ); const statusService = new StatusService(logger, monitorsRepository, monitorStatsRepository); - const egressService = new EgressService(settingsService, egressStateRepository, jobsRepository, networkService, proxyResolver, logger); + const egressService = new EgressService(settingsService, egressStateRepository, jobsRepository, providerRegistry, proxyResolver, logger); const notificationReactor = new NotificationReactor(notificationsService); const incidentReactor = new IncidentReactor(incidentService); @@ -118,7 +118,7 @@ export const buildWorker = async (shared: SharedServices, envSettings: EnvConfig checksRepository, jobsRepository, checkService, - networkService, + providerRegistry: providerRegistry, proxyResolver, bufferService, dockerLogsService, @@ -188,5 +188,5 @@ export const buildWorker = async (shared: SharedServices, envSettings: EnvConfig }); } - return { worker, networkService, bufferService, statusService, egressService }; + return { worker, networkService: providerRegistry, bufferService, statusService, egressService }; }; diff --git a/server/src/domain/egress/egress.service.ts b/server/src/domain/egress/egress.service.ts index 4e6b0e515..c66d1b325 100644 --- a/server/src/domain/egress/egress.service.ts +++ b/server/src/domain/egress/egress.service.ts @@ -3,8 +3,8 @@ import type { ISettingsService } from "@/domain/app-settings/app-settings.servic import type { IEgressStateRepository } from "@/domain/egress/egress-state.repository.interface.js"; import type { IJobsRepository } from "@/domain/jobs/job.repository.interface.js"; import { jobId, type Job, type JobSeed } from "@/domain/jobs/job.type.js"; -import type { INetworkService } from "@/service/networkService.js"; -import type { IProxyResolver } from "@/service/network/ProxyResolver.js"; +import type { IProviderRegistry } from "@/service/networkProviders/providerRegistry.js"; +import type { IProxyResolver } from "@/service/networkProviders/ProxyResolver.js"; import type { ILogger } from "@/utils/logger.js"; import { EGRESS_RECOVERY_POLL_SECONDS, @@ -13,7 +13,7 @@ import { type EgressProbeResult, type EgressStatus, } from "@/domain/egress/egress.type.js"; -import { timeRequest } from "@/service/network/utils.js"; +import { timeRequest } from "@/service/networkProviders/utils.js"; import { parseEgressTarget, type EgressTarget } from "@/utils/egressTarget.js"; const SERVICE_NAME = "EgressService"; @@ -54,7 +54,7 @@ export class EgressService implements IEgressService { private settingsService: ISettingsService, private egressStateRepository: IEgressStateRepository, private jobsRepository: IJobsRepository, - private networkService: INetworkService, + private networkService: IProviderRegistry, private proxyResolver: IProxyResolver, private logger: ILogger ) {} @@ -100,7 +100,7 @@ export class EgressService implements IEgressService { const { response, responseTime, error } = await timeRequest(async () => { const proxyUrl = await this.proxyResolver.resolve(monitor); return Promise.race([ - this.networkService.requestStatus(monitor, { proxyUrl }), + this.networkService.probe(monitor, { proxyUrl }), new Promise((_, reject) => { timer = setTimeout(() => reject(new Error(`Egress probe timed out after ${PROBE_TIMEOUT_MS}ms`)), PROBE_TIMEOUT_MS); }), diff --git a/server/src/service/globalPingService.ts b/server/src/service/globalPingService.ts index 5a175485f..3fc2cc779 100644 --- a/server/src/service/globalPingService.ts +++ b/server/src/service/globalPingService.ts @@ -3,7 +3,7 @@ import { supportsGeoCheck, type HttpStatusCode } from "@/domain/monitors/monitor import { MonitorType } from "@/domain/monitors/monitor.type.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; -import { isStatusUp } from "@/service/network/utils.js"; +import { isStatusUp } from "@/service/networkProviders/utils.js"; const SERVICE_NAME = "GlobalPingService"; const GLOBAL_PING_API_BASE = "https://api.globalping.io/v1"; diff --git a/server/src/service/network/AdvancedMatcher.ts b/server/src/service/networkProviders/AdvancedMatcher.ts similarity index 100% rename from server/src/service/network/AdvancedMatcher.ts rename to server/src/service/networkProviders/AdvancedMatcher.ts diff --git a/server/src/service/network/DNSProvider.ts b/server/src/service/networkProviders/DNSProvider.ts similarity index 95% rename from server/src/service/network/DNSProvider.ts rename to server/src/service/networkProviders/DNSProvider.ts index 475026c54..a0aaa9d38 100644 --- a/server/src/service/network/DNSProvider.ts +++ b/server/src/service/networkProviders/DNSProvider.ts @@ -1,10 +1,10 @@ import { DNSStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import dns from "dns"; import type { Resolver } from "dns/promises"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; -import { timeRequest } from "@/service/network/utils.js"; +import { timeRequest } from "@/service/networkProviders/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; const SERVICE_NAME = "DNSProvider"; diff --git a/server/src/service/network/DockerProvider.ts b/server/src/service/networkProviders/DockerProvider.ts similarity index 99% rename from server/src/service/network/DockerProvider.ts rename to server/src/service/networkProviders/DockerProvider.ts index a25e847ca..3bf9e3353 100644 --- a/server/src/service/network/DockerProvider.ts +++ b/server/src/service/networkProviders/DockerProvider.ts @@ -1,7 +1,7 @@ import https from "node:https"; -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; -import { HttpProvider } from "@/service/network/HttpProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; +import { HttpProvider } from "@/service/networkProviders/HttpProvider.js"; import { CaptureDockerContainer, CaptureDockerStatusPayload, CheckContext, DockerStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { @@ -24,7 +24,7 @@ import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; import Dockerode from "dockerode"; -import { timeRequest, peerAnsweredFromError } from "@/service/network/utils.js"; +import { timeRequest, peerAnsweredFromError } from "@/service/networkProviders/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; import { IEncryptionService } from "@/service/encryption/encryptionService.js"; import { DOCKER_TLS_URL, isCaptureDockerUrl, isDockerTlsUrl } from "@/utils/dockerHost.js"; diff --git a/server/src/service/network/GameProvider.ts b/server/src/service/networkProviders/GameProvider.ts similarity index 96% rename from server/src/service/network/GameProvider.ts rename to server/src/service/networkProviders/GameProvider.ts index 904f304f7..ad8791c49 100644 --- a/server/src/service/network/GameProvider.ts +++ b/server/src/service/networkProviders/GameProvider.ts @@ -1,4 +1,4 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { GameStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { GameDig } from "gamedig"; diff --git a/server/src/service/network/GrpcProvider.ts b/server/src/service/networkProviders/GrpcProvider.ts similarity index 97% rename from server/src/service/network/GrpcProvider.ts rename to server/src/service/networkProviders/GrpcProvider.ts index 9eee2041b..2fe669937 100644 --- a/server/src/service/network/GrpcProvider.ts +++ b/server/src/service/networkProviders/GrpcProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { GrpcStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; -import { timeRequest } from "@/service/network/utils.js"; +import { timeRequest } from "@/service/networkProviders/utils.js"; import * as grpc from "@grpc/grpc-js"; import * as protoLoader from "@grpc/proto-loader"; diff --git a/server/src/service/network/HardwareProvider.ts b/server/src/service/networkProviders/HardwareProvider.ts similarity index 85% rename from server/src/service/network/HardwareProvider.ts rename to server/src/service/networkProviders/HardwareProvider.ts index 840dbc2e8..a25a9dd6f 100644 --- a/server/src/service/network/HardwareProvider.ts +++ b/server/src/service/networkProviders/HardwareProvider.ts @@ -1,7 +1,7 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; -import { HttpProvider } from "@/service/network/HttpProvider.js"; +import { HttpProvider } from "@/service/networkProviders/HttpProvider.js"; import { AppError } from "@/utils/AppError.js"; export class HardwareProvider implements IStatusProvider { diff --git a/server/src/service/network/HttpProvider.ts b/server/src/service/networkProviders/HttpProvider.ts similarity index 97% rename from server/src/service/network/HttpProvider.ts rename to server/src/service/networkProviders/HttpProvider.ts index 9fa705b55..bc9d8ab65 100644 --- a/server/src/service/network/HttpProvider.ts +++ b/server/src/service/networkProviders/HttpProvider.ts @@ -1,12 +1,12 @@ import { type Got, HTTPError, RequestError } from "got"; -import { IAdvancedMatcher } from "@/service/network/AdvancedMatcher.js"; -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IAdvancedMatcher } from "@/service/networkProviders/AdvancedMatcher.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { HttpStatusPayload } from "@/types/network.js"; import { MonitorStatusResponse } from "@/types/network.js"; import { Agent as HttpsAgent } from "https"; import { Agent as HttpAgent } from "http"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; -import { isStatusUp, peerAnsweredFromError } from "@/service/network/utils.js"; +import { isStatusUp, peerAnsweredFromError } from "@/service/networkProviders/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; import CacheableLookup from "cacheable-lookup"; import { HttpProxyAgent, HttpsProxyAgent } from "hpagent"; diff --git a/server/src/service/network/IStatusProvider.ts b/server/src/service/networkProviders/IStatusProvider.ts similarity index 100% rename from server/src/service/network/IStatusProvider.ts rename to server/src/service/networkProviders/IStatusProvider.ts diff --git a/server/src/service/network/PageSpeedProvider.ts b/server/src/service/networkProviders/PageSpeedProvider.ts similarity index 92% rename from server/src/service/network/PageSpeedProvider.ts rename to server/src/service/networkProviders/PageSpeedProvider.ts index bbc2016b2..1c6df8537 100644 --- a/server/src/service/network/PageSpeedProvider.ts +++ b/server/src/service/networkProviders/PageSpeedProvider.ts @@ -1,7 +1,7 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { MonitorStatusResponse, PageSpeedStatusPayload } from "@/types/network.js"; import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.type.js"; -import { HttpProvider } from "@/service/network/HttpProvider.js"; +import { HttpProvider } from "@/service/networkProviders/HttpProvider.js"; import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/network/PingProvider.ts b/server/src/service/networkProviders/PingProvider.ts similarity index 97% rename from server/src/service/network/PingProvider.ts rename to server/src/service/networkProviders/PingProvider.ts index 7a6abb33a..67e0cbe68 100644 --- a/server/src/service/network/PingProvider.ts +++ b/server/src/service/networkProviders/PingProvider.ts @@ -5,7 +5,7 @@ import { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import ping from "ping"; import * as net from "net"; -import { timeRequest } from "@/service/network/utils.js"; +import { timeRequest } from "@/service/networkProviders/utils.js"; const SERVICE_NAME = "PingProvider"; type Ping = typeof ping; diff --git a/server/src/service/network/PortProvider.ts b/server/src/service/networkProviders/PortProvider.ts similarity index 96% rename from server/src/service/network/PortProvider.ts rename to server/src/service/networkProviders/PortProvider.ts index bb21d0799..e28d9d6ed 100644 --- a/server/src/service/network/PortProvider.ts +++ b/server/src/service/networkProviders/PortProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { PortStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; -import { timeRequest, peerAnsweredFromError } from "@/service/network/utils.js"; +import { timeRequest, peerAnsweredFromError } from "@/service/networkProviders/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; import * as net from "net"; type NetType = typeof net; diff --git a/server/src/service/network/ProxyResolver.ts b/server/src/service/networkProviders/ProxyResolver.ts similarity index 100% rename from server/src/service/network/ProxyResolver.ts rename to server/src/service/networkProviders/ProxyResolver.ts diff --git a/server/src/service/network/WebSocketProvider.ts b/server/src/service/networkProviders/WebSocketProvider.ts similarity index 96% rename from server/src/service/network/WebSocketProvider.ts rename to server/src/service/networkProviders/WebSocketProvider.ts index be9873d41..b37c1529a 100644 --- a/server/src/service/network/WebSocketProvider.ts +++ b/server/src/service/networkProviders/WebSocketProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/networkProviders/IStatusProvider.js"; import { WebSocketStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; -import { timeRequest, peerAnsweredFromError } from "@/service/network/utils.js"; +import { timeRequest, peerAnsweredFromError } from "@/service/networkProviders/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; import type WebSocket from "ws"; diff --git a/server/src/service/networkProviders/providerRegistry.ts b/server/src/service/networkProviders/providerRegistry.ts new file mode 100644 index 000000000..f7cc9c63a --- /dev/null +++ b/server/src/service/networkProviders/providerRegistry.ts @@ -0,0 +1,34 @@ +import type { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; +import type { CheckContext, MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js"; +import { NETWORK_ERROR } from "@/types/network.js"; +import { IStatusProvider } from "./IStatusProvider.js"; +const SERVICE_NAME = "NetworkService"; + +export interface IProviderRegistry { + probe(monitor: Monitor & { type: T }, ctx?: CheckContext): Promise>; +} + +export class ProviderRegistry implements IProviderRegistry { + static SERVICE_NAME = SERVICE_NAME; + + constructor(private providers: IStatusProvider[]) {} + + async probe(monitor: Monitor & { type: T }, ctx?: CheckContext): Promise> { + const provider = this.providers.find((p) => p.supports(monitor.type)); + if (!provider) { + return this.handleUnsupportedType(monitor.type) as Promise>; + } + return provider.handle(monitor, ctx) as Promise>; + } + + private async handleUnsupportedType(type: string): Promise { + return { + monitorId: "unknown", + teamId: "unknown", + type: "unknown", + status: false, + code: NETWORK_ERROR, + message: `Unsupported type: ${type}`, + }; + } +} diff --git a/server/src/service/network/utils.ts b/server/src/service/networkProviders/utils.ts similarity index 100% rename from server/src/service/network/utils.ts rename to server/src/service/networkProviders/utils.ts diff --git a/server/src/service/networkService.ts b/server/src/service/networkService.ts deleted file mode 100644 index 69e97b092..000000000 --- a/server/src/service/networkService.ts +++ /dev/null @@ -1,198 +0,0 @@ -import type { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; -import type { CheckContext, MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js"; -import type { AxiosStatic } from "axios"; -import { AppError } from "@/utils/AppError.js"; -import { NETWORK_ERROR } from "@/types/network.js"; -import { ILogger } from "@/utils/logger.js"; -import { IStatusProvider } from "./network/IStatusProvider.js"; -const SERVICE_NAME = "NetworkService"; - -export interface INetworkService { - requestStatus(monitor: Monitor & { type: T }, ctx?: CheckContext): Promise>; - requestWebhook( - type: string, - url: string, - body: unknown - ): Promise<{ type: string; status: boolean; code: number; message: string; payload?: unknown }>; - requestPagerDuty(args: { message: string; routingKey: string; monitorUrl: string }): Promise; - requestMatrix(args: { homeserverUrl: string; accessToken: string; roomId: string; message: string }): Promise<{ - status: boolean; - code: number; - message: string; - payload?: unknown; - }>; -} - -export class NetworkService implements INetworkService { - static SERVICE_NAME = SERVICE_NAME; - - private axios: AxiosStatic; - private logger: ILogger; - - constructor( - axios: AxiosStatic, - logger: ILogger, - private providers: IStatusProvider[] - ) { - this.axios = axios; - this.logger = logger; - } - - // Main entry point - async requestStatus( - monitor: Monitor & { type: T }, - ctx?: CheckContext - ): Promise> { - const provider = this.providers.find((p) => p.supports(monitor.type)); - if (!provider) { - return this.handleUnsupportedType(monitor.type) as Promise>; - } - return provider.handle(monitor, ctx) as Promise>; - } - - private async handleUnsupportedType(type: string): Promise { - return { - monitorId: "unknown", - teamId: "unknown", - type: "unknown", - status: false, - code: NETWORK_ERROR, - message: `Unsupported type: ${type}`, - }; - } - - // Other network requests unrelated to monitoring: - async requestWebhook(type: string, url: string, body: unknown) { - try { - const response = await this.axios.post(url, body, { - headers: { - "Content-Type": "application/json", - }, - }); - - return { - type: "webhook", - status: true, - code: response.status, - message: `Successfully sent ${type} notification`, - payload: response.data, - }; - } catch (err: unknown) { - this.logger.warn({ - message: err instanceof Error ? err.message : String(err), - service: SERVICE_NAME, - method: "requestWebhook", - }); - - if (err && typeof err === "object" && "response" in err) { - const axiosError = err as { response?: { status?: number; data?: unknown } }; - return { - type: "webhook", - status: false, - code: axiosError.response?.status ?? NETWORK_ERROR, - message: `Failed to send ${type} notification`, - payload: axiosError.response?.data, - }; - } - - return { - type: "webhook", - status: false, - code: NETWORK_ERROR, - message: `Failed to send ${type} notification`, - }; - } - } - - async requestPagerDuty({ message, routingKey, monitorUrl }: { message: string; routingKey: string; monitorUrl: string }) { - try { - const response = await this.axios.post(`https://events.pagerduty.com/v2/enqueue`, { - routing_key: routingKey, - event_action: "trigger", - payload: { - summary: message, - severity: "critical", - source: monitorUrl, - timestamp: new Date().toISOString(), - }, - }); - - if (response.data?.status !== "success") return false; - return true; - } catch (err: unknown) { - const originalMessage = err instanceof Error ? err.message : String(err); - - throw new AppError({ - message: originalMessage || "Error sending PagerDuty notification", - service: SERVICE_NAME, - method: "requestPagerDuty", - details: { - responseData: err && typeof err === "object" && "response" in err ? (err as { response?: { data?: unknown } }).response?.data : undefined, - }, - }); - } - } - - async requestMatrix({ - homeserverUrl, - accessToken, - roomId, - message, - }: { - homeserverUrl: string; - accessToken: string; - roomId: string; - message: string; - }) { - try { - const url = `${homeserverUrl}/_matrix/client/v3/rooms/${roomId}/send/m.room.message?access_token=${accessToken}`; - const body = { - msgtype: "m.text", - body: message, - format: "org.matrix.custom.html", - formatted_body: message, - }; - const response = await this.axios.post(url, body, { - headers: { - "Content-Type": "application/json", - }, - }); - - return { - status: true, - code: response.status, - message: "Successfully sent Matrix notification", - }; - } catch (err: unknown) { - if (err instanceof Error) { - this.logger.warn({ - message: err.message, - service: SERVICE_NAME, - method: "requestMatrix", - }); - - if (err && typeof err === "object" && "response" in err) { - const axiosError = err as { response?: { status?: number; data?: unknown } }; - return { - status: false, - code: axiosError.response?.status || NETWORK_ERROR, - message: "Failed to send Matrix notification", - payload: axiosError.response?.data, - }; - } - } - - this.logger.warn({ - message: String(err), - service: SERVICE_NAME, - method: "requestMatrix", - }); - - return { - status: false, - code: NETWORK_ERROR, - message: "Failed to send Matrix notification", - }; - } - } -} diff --git a/server/src/worker/worker.pipeline.ts b/server/src/worker/worker.pipeline.ts index ef5949229..b980371c9 100644 --- a/server/src/worker/worker.pipeline.ts +++ b/server/src/worker/worker.pipeline.ts @@ -9,8 +9,8 @@ import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/main import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; import { isEgressAttributable, Monitor } from "@/domain/monitors/monitor.type.js"; import { IBufferService } from "@/service/bufferService.js"; -import { IProxyResolver } from "@/service/network/ProxyResolver.js"; -import { INetworkService } from "@/service/networkService.js"; +import { IProxyResolver } from "@/service/networkProviders/ProxyResolver.js"; +import { IProviderRegistry } from "@/service/networkProviders/providerRegistry.js"; import { IStatusService } from "@/service/statusService.js"; import { DockerStatusPayload, MonitorStatusResponse, StatusChangeResult } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; @@ -36,7 +36,7 @@ export interface WorkerPipelineDependencies { checksRepository: IChecksRepository; jobsRepository: IJobsRepository; checkService: ICheckService; - networkService: INetworkService; + providerRegistry: IProviderRegistry; proxyResolver: IProxyResolver; bufferService: IBufferService; dockerLogsService: IDockerLogsService; @@ -103,7 +103,7 @@ export class WorkerPipeline implements IWorkerPipeline { const proxyUrl = await this.deps.proxyResolver.resolve(monitor); const dockerTlsKey = await this.resolveDockerTlsKey(monitor); - const status = await this.deps.networkService.requestStatus(monitor, { proxyUrl, dockerTlsKey }); + const status = await this.deps.providerRegistry.probe(monitor, { proxyUrl, dockerTlsKey }); if (!status) { throw new Error("No network response"); }