From 86821a231badedc74d61006f118be6d4bce8dbab Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Fri, 22 Apr 2022 17:33:35 +0200 Subject: [PATCH 01/14] feat: serve AsyncAPI JSON Schema definitions --- README.md | 10 ++++++++++ edge-functions/serve-definitions.ts | 11 +++++++++++ netlify.toml | 10 +++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 edge-functions/serve-definitions.ts diff --git a/README.md b/README.md index 6d3495d11bfb..f6b4258cad6f 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,14 @@ npm run build Generated files of the website go to the `.next` folder. +## JSON Schema definitions + +All AsyncAPI JSON Schema definition files are being served within the `/definitions/` path. The content is literally being served from GH, in particular from https://github.com/asyncapi/spec-json-schemas/tree/master/schemas. +This is possible thanks to the following: + +1. A [Netlify Rewrite rule](https://docs.netlify.com/routing/redirects/rewrites-proxies/) located in the [netlify.toml](netlify.toml) file, which acts as proxy for all requests to the `/definitions/` path, serving the content from GH without having an HTTP redirect. +2. A [Netlify Edge Function](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) that modifies the `Content-Type` header of the rewrite response to become `application/schema+json`. This lets tooling, such as [Hyperjump](https://json-schema.hyperjump.io), to fetch the schemas directly from their URL. + ## Project structure This repository has the following structure: @@ -85,6 +93,8 @@ This repository has the following structure: ├── public # Data for site metadata and static blog such as images ├── scripts # Scripts used in the build and dev processes ├── next.config.js # Next.js configuration file + ├── netlify # Code that runs on Netlify + │ ├── edge-functions # Netlify Edge-Functions code ├── postcss.config.js # PostCSS configuration file └── tailwind.config.js # TailwindCSS configuration file ``` diff --git a/edge-functions/serve-definitions.ts b/edge-functions/serve-definitions.ts new file mode 100644 index 000000000000..3ec85c3d232e --- /dev/null +++ b/edge-functions/serve-definitions.ts @@ -0,0 +1,11 @@ +import type { Context } from "netlify:edge"; + +export default async (request: Request, context: Context) => { + const response = await context.next(); + + // Setting proper Content-Type header for JSON Schema files. + // This lets tooling fetch the schemas directly from their URL. + response.headers.set("Content-Type", "application/schema+json"); + + return response; +}; \ No newline at end of file diff --git a/netlify.toml b/netlify.toml index 401897d653d9..2848f0327bf0 100644 --- a/netlify.toml +++ b/netlify.toml @@ -7,4 +7,12 @@ command = "npm run build && npm run export" functions = "netlify/functions" publish = "out" - \ No newline at end of file + +[[redirects]] + from = "/definitions/*" + to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" + status = 200 + +[[edge_functions]] +function = "serve-definitions" +path = "/definitions/*" From 0dbfa263d9908e0f504a87a4d22a0212b71757f7 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Fri, 22 Apr 2022 18:10:47 +0200 Subject: [PATCH 02/14] fix wrong dir --- {edge-functions => netlify/edge-functions}/serve-definitions.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {edge-functions => netlify/edge-functions}/serve-definitions.ts (100%) diff --git a/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts similarity index 100% rename from edge-functions/serve-definitions.ts rename to netlify/edge-functions/serve-definitions.ts From 25c1e03e4a9c1adaaa16db2f2e9b48371b32390f Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Sun, 24 Apr 2022 20:07:04 +0200 Subject: [PATCH 03/14] Update README.md Co-authored-by: Alejandra Quetzalli --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6b4258cad6f..31e9341593b4 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Generated files of the website go to the `.next` folder. ## JSON Schema definitions -All AsyncAPI JSON Schema definition files are being served within the `/definitions/` path. The content is literally being served from GH, in particular from https://github.com/asyncapi/spec-json-schemas/tree/master/schemas. +All AsyncAPI JSON Schema definition files are being served within the `/definitions/` path. The content is being served from GH, in particular from https://github.com/asyncapi/spec-json-schemas/tree/master/schemas. This is possible thanks to the following: 1. A [Netlify Rewrite rule](https://docs.netlify.com/routing/redirects/rewrites-proxies/) located in the [netlify.toml](netlify.toml) file, which acts as proxy for all requests to the `/definitions/` path, serving the content from GH without having an HTTP redirect. From b8c463b919eb55ce222809c9b8dee8d546052855 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Mon, 2 May 2022 19:48:37 +0200 Subject: [PATCH 04/14] authorization + cleanup headers --- netlify/edge-functions/serve-definitions.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 3ec85c3d232e..be532230ddbc 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -1,6 +1,15 @@ import type { Context } from "netlify:edge"; export default async (request: Request, context: Context) => { + + // Deleting Origin header, which is involved in the cache policy, so requests can hit GH cache. + // Reason: raw.githubusercontent.com responses include vary: Authorization,Accept-Encoding,Origin + request.headers.delete("origin"); + + // Setting GH Token to increase GH rate limit to 5,000 req/h. + request.headers.set("Authorization", "token " + Deno.env.get("GITHUB_TOKEN")); + + // Fetching the definition file const response = await context.next(); // Setting proper Content-Type header for JSON Schema files. From 9e994c2dc51639cbaeba4be5a4cb331c8244eb40 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Wed, 4 May 2022 16:21:45 +0200 Subject: [PATCH 05/14] add a new path /schemas for definitions fetched from schemastore.org --- netlify.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/netlify.toml b/netlify.toml index 2848f0327bf0..8975db61f7d7 100644 --- a/netlify.toml +++ b/netlify.toml @@ -8,6 +8,7 @@ functions = "netlify/functions" publish = "out" +# Used by JSON Schema definitions fetched directly from AsyncAPI website [[redirects]] from = "/definitions/*" to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" @@ -16,3 +17,14 @@ [[edge_functions]] function = "serve-definitions" path = "/definitions/*" + +# Used by JSON Schema definitions fetched from schemastore.org +[[redirects]] + from = "/schemas/*" + to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" + status = 200 + +[[edge_functions]] +function = "serve-definitions" +path = "/schemas/*" + From 4ce68cbecd544bdcab79496a62aa04154d5f03cf Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Wed, 4 May 2022 16:22:03 +0200 Subject: [PATCH 06/14] send metrics to NR --- netlify/edge-functions/serve-definitions.ts | 66 ++++++++++++++++++--- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index be532230ddbc..824438c5847d 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -1,20 +1,72 @@ import type { Context } from "netlify:edge"; -export default async (request: Request, context: Context) => { +const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN"); +const NR_ACCOUNT = Deno.env.get("NR_ACCOUNT"); +const NR_API_KEY = Deno.env.get("NR_API_KEY"); +export default async (request: Request, context: Context) => { // Deleting Origin header, which is involved in the cache policy, so requests can hit GH cache. // Reason: raw.githubusercontent.com responses include vary: Authorization,Accept-Encoding,Origin request.headers.delete("origin"); // Setting GH Token to increase GH rate limit to 5,000 req/h. - request.headers.set("Authorization", "token " + Deno.env.get("GITHUB_TOKEN")); + request.headers.set("Authorization", "token " + GITHUB_TOKEN); // Fetching the definition file const response = await context.next(); - - // Setting proper Content-Type header for JSON Schema files. - // This lets tooling fetch the schemas directly from their URL. - response.headers.set("Content-Type", "application/schema+json"); + + if (response.status === 200) { + // Setting proper Content-Type header for JSON Schema files. + // This lets tooling fetch the schemas directly from their URL. + response.headers.set("Content-Type", "application/schema+json"); + + // Sending metrics to NR. + await sendMetrics(request, context); + } return response; -}; \ No newline at end of file +}; + +async function sendMetrics(request: Request, context: Context) { + try { + const rawResponse = await doFetch(`https://insights-collector.eu01.nr-data.net/v1/accounts/${NR_ACCOUNT}/events`, { + timeout: 2000, // Success in 2 seconds, cancel if not. User's request is more important than collecting metrics. + method: 'POST', + headers: { + 'Api-Key': NR_API_KEY, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + "eventType":"AsyncAPIJSONSchemaDefinitionDownload", + "path": new URL(request.url).pathname, + }) + }); + + if (rawResponse.status !== 200) { + context.log(`Unexpected response status code when sending metrics: ${rawResponse.status} ${rawResponse.statusText}`); + } + } catch (e) { + if (e instanceof DOMException) { + context.log(`Timeout during sending metrics: ${e}`); + } else { + context.log(`Unexpected error sending metrics: ${e}`); + } + } +} + +interface TimeoutRequestInit extends RequestInit { + timeout: number; +} + +async function doFetch(resource: string, options: TimeoutRequestInit): Promise { + const { timeout = 5000 } = options; + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + const response = await fetch(resource, { + ...options, + signal: controller.signal + }); + clearTimeout(timeoutId); + return response; +} \ No newline at end of file From 202ae0d7ee8efaa2857cd00884b723700348d409 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Wed, 4 May 2022 17:03:02 +0200 Subject: [PATCH 07/14] rename /schemas to /schema-store --- netlify.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netlify.toml b/netlify.toml index 8975db61f7d7..89dba10efc70 100644 --- a/netlify.toml +++ b/netlify.toml @@ -20,11 +20,11 @@ path = "/definitions/*" # Used by JSON Schema definitions fetched from schemastore.org [[redirects]] - from = "/schemas/*" + from = "/schema-store/*" to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" status = 200 [[edge_functions]] function = "serve-definitions" -path = "/schemas/*" +path = "/schema-store/*" From 157636dc61b7367039c3ff469d6e3f30da97042a Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Wed, 4 May 2022 17:03:41 +0200 Subject: [PATCH 08/14] extract event generation --- netlify/edge-functions/serve-definitions.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 824438c5847d..9508510f0a59 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -28,18 +28,22 @@ export default async (request: Request, context: Context) => { }; async function sendMetrics(request: Request, context: Context) { + const splitPath = new URL(request.url).pathname.split("/"); + const event = { + "eventType":"AsyncAPIJSONSchemaDefinitionDownload", + "source": splitPath[1], + "file": splitPath[2], + }; + try { const rawResponse = await doFetch(`https://insights-collector.eu01.nr-data.net/v1/accounts/${NR_ACCOUNT}/events`, { timeout: 2000, // Success in 2 seconds, cancel if not. User's request is more important than collecting metrics. method: 'POST', headers: { - 'Api-Key': NR_API_KEY, + 'Api-Key': NR_API_KEY || "", 'Content-Type': 'application/json' }, - body: JSON.stringify({ - "eventType":"AsyncAPIJSONSchemaDefinitionDownload", - "path": new URL(request.url).pathname, - }) + body: JSON.stringify(event) }); if (rawResponse.status !== 200) { From 6dd2945ac71154a21b90192be5e8471b6856ef4e Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:20:13 +0200 Subject: [PATCH 09/14] notify NR on errors --- netlify/edge-functions/serve-definitions.ts | 71 +++++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 9508510f0a59..390493c725c8 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -15,26 +15,58 @@ export default async (request: Request, context: Context) => { // Fetching the definition file const response = await context.next(); - if (response.status === 200) { + if (response.ok) { // Setting proper Content-Type header for JSON Schema files. // This lets tooling fetch the schemas directly from their URL. response.headers.set("Content-Type", "application/schema+json"); // Sending metrics to NR. - await sendMetrics(request, context); + const event = { + "eventType": "AsyncAPIJSONSchemaDefinitionDownload", + }; + + await sendEventToNR(request, context, event); + } else { + // Notifying NR of the error. + const event = { + "eventType": "AsyncAPIJSONSchemaDefinitionDownloadError", + "responseStatus": response.status, + "responseStatusText": response.statusText, + }; + + await sendEventToNR(request, context, event); } - + return response; }; -async function sendMetrics(request: Request, context: Context) { +interface TimeoutRequestInit extends RequestInit { + timeout: number; +} + +async function doFetch(resource: string, options: TimeoutRequestInit): Promise { + const { timeout = 5000 } = options; + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + const response = await fetch(resource, {...options, signal: controller.signal}); + clearTimeout(timeoutId); + return response; +} + +interface NREvent { + eventType: string; + source?: string; + file?: string; +} + +async function sendEventToNR(request: Request, context: Context, event: NREvent) { const splitPath = new URL(request.url).pathname.split("/"); - const event = { - "eventType":"AsyncAPIJSONSchemaDefinitionDownload", - "source": splitPath[1], - "file": splitPath[2], - }; - + if (event.source === "" || event.source === undefined) { + event.source = splitPath[1]; + event.file = splitPath[2]; + } + try { const rawResponse = await doFetch(`https://insights-collector.eu01.nr-data.net/v1/accounts/${NR_ACCOUNT}/events`, { timeout: 2000, // Success in 2 seconds, cancel if not. User's request is more important than collecting metrics. @@ -45,7 +77,7 @@ async function sendMetrics(request: Request, context: Context) { }, body: JSON.stringify(event) }); - + if (rawResponse.status !== 200) { context.log(`Unexpected response status code when sending metrics: ${rawResponse.status} ${rawResponse.statusText}`); } @@ -56,21 +88,4 @@ async function sendMetrics(request: Request, context: Context) { context.log(`Unexpected error sending metrics: ${e}`); } } -} - -interface TimeoutRequestInit extends RequestInit { - timeout: number; -} - -async function doFetch(resource: string, options: TimeoutRequestInit): Promise { - const { timeout = 5000 } = options; - - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), timeout); - const response = await fetch(resource, { - ...options, - signal: controller.signal - }); - clearTimeout(timeoutId); - return response; } \ No newline at end of file From 5c4614405ee3e5850c1747254a9e6e6276e37285 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Tue, 14 Jun 2022 17:58:42 +0200 Subject: [PATCH 10/14] redirect to README in / path --- netlify.toml | 10 ++++++++++ netlify/edge-functions/serve-definitions.ts | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index 89dba10efc70..177d7f27c17a 100644 --- a/netlify.toml +++ b/netlify.toml @@ -9,6 +9,11 @@ publish = "out" # Used by JSON Schema definitions fetched directly from AsyncAPI website +[[redirects]] + from = "/definitions" + to = "https://github.com/asyncapi/spec-json-schemas/tree/master/schemas" + status = 200 + [[redirects]] from = "/definitions/*" to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" @@ -19,6 +24,11 @@ function = "serve-definitions" path = "/definitions/*" # Used by JSON Schema definitions fetched from schemastore.org +[[redirects]] + from = "/schema-store" + to = "https://github.com/asyncapi/spec-json-schemas/tree/master/schemas" + status = 200 + [[redirects]] from = "/schema-store/*" to = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/:splat" diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 390493c725c8..567d0d9efa98 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -15,7 +15,8 @@ export default async (request: Request, context: Context) => { // Fetching the definition file const response = await context.next(); - if (response.ok) { + const isRequestingAFile = request.url.charAt(request.url.length - 1) !== "/"; + if (response.ok && isRequestingAFile) { // Setting proper Content-Type header for JSON Schema files. // This lets tooling fetch the schemas directly from their URL. response.headers.set("Content-Type", "application/schema+json"); From 9df31a484fa9d0bd1af9a0d8b73d6562a559ff7c Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Tue, 14 Jun 2022 18:27:25 +0200 Subject: [PATCH 11/14] add url field to NR event --- netlify/edge-functions/serve-definitions.ts | 49 ++++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 567d0d9efa98..ce5dc062e27d 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -16,28 +16,30 @@ export default async (request: Request, context: Context) => { const response = await context.next(); const isRequestingAFile = request.url.charAt(request.url.length - 1) !== "/"; - if (response.ok && isRequestingAFile) { - // Setting proper Content-Type header for JSON Schema files. - // This lets tooling fetch the schemas directly from their URL. - response.headers.set("Content-Type", "application/schema+json"); - - // Sending metrics to NR. - const event = { - "eventType": "AsyncAPIJSONSchemaDefinitionDownload", - }; - - await sendEventToNR(request, context, event); - } else { - // Notifying NR of the error. - const event = { - "eventType": "AsyncAPIJSONSchemaDefinitionDownloadError", - "responseStatus": response.status, - "responseStatusText": response.statusText, - }; - - await sendEventToNR(request, context, event); - } - + if (isRequestingAFile) { + if (response.ok) { + // Setting proper Content-Type header for JSON Schema files. + // This lets tooling fetch the schemas directly from their URL. + response.headers.set("Content-Type", "application/schema+json"); + + // Sending metrics to NR. + const event = { + "eventType": "AsyncAPIJSONSchemaDefinitionDownload", + }; + + await sendEventToNR(request, context, event); + } else { + // Notifying NR of the error. + const event = { + "eventType": "AsyncAPIJSONSchemaDefinitionDownloadError", + "responseStatus": response.status, + "responseStatusText": response.statusText, + }; + + await sendEventToNR(request, context, event); + } + } + return response; }; @@ -57,6 +59,7 @@ async function doFetch(resource: string, options: TimeoutRequestInit): Promise Date: Wed, 15 Jun 2022 19:28:51 +0200 Subject: [PATCH 12/14] Update netlify/edge-functions/serve-definitions.ts Co-authored-by: Lukasz Gornicki --- netlify/edge-functions/serve-definitions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index ce5dc062e27d..0ecdc7e11783 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -1,6 +1,6 @@ import type { Context } from "netlify:edge"; -const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN"); +const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN_NR"); const NR_ACCOUNT = Deno.env.get("NR_ACCOUNT"); const NR_API_KEY = Deno.env.get("NR_API_KEY"); From a6830645e95c4913eb7df3f16234f0465ca1be73 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Wed, 15 Jun 2022 19:56:17 +0200 Subject: [PATCH 13/14] Use New Relic Metrics API Instead of events (retention is way higher) --- netlify/edge-functions/serve-definitions.ts | 86 ++++++++++++++------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 0ecdc7e11783..56f5c2bbdac8 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -1,8 +1,8 @@ import type { Context } from "netlify:edge"; const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN_NR"); -const NR_ACCOUNT = Deno.env.get("NR_ACCOUNT"); const NR_API_KEY = Deno.env.get("NR_API_KEY"); +const NR_METRICS_ENDPOINT = Deno.env.get("NR_METRICS_ENDPOINT") || "https://metric-api.eu.newrelic.com/metric/v1"; export default async (request: Request, context: Context) => { // Deleting Origin header, which is involved in the cache policy, so requests can hit GH cache. @@ -23,20 +23,18 @@ export default async (request: Request, context: Context) => { response.headers.set("Content-Type", "application/schema+json"); // Sending metrics to NR. - const event = { - "eventType": "AsyncAPIJSONSchemaDefinitionDownload", - }; - - await sendEventToNR(request, context, event); + const metric = newNRMetricCount("asyncapi.jsonschema.download.success", request) + + await sendMetricToNR(context, metric); } else { // Notifying NR of the error. - const event = { - "eventType": "AsyncAPIJSONSchemaDefinitionDownloadError", - "responseStatus": response.status, - "responseStatusText": response.statusText, + const attributes = { + "responseStatus": response.status, + "responseStatusText": response.statusText, }; - - await sendEventToNR(request, context, event); + const metric = newNRMetricCount("asyncapi.jsonschema.download.error", request, attributes); + + await sendMetricToNR(context, metric); } } @@ -57,34 +55,22 @@ async function doFetch(resource: string, options: TimeoutRequestInit): Promise Date: Wed, 15 Jun 2022 20:00:11 +0200 Subject: [PATCH 14/14] lint --- netlify/edge-functions/serve-definitions.ts | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 56f5c2bbdac8..02db60860f58 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -21,23 +21,23 @@ export default async (request: Request, context: Context) => { // Setting proper Content-Type header for JSON Schema files. // This lets tooling fetch the schemas directly from their URL. response.headers.set("Content-Type", "application/schema+json"); - + // Sending metrics to NR. const metric = newNRMetricCount("asyncapi.jsonschema.download.success", request) - + await sendMetricToNR(context, metric); } else { // Notifying NR of the error. const attributes = { - "responseStatus": response.status, - "responseStatusText": response.statusText, + "responseStatus": response.status, + "responseStatusText": response.statusText, }; const metric = newNRMetricCount("asyncapi.jsonschema.download.error", request, attributes); - + await sendMetricToNR(context, metric); } - } - + } + return response; }; @@ -50,17 +50,17 @@ async function doFetch(resource: string, options: TimeoutRequestInit): Promise controller.abort(), timeout); - const response = await fetch(resource, {...options, signal: controller.signal}); + const response = await fetch(resource, { ...options, signal: controller.signal }); clearTimeout(timeoutId); return response; } async function sendMetricToNR(context: Context, metric: NRMetric) { - const metrics = [{"metrics": [metric]}]; + const metrics = [{ "metrics": [metric] }]; console.log(JSON.stringify(metrics)); try { - const rawResponse = await doFetch(NR_METRICS_ENDPOINT, { + const rawResponse = await doFetch(NR_METRICS_ENDPOINT, { timeout: 2000, // Success in 2 seconds, cancel if not. User's request is more important than collecting metrics. method: 'POST', headers: { @@ -87,7 +87,7 @@ function newNRMetricCount(name: string, request: Request, attributes: any = {}): metric["interval.ms"] = 1; const splitPath = new URL(request.url).pathname.split("/"); - + metric.attributes = { "source": splitPath[1], "file": splitPath[2], @@ -113,7 +113,7 @@ class NRMetric { "interval.ms": number; type: NRMetricType; attributes: any; - + constructor(name: string, type = NRMetricType.Count, value = 1, timestamp = Date.now()) { this.name = name; this.type = type;