From afe648773c0c924553f4bcd2e869b62def690080 Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Mon, 3 Jul 2023 23:09:43 +0700 Subject: [PATCH 1/6] fix(connect): fix wrong rpcMetada.route value not handle nested route --- .../src/instrumentation.ts | 67 ++++++++++++++- .../src/internal-types.ts | 7 +- .../test/instrumentation.test.ts | 83 +++++++++++++++++++ 3 files changed, 153 insertions(+), 4 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts index a2fce4cd40..340a639dc5 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts @@ -23,7 +23,13 @@ import { ConnectNames, ConnectTypes, } from './enums/AttributeNames'; -import { Use, UseArgs, UseArgs2 } from './internal-types'; +import { + _LAYERS_STORE_PROPERTY, + PatchedRequest, + Use, + UseArgs, + UseArgs2, +} from './internal-types'; import { VERSION } from './version'; import { InstrumentationBase, @@ -35,6 +41,22 @@ import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; export const ANONYMOUS_NAME = 'anonymous'; +const addNewStackLayer = (request: PatchedRequest) => { + if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) { + Object.defineProperty(request, _LAYERS_STORE_PROPERTY, { + enumerable: false, + value: [], + }); + } + request[_LAYERS_STORE_PROPERTY].push('/'); +}; + +const replaceCurrentStackRoute = (request: PatchedRequest, value?: string) => { + if (value) { + request[_LAYERS_STORE_PROPERTY].splice(-1, 1, value); + } +}; + /** Connect instrumentation for OpenTelemetry */ export class ConnectInstrumentation extends InstrumentationBase { constructor(config: InstrumentationConfig = {}) { @@ -65,6 +87,9 @@ export class ConnectInstrumentation extends InstrumentationBase { if (!isWrapped(patchedApp.use)) { this._wrap(patchedApp, 'use', this._patchUse.bind(this)); } + if (!isWrapped(patchedApp.handle)) { + this._wrap(patchedApp, 'handle', this._patchHandle.bind(this)); + } } private _patchConstructor(original: () => Server): () => Server { @@ -120,13 +145,20 @@ export class ConnectInstrumentation extends InstrumentationBase { if (!instrumentation.isEnabled()) { return (middleWare as any).apply(this, arguments); } - const [resArgIdx, nextArgIdx] = isErrorMiddleware ? [2, 3] : [1, 2]; + const [reqArgIdx, resArgIdx, nextArgIdx] = isErrorMiddleware + ? [1, 2, 3] + : [0, 1, 2]; + const req = arguments[reqArgIdx] as PatchedRequest; const res = arguments[resArgIdx] as ServerResponse; const next = arguments[nextArgIdx] as NextFunction; + replaceCurrentStackRoute(req, routeName); + const rpcMetadata = getRPCMetadata(context.active()); if (routeName && rpcMetadata?.type === RPCType.HTTP) { - rpcMetadata.route = routeName; + rpcMetadata.route = req[_LAYERS_STORE_PROPERTY].reduce( + (acc, sub) => acc.replace(/\/+$/, '') + sub + ); } let spanName = ''; if (routeName) { @@ -180,4 +212,33 @@ export class ConnectInstrumentation extends InstrumentationBase { return original.apply(this, args as UseArgs2); }; } + + public _patchHandle(original: Server['handle']): Server['handle'] { + const instrumentation = this; + return function ( + this: Server, + req: PatchedRequest, + res: ServerResponse, + out?: Function + ): ReturnType { + addNewStackLayer(req); + + function completeStack() { + req[_LAYERS_STORE_PROPERTY].pop(); + } + const done = out + ? instrumentation._patchOut(out as NextFunction, completeStack) + : undefined; + + return original.apply(this, [req, res, done as Function]); + }; + } + + public _patchOut(out: NextFunction, completeStack: () => void): NextFunction { + return function nextFunction(this: NextFunction, err?: any): void { + completeStack(); + const result = out.apply(this, [err]); + return result; + }; + } } diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts index 15947a401f..93a131b4a1 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts @@ -14,9 +14,14 @@ * limitations under the License. */ -import type { HandleFunction, Server } from 'connect'; +import type { HandleFunction, IncomingMessage, Server } from 'connect'; + +export const _LAYERS_STORE_PROPERTY = '__ot_middlewares'; export type UseArgs1 = [HandleFunction]; export type UseArgs2 = [string, HandleFunction]; export type UseArgs = UseArgs1 | UseArgs2; export type Use = (...args: UseArgs) => Server; +export type PatchedRequest = { + [_LAYERS_STORE_PROPERTY]: string[]; +} & IncomingMessage; diff --git a/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts b/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts index e871885e2b..c6ab9456d2 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts @@ -243,5 +243,88 @@ describe('connect', () => { changedRootSpan.spanContext().spanId ); }); + + it('should append nested route in RpcMetadata', async () => { + const rootSpan = tracer.startSpan('root span'); + const rpcMetadata: RPCMetadata = { type: RPCType.HTTP, span: rootSpan }; + app.use((req, res, next) => { + return context.with( + setRPCMetadata( + trace.setSpan(context.active(), rootSpan), + rpcMetadata + ), + next + ); + }); + + const nestedApp = connect(); + + app.use('/foo/', nestedApp); + nestedApp.use('/bar/', (req, res, next) => { + next(); + }); + + await httpRequest.get(`http://localhost:${PORT}/foo/bar`); + rootSpan.end(); + + assert.strictEqual(rpcMetadata.route, '/foo/bar/'); + }); + + it('should use latest match route when multiple route is match', async () => { + const rootSpan = tracer.startSpan('root span'); + const rpcMetadata: RPCMetadata = { type: RPCType.HTTP, span: rootSpan }; + app.use((req, res, next) => { + return context.with( + setRPCMetadata( + trace.setSpan(context.active(), rootSpan), + rpcMetadata + ), + next + ); + }); + + app.use('/foo', (req, res, next) => { + next(); + }); + + app.use('/foo/bar', (req, res, next) => { + next(); + }); + + await httpRequest.get(`http://localhost:${PORT}/foo/bar`); + rootSpan.end(); + + assert.strictEqual(rpcMetadata.route, '/foo/bar'); + }); + + it('should use latest match route when multiple route is match (with nested app)', async () => { + const rootSpan = tracer.startSpan('root span'); + const rpcMetadata: RPCMetadata = { type: RPCType.HTTP, span: rootSpan }; + app.use((req, res, next) => { + return context.with( + setRPCMetadata( + trace.setSpan(context.active(), rootSpan), + rpcMetadata + ), + next + ); + }); + + const nestedApp = connect(); + + app.use('/foo/', nestedApp); + nestedApp.use('/bar/', (req, res, next) => { + next(); + }); + + app.use('/foo/bar/test', (req, res, next) => { + next(); + }); + + await httpRequest.get(`http://localhost:${PORT}/foo/bar/test`); + rootSpan.end(); + + assert.strictEqual(rpcMetadata.route, '/foo/bar/test'); + }); }); }); From 088ea7ef5936adcc20ec2291269d4827eab05e5d Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Tue, 11 Jul 2023 13:55:32 +0700 Subject: [PATCH 2/6] fix: update base on PR feedback --- .../src/instrumentation.ts | 21 +++++++++---------- .../src/internal-types.ts | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts index 340a639dc5..061f3d23e6 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts @@ -216,29 +216,28 @@ export class ConnectInstrumentation extends InstrumentationBase { public _patchHandle(original: Server['handle']): Server['handle'] { const instrumentation = this; return function ( - this: Server, - req: PatchedRequest, - res: ServerResponse, - out?: Function + this: Server ): ReturnType { + const [reqIdx, outIdx] = [0, 2] + const req = arguments[reqIdx] as PatchedRequest + const out = arguments[outIdx] addNewStackLayer(req); function completeStack() { req[_LAYERS_STORE_PROPERTY].pop(); } - const done = out - ? instrumentation._patchOut(out as NextFunction, completeStack) - : undefined; + if (typeof out === 'function') { + arguments[outIdx] = instrumentation._patchOut(out as NextFunction, completeStack) + } - return original.apply(this, [req, res, done as Function]); + return (original as any).apply(this, arguments); }; } public _patchOut(out: NextFunction, completeStack: () => void): NextFunction { - return function nextFunction(this: NextFunction, err?: any): void { + return function nextFunction(this: NextFunction, ...args: any[]): void { completeStack(); - const result = out.apply(this, [err]); - return result; + return Reflect.apply(out, this, args); }; } } diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts index 93a131b4a1..1f3f4fb37b 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts @@ -16,7 +16,7 @@ import type { HandleFunction, IncomingMessage, Server } from 'connect'; -export const _LAYERS_STORE_PROPERTY = '__ot_middlewares'; +export const _LAYERS_STORE_PROPERTY: unique symbol = Symbol('__ot_middlewares'); export type UseArgs1 = [HandleFunction]; export type UseArgs2 = [string, HandleFunction]; From 320ee81d4db52c4f7a9ef8999f0a5648e4e1bdc8 Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Tue, 11 Jul 2023 14:01:31 +0700 Subject: [PATCH 3/6] fix: lint issue --- .../src/instrumentation.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts index 061f3d23e6..9eb3044d5a 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts @@ -215,19 +215,20 @@ export class ConnectInstrumentation extends InstrumentationBase { public _patchHandle(original: Server['handle']): Server['handle'] { const instrumentation = this; - return function ( - this: Server - ): ReturnType { - const [reqIdx, outIdx] = [0, 2] - const req = arguments[reqIdx] as PatchedRequest - const out = arguments[outIdx] + return function (this: Server): ReturnType { + const [reqIdx, outIdx] = [0, 2]; + const req = arguments[reqIdx] as PatchedRequest; + const out = arguments[outIdx]; addNewStackLayer(req); function completeStack() { req[_LAYERS_STORE_PROPERTY].pop(); } if (typeof out === 'function') { - arguments[outIdx] = instrumentation._patchOut(out as NextFunction, completeStack) + arguments[outIdx] = instrumentation._patchOut( + out as NextFunction, + completeStack + ); } return (original as any).apply(this, arguments); From bc8a618acc60c1b32532cb41fa2b1ec03656fcbc Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Sat, 12 Aug 2023 02:01:28 +0700 Subject: [PATCH 4/6] Fix PR's feedback --- .../src/instrumentation.ts | 28 +----- .../src/internal-types.ts | 2 +- .../src/utils.ts | 40 ++++++++ .../test/utils.test.ts | 98 +++++++++++++++++++ 4 files changed, 143 insertions(+), 25 deletions(-) create mode 100644 plugins/node/opentelemetry-instrumentation-connect/src/utils.ts create mode 100644 plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts index 9eb3044d5a..0b17c55a56 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts @@ -24,7 +24,6 @@ import { ConnectTypes, } from './enums/AttributeNames'; import { - _LAYERS_STORE_PROPERTY, PatchedRequest, Use, UseArgs, @@ -38,25 +37,10 @@ import { isWrapped, } from '@opentelemetry/instrumentation'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; +import { replaceCurrentStackRoute, addNewStackLayer, generateRoute } from './utils'; export const ANONYMOUS_NAME = 'anonymous'; -const addNewStackLayer = (request: PatchedRequest) => { - if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) { - Object.defineProperty(request, _LAYERS_STORE_PROPERTY, { - enumerable: false, - value: [], - }); - } - request[_LAYERS_STORE_PROPERTY].push('/'); -}; - -const replaceCurrentStackRoute = (request: PatchedRequest, value?: string) => { - if (value) { - request[_LAYERS_STORE_PROPERTY].splice(-1, 1, value); - } -}; - /** Connect instrumentation for OpenTelemetry */ export class ConnectInstrumentation extends InstrumentationBase { constructor(config: InstrumentationConfig = {}) { @@ -156,10 +140,9 @@ export class ConnectInstrumentation extends InstrumentationBase { const rpcMetadata = getRPCMetadata(context.active()); if (routeName && rpcMetadata?.type === RPCType.HTTP) { - rpcMetadata.route = req[_LAYERS_STORE_PROPERTY].reduce( - (acc, sub) => acc.replace(/\/+$/, '') + sub - ); + rpcMetadata.route = generateRoute(req); } + let spanName = ''; if (routeName) { spanName = `request handler - ${routeName}`; @@ -219,11 +202,8 @@ export class ConnectInstrumentation extends InstrumentationBase { const [reqIdx, outIdx] = [0, 2]; const req = arguments[reqIdx] as PatchedRequest; const out = arguments[outIdx]; - addNewStackLayer(req); + const completeStack = addNewStackLayer(req); - function completeStack() { - req[_LAYERS_STORE_PROPERTY].pop(); - } if (typeof out === 'function') { arguments[outIdx] = instrumentation._patchOut( out as NextFunction, diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts index 1f3f4fb37b..34bb3603da 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts @@ -16,7 +16,7 @@ import type { HandleFunction, IncomingMessage, Server } from 'connect'; -export const _LAYERS_STORE_PROPERTY: unique symbol = Symbol('__ot_middlewares'); +export const _LAYERS_STORE_PROPERTY: unique symbol = Symbol('opentelemetry.instrumentation-connect.request-route-stack'); export type UseArgs1 = [HandleFunction]; export type UseArgs2 = [string, HandleFunction]; diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts b/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts new file mode 100644 index 0000000000..be8d95cdc1 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts @@ -0,0 +1,40 @@ +import { diag } from '@opentelemetry/api'; +import { + _LAYERS_STORE_PROPERTY, + PatchedRequest +} from './internal-types'; + +export const addNewStackLayer = (request: PatchedRequest) => { + if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) { + Object.defineProperty(request, _LAYERS_STORE_PROPERTY, { + enumerable: false, + value: [], + }); + } + request[_LAYERS_STORE_PROPERTY].push('/'); + + const stackLength = request[_LAYERS_STORE_PROPERTY].length + + return () => { + if (stackLength === request[_LAYERS_STORE_PROPERTY].length) { + request[_LAYERS_STORE_PROPERTY].pop(); + } else { + diag.warn('Connect: Trying to pop the stack multiple time') + } + } +}; + +export const replaceCurrentStackRoute = (request: PatchedRequest, newRoute?: string) => { + if (newRoute) { + request[_LAYERS_STORE_PROPERTY].splice(-1, 1, newRoute); + } +}; + +// generage route from existing stack on request object. +// splash between stack layer will be dedup +// ["/first/", "/second", "/third/"] => /first/second/thrid/ +export const generateRoute = (request: PatchedRequest) => { + return request[_LAYERS_STORE_PROPERTY].reduce( + (acc, sub) => acc.replace(/\/+$/, '') + sub + ) +} \ No newline at end of file diff --git a/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts new file mode 100644 index 0000000000..91404b7651 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts @@ -0,0 +1,98 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as assert from 'assert'; + +import { PatchedRequest, _LAYERS_STORE_PROPERTY } from "../src/internal-types"; +import { addNewStackLayer, generateRoute, replaceCurrentStackRoute } from "../src/utils"; + +describe('utils', () => { + describe('addNewStackLayer', () => { + it("should inject new array to symbol property if not exist", () => { + const fakeRequest = { + + } as PatchedRequest + + addNewStackLayer(fakeRequest) + + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 1); + }) + + it("should append new stack item if private symbol already exists", () => { + const stack = ["/first"] + const fakeRequest = { + [_LAYERS_STORE_PROPERTY]: stack + } as PatchedRequest + + addNewStackLayer(fakeRequest) + + assert.equal(fakeRequest[_LAYERS_STORE_PROPERTY], stack); + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 2); + }) + + it("should return pop method to remove newly add stack", () => { + const fakeRequest = { + + } as PatchedRequest + + const pop = addNewStackLayer(fakeRequest) + + assert.notStrictEqual(pop, undefined); + + pop() + + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 0); + }) + + it("should prevent pop the same stack item multiple time", () => { + const fakeRequest = { + + } as PatchedRequest + + addNewStackLayer(fakeRequest) // add first stack item + const pop = addNewStackLayer(fakeRequest) // add second stack item + + pop() + pop() + + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 1); + }) + }) + + describe('replaceCurrentStackRoute', () => { + it('should replace the last stack item with new value', () => { + const fakeRequest = { + [_LAYERS_STORE_PROPERTY]: ["/first", "/second"] + } as PatchedRequest + + replaceCurrentStackRoute(fakeRequest, "/new_route") + + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 2); + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY][1], "/new_route"); + }) + }) + + describe('generateRoute', () => { + it('should combine the stack and striped anu slash between layer', () => { + const fakeRequest = { + [_LAYERS_STORE_PROPERTY]: ["/first/", "/second", "/third/"] + } as PatchedRequest + + const route = generateRoute(fakeRequest) + + assert.strictEqual(route, "/first/second/third/"); + }) + }) +}); From 1f3dbf2e3476cab6f1602de80146e54ecf9d154e Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Sat, 12 Aug 2023 13:28:00 +0700 Subject: [PATCH 5/6] Fix lint issue --- .../src/instrumentation.ts | 13 ++- .../src/internal-types.ts | 4 +- .../src/utils.ts | 37 +++++--- .../test/utils.test.ts | 84 +++++++++---------- 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts index 0b17c55a56..97a06d8a37 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/instrumentation.ts @@ -23,12 +23,7 @@ import { ConnectNames, ConnectTypes, } from './enums/AttributeNames'; -import { - PatchedRequest, - Use, - UseArgs, - UseArgs2, -} from './internal-types'; +import { PatchedRequest, Use, UseArgs, UseArgs2 } from './internal-types'; import { VERSION } from './version'; import { InstrumentationBase, @@ -37,7 +32,11 @@ import { isWrapped, } from '@opentelemetry/instrumentation'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; -import { replaceCurrentStackRoute, addNewStackLayer, generateRoute } from './utils'; +import { + replaceCurrentStackRoute, + addNewStackLayer, + generateRoute, +} from './utils'; export const ANONYMOUS_NAME = 'anonymous'; diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts index 34bb3603da..b8fce41f36 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/internal-types.ts @@ -16,7 +16,9 @@ import type { HandleFunction, IncomingMessage, Server } from 'connect'; -export const _LAYERS_STORE_PROPERTY: unique symbol = Symbol('opentelemetry.instrumentation-connect.request-route-stack'); +export const _LAYERS_STORE_PROPERTY: unique symbol = Symbol( + 'opentelemetry.instrumentation-connect.request-route-stack' +); export type UseArgs1 = [HandleFunction]; export type UseArgs2 = [string, HandleFunction]; diff --git a/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts b/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts index be8d95cdc1..02887ef518 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/src/utils.ts @@ -1,8 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import { diag } from '@opentelemetry/api'; -import { - _LAYERS_STORE_PROPERTY, - PatchedRequest -} from './internal-types'; +import { _LAYERS_STORE_PROPERTY, PatchedRequest } from './internal-types'; export const addNewStackLayer = (request: PatchedRequest) => { if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) { @@ -12,19 +24,22 @@ export const addNewStackLayer = (request: PatchedRequest) => { }); } request[_LAYERS_STORE_PROPERTY].push('/'); - - const stackLength = request[_LAYERS_STORE_PROPERTY].length + + const stackLength = request[_LAYERS_STORE_PROPERTY].length; return () => { if (stackLength === request[_LAYERS_STORE_PROPERTY].length) { request[_LAYERS_STORE_PROPERTY].pop(); } else { - diag.warn('Connect: Trying to pop the stack multiple time') + diag.warn('Connect: Trying to pop the stack multiple time'); } - } + }; }; -export const replaceCurrentStackRoute = (request: PatchedRequest, newRoute?: string) => { +export const replaceCurrentStackRoute = ( + request: PatchedRequest, + newRoute?: string +) => { if (newRoute) { request[_LAYERS_STORE_PROPERTY].splice(-1, 1, newRoute); } @@ -36,5 +51,5 @@ export const replaceCurrentStackRoute = (request: PatchedRequest, newRoute?: str export const generateRoute = (request: PatchedRequest) => { return request[_LAYERS_STORE_PROPERTY].reduce( (acc, sub) => acc.replace(/\/+$/, '') + sub - ) -} \ No newline at end of file + ); +}; diff --git a/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts index 91404b7651..9ab52f051c 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts @@ -15,84 +15,82 @@ */ import * as assert from 'assert'; -import { PatchedRequest, _LAYERS_STORE_PROPERTY } from "../src/internal-types"; -import { addNewStackLayer, generateRoute, replaceCurrentStackRoute } from "../src/utils"; +import { PatchedRequest, _LAYERS_STORE_PROPERTY } from '../src/internal-types'; +import { + addNewStackLayer, + generateRoute, + replaceCurrentStackRoute, +} from '../src/utils'; describe('utils', () => { describe('addNewStackLayer', () => { - it("should inject new array to symbol property if not exist", () => { - const fakeRequest = { - - } as PatchedRequest + it('should inject new array to symbol property if not exist', () => { + const fakeRequest = {} as PatchedRequest; - addNewStackLayer(fakeRequest) + addNewStackLayer(fakeRequest); assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 1); - }) + }); - it("should append new stack item if private symbol already exists", () => { - const stack = ["/first"] + it('should append new stack item if private symbol already exists', () => { + const stack = ['/first']; const fakeRequest = { - [_LAYERS_STORE_PROPERTY]: stack - } as PatchedRequest + [_LAYERS_STORE_PROPERTY]: stack, + } as PatchedRequest; - addNewStackLayer(fakeRequest) + addNewStackLayer(fakeRequest); assert.equal(fakeRequest[_LAYERS_STORE_PROPERTY], stack); assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 2); - }) - - it("should return pop method to remove newly add stack", () => { - const fakeRequest = { + }); - } as PatchedRequest + it('should return pop method to remove newly add stack', () => { + const fakeRequest = {} as PatchedRequest; - const pop = addNewStackLayer(fakeRequest) + const pop = addNewStackLayer(fakeRequest); assert.notStrictEqual(pop, undefined); - pop() + pop(); assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 0); - }) - - it("should prevent pop the same stack item multiple time", () => { - const fakeRequest = { + }); - } as PatchedRequest + it('should prevent pop the same stack item multiple time', () => { + const fakeRequest = {} as PatchedRequest; - addNewStackLayer(fakeRequest) // add first stack item - const pop = addNewStackLayer(fakeRequest) // add second stack item + addNewStackLayer(fakeRequest); // add first stack item + const pop = addNewStackLayer(fakeRequest); // add second stack item - pop() - pop() + pop(); + pop(); assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 1); - }) - }) + }); + }); describe('replaceCurrentStackRoute', () => { it('should replace the last stack item with new value', () => { const fakeRequest = { - [_LAYERS_STORE_PROPERTY]: ["/first", "/second"] - } as PatchedRequest + [_LAYERS_STORE_PROPERTY]: ['/first', '/second'], + } as PatchedRequest; - replaceCurrentStackRoute(fakeRequest, "/new_route") + replaceCurrentStackRoute(fakeRequest, '/new_route'); assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY].length, 2); - assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY][1], "/new_route"); - }) - }) + assert.strictEqual(fakeRequest[_LAYERS_STORE_PROPERTY][1], '/new_route'); + }); + }); describe('generateRoute', () => { it('should combine the stack and striped anu slash between layer', () => { const fakeRequest = { - [_LAYERS_STORE_PROPERTY]: ["/first/", "/second", "/third/"] - } as PatchedRequest + [_LAYERS_STORE_PROPERTY]: ['/first/', '/second', '/third/'], + } as PatchedRequest; - const route = generateRoute(fakeRequest) + const route = generateRoute(fakeRequest); - assert.strictEqual(route, "/first/second/third/"); - }) - }) + assert.strictEqual(route, '/first/second/third/'); + }); + }); }); From db31f3e641969ce1874969848b9d605ddeec4502 Mon Sep 17 00:00:00 2001 From: Chi Ma Date: Sat, 12 Aug 2023 13:29:56 +0700 Subject: [PATCH 6/6] Fix typo --- .../opentelemetry-instrumentation-connect/test/utils.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts index 9ab52f051c..b62d3d6ab8 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/test/utils.test.ts @@ -83,7 +83,7 @@ describe('utils', () => { }); describe('generateRoute', () => { - it('should combine the stack and striped anu slash between layer', () => { + it('should combine the stack and striped any slash between layer', () => { const fakeRequest = { [_LAYERS_STORE_PROPERTY]: ['/first/', '/second', '/third/'], } as PatchedRequest;