diff --git a/app/package.json b/app/package.json index 57e4f5d..7a16f48 100644 --- a/app/package.json +++ b/app/package.json @@ -3,8 +3,8 @@ "private": true, "type": "module", "scripts": { - "dev": "tsx watch src/index.ts", - "start": "tsx src/index.ts", + "dev": "node --env-file-if-exists=.env ./node_modules/tsx/dist/cli.mjs watch src/index.ts", + "start": "node --env-file-if-exists=.env ./node_modules/tsx/dist/cli.mjs src/index.ts", "build": "tsc", "typecheck": "tsc --noEmit" }, diff --git a/app/src/cloud-ingest.ts b/app/src/cloud-ingest.ts new file mode 100644 index 0000000..764559c --- /dev/null +++ b/app/src/cloud-ingest.ts @@ -0,0 +1,25 @@ +const DEFAULT_CLOUD_INGEST_URL = 'http://localhost:3100/ingest' + +export const cloudIngestUrl = + process.env.CLOUD_INGEST_URL ?? DEFAULT_CLOUD_INGEST_URL + +function getHeaders(): Record { + const headers: Record = { + 'content-type': 'application/json', + } + + const apiKey = process.env.CLOUD_INGEST_API_KEY?.trim() + if (apiKey) { + headers['x-api-key'] = apiKey + } + + return headers +} + +export function postCloudIngest(body: unknown): Promise { + return fetch(cloudIngestUrl, { + method: 'POST', + headers: getHeaders(), + body: JSON.stringify(body), + }) +} diff --git a/app/src/handlers/demo-plc.ts b/app/src/handlers/demo-plc.ts index ea44cba..91b9fed 100644 --- a/app/src/handlers/demo-plc.ts +++ b/app/src/handlers/demo-plc.ts @@ -1,11 +1,10 @@ +import { postCloudIngest } from '../cloud-ingest.js' import { parseJson } from '../helpers/parse.js' import type { TopicHandler } from '../types.js' export const TOPIC = 'data/demo/plc/v1' const EDGE = 'demo' -const postUrl = - process.env.CLOUD_INGEST_URL ?? 'https://demo.backend.drill.greact.ru/ingest' type DemoPlcPayload = { tag: string @@ -29,13 +28,7 @@ function toMetric(payload: DemoPlcPayload, timestamp: number): DemoPlcMetric { } async function postMetric(metric: DemoPlcMetric): Promise { - const response = await fetch(postUrl, { - method: 'POST', - headers: { - 'content-type': 'application/json', - }, - body: JSON.stringify(metric), - }) + const response = await postCloudIngest([metric]) if (!response.ok) { const text = await response.text() diff --git a/app/src/handlers/edge5-modbus-v2.ts b/app/src/handlers/edge5-modbus-v2.ts index cd69336..2167fe4 100644 --- a/app/src/handlers/edge5-modbus-v2.ts +++ b/app/src/handlers/edge5-modbus-v2.ts @@ -1,3 +1,4 @@ +import { postCloudIngest } from '../cloud-ingest.js' import { createMetricMapper, type MappedMetric } from '../mapping.js' import type { TopicHandler } from '../types.js' @@ -9,17 +10,9 @@ const mapper = createMetricMapper({ new URL('../mappings/edge5-modbus.json', import.meta.url), }) const REGISTER_COUNT = mapper.tagCount -const postUrl = - process.env.CLOUD_INGEST_URL ?? 'https://demo.backend.drill.greact.ru/ingest' function parseValues(payload: Buffer): number[] { - let value: unknown - - try { - value = JSON.parse(payload.toString('utf8')) as unknown - } catch { - throw new Error(`Expected JSON number[${REGISTER_COUNT}]`) - } + const value = JSON.parse(payload.toString('utf8')) as unknown if ( Array.isArray(value) && @@ -33,13 +26,7 @@ function parseValues(payload: Buffer): number[] { } async function postMetrics(metrics: MappedMetric[]): Promise { - const response = await fetch(postUrl, { - method: 'POST', - headers: { - 'content-type': 'application/json', - }, - body: JSON.stringify(metrics), - }) + const response = await postCloudIngest(metrics) if (!response.ok) { const text = await response.text() diff --git a/app/src/handlers/edge5-modbus.ts b/app/src/handlers/edge5-modbus.ts index 99171ba..5416393 100644 --- a/app/src/handlers/edge5-modbus.ts +++ b/app/src/handlers/edge5-modbus.ts @@ -1,11 +1,10 @@ +import { postCloudIngest } from '../cloud-ingest.js' import type { TopicHandler } from '../types.js' export const TOPIC = 'data/edge5/modbus/v1' const EDGE = 'edge5' const REGISTER_COUNT = 125 -const postUrl = - process.env.CLOUD_INGEST_URL ?? 'https://demo.backend.drill.greact.ru/ingest' type Edge5ModbusMetric = { edge: string @@ -44,13 +43,7 @@ function toMetrics(values: number[], timestamp: number): Edge5ModbusMetric[] { } async function postMetrics(metrics: Edge5ModbusMetric[]): Promise { - const response = await fetch(postUrl, { - method: 'POST', - headers: { - 'content-type': 'application/json', - }, - body: JSON.stringify(metrics), - }) + const response = await postCloudIngest(metrics) if (!response.ok) { const text = await response.text() diff --git a/docker-compose.yml b/docker-compose.yml index fe27b92..5c503f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: HTTP_PORT: "80" WS_PORT: "9090" CLOUD_INGEST_URL: ${CLOUD_INGEST_URL:-https://demo.backend.drill.greact.ru/ingest} + CLOUD_INGEST_API_KEY: ${CLOUD_INGEST_API_KEY:-} EDGE5_MODBUS_V2_MAPPING_FILE: ${EDGE5_MODBUS_V2_MAPPING_FILE:-/app/src/mappings/edge5-modbus.json} volumes: