Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions __mocks__/@vtex/diagnostics-semconv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Mock para @vtex/diagnostics-semconv
const ATTR_VTEX_ACCOUNT_NAME = 'vtex.account.name'
const ATTR_VTEX_IO_WORKSPACE_NAME = 'vtex_io.workspace.name'
const ATTR_VTEX_IO_WORKSPACE_TYPE = 'vtex_io.workspace.type'
const ATTR_VTEX_IO_APP_ID = 'vtex_io.app.id'
const ATTR_VTEX_IO_APP_AUTHOR_TYPE = 'vtex_io.app.author-type'

export {
ATTR_VTEX_ACCOUNT_NAME,
ATTR_VTEX_IO_WORKSPACE_NAME,
ATTR_VTEX_IO_WORKSPACE_TYPE,
ATTR_VTEX_IO_APP_ID,
ATTR_VTEX_IO_APP_AUTHOR_TYPE,
}
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ module.exports = {
},
testRegex: '(.*(test|spec)).tsx?$',
testEnvironment: 'node',
moduleNameMapper: {
'^@vtex/diagnostics-semconv$': '<rootDir>/__mocks__/@vtex/diagnostics-semconv.ts',
},
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@types/koa": "^2.11.0",
"@types/koa-compose": "^3.2.3",
"@vtex/diagnostics-nodejs": "0.1.0-io-beta.20",
"@vtex/diagnostics-semconv": "^1.1.2",
"@vtex/node-error-report": "^0.0.3",
"@wry/equality": "^0.1.9",
"agentkeepalive": "^4.0.2",
Expand Down
33 changes: 13 additions & 20 deletions src/HttpClient/HttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@ import { createHash } from 'crypto'
import { IncomingMessage } from 'http'
import compose from 'koa-compose'
import pLimit from 'p-limit'

import {
BINDING_HEADER,
HeaderKeys,
BODY_HASH,
FORWARDED_HOST_HEADER,
LOCALE_HEADER,
PRODUCT_HEADER,
SEGMENT_HEADER,
SESSION_HEADER,
TENANT_HEADER,
} from '../constants'
import { Logger } from '../service/logger'
import { IOContext } from '../service/worker/runtime/typings'
Expand Down Expand Up @@ -89,14 +82,14 @@ export class HttpClient {
...defaultHeaders,
'Accept-Encoding': 'gzip',
'User-Agent': userAgent,
...host ? { [FORWARDED_HOST_HEADER]: host } : null,
...tenant ? { [TENANT_HEADER]: formatTenantHeaderValue(tenant) } : null,
...binding ? { [BINDING_HEADER]: formatBindingHeaderValue(binding) } : null,
...locale ? { [LOCALE_HEADER]: locale } : null,
...operationId ? { 'x-vtex-operation-id': operationId } : null,
...product ? { [PRODUCT_HEADER]: product } : null,
...segmentToken ? { [SEGMENT_HEADER]: segmentToken } : null,
...sessionToken ? { [SESSION_HEADER]: sessionToken } : null,
...host ? { [HeaderKeys.FORWARDED_HOST]: host } : null,
...tenant ? { [HeaderKeys.TENANT]: formatTenantHeaderValue(tenant) } : null,
...binding ? { [HeaderKeys.BINDING]: formatBindingHeaderValue(binding) } : null,
...locale ? { [HeaderKeys.LOCALE]: locale } : null,
...operationId ? { [HeaderKeys.OPERATION_ID]: operationId } : null,
...product ? { [HeaderKeys.PRODUCT]: product } : null,
...segmentToken ? { [HeaderKeys.SEGMENT]: segmentToken } : null,
...sessionToken ? { [HeaderKeys.SESSION]: sessionToken } : null,
}

if (authType && authToken) {
Expand Down Expand Up @@ -139,16 +132,16 @@ export class HttpClient {
return typeof v !== 'object' || v === null || Array.isArray(v) ? v :
Object.fromEntries(Object.entries(v).sort(([ka], [kb]) =>
ka < kb ? -1 : ka > kb ? 1 : 0))
}
catch(error) {
}
catch(error) {
// I don't believe this will ever happen, but just in case
// Also, I didn't include error as I am unsure if it would have sensitive information
this.logger.warn({message: 'Error while sorting object for cache key'})
return v
}
}


const bodyHash = createHash('md5').update(JSON.stringify(data, deterministicReplacer)).digest('hex')
const cacheableConfig = this.getConfig(url, {
...config,
Expand Down
10 changes: 5 additions & 5 deletions src/HttpClient/middlewares/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AxiosRequestConfig, AxiosResponse } from 'axios'
import { Span } from 'opentracing'

import { CacheLayer } from '../../caches/CacheLayer'
import { LOCALE_HEADER, SEGMENT_HEADER, SESSION_HEADER } from '../../constants'
import { HeaderKeys } from '../../constants'
import { IOContext } from '../../service/worker/runtime/typings'
import { ErrorReport } from '../../tracing'
import { HttpLogEvents } from '../../tracing/LogEvents'
Expand All @@ -15,7 +15,7 @@ const cacheableStatusCodes = [200, 203, 204, 206, 300, 301, 404, 405, 410, 414,

export const cacheKey = (config: AxiosRequestConfig) => {
const {baseURL = '', url = '', params, headers} = config
const locale = headers?.[LOCALE_HEADER]
const locale = headers?.[HeaderKeys.LOCALE]

const encodedBaseURL = baseURL.replace(/\//g, '\\')
const encodedURL = url.replace(/\//g, '\\')
Expand Down Expand Up @@ -97,7 +97,7 @@ export const cacheMiddleware = ({ type, storage, asyncSet }: CacheOptions) => {
const { rootSpan: span, tracer, logger } = ctx.tracing ?? {}

const key = cacheKey(ctx.config)
const segmentToken = ctx.config.headers?.[SEGMENT_HEADER]
const segmentToken = ctx.config.headers?.[HeaderKeys.SEGMENT]
const keyWithSegment = key + segmentToken

span?.log({
Expand Down Expand Up @@ -204,11 +204,11 @@ export const cacheMiddleware = ({ type, storage, asyncSet }: CacheOptions) => {
}

const shouldCache = maxAge || etag
const varySession = ctx.response.headers.vary && ctx.response.headers.vary.includes(SESSION_HEADER)
const varySession = ctx.response.headers.vary && ctx.response.headers.vary.includes(HeaderKeys.SESSION)
if (shouldCache && !varySession) {
const {responseType, responseEncoding: configResponseEncoding} = ctx.config
const currentAge = revalidated ? 0 : age
const varySegment = ctx.response.headers.vary && ctx.response.headers.vary.includes(SEGMENT_HEADER)
const varySegment = ctx.response.headers.vary && ctx.response.headers.vary.includes(HeaderKeys.SEGMENT)
const setKey = varySegment ? keyWithSegment : key
const responseEncoding = configResponseEncoding || (responseType === 'arraybuffer' ? 'base64' : undefined)
const cacheableData = type === CacheType.Disk && responseType === 'arraybuffer'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MockSpanContext } from '@tiagonapoli/opentracing-alternate-mock'
import { AxiosError, AxiosInstance } from 'axios'
import { REFERENCE_CHILD_OF, REFERENCE_FOLLOWS_FROM } from 'opentracing'
import { ROUTER_CACHE_HEADER } from '../../../../../constants'
import { HeaderKeys } from '../../../../../constants'
import { SpanReferenceTypes } from '../../../../../tracing'
import { ErrorReportLogFields } from '../../../../../tracing/LogFields'
import { CustomHttpTags, OpentracingTags } from '../../../../../tracing/Tags'
Expand Down Expand Up @@ -141,7 +141,7 @@ export const registerSharedTestSuite = (testSuiteConfig: TestSuiteConfig) => {

if (testSuiteConfig.testServer) {
it(`Properly assigns router cache tag when it's present`, async () => {
testSuiteConfig.testServer!.mockResponseHeaders({ [ROUTER_CACHE_HEADER]: 'MISS' })
testSuiteConfig.testServer!.mockResponseHeaders({ [HeaderKeys.ROUTER_CACHE]: 'MISS' })
const { allRequestSpans } = await TracedTestRequest.doRequest(http, testSuiteConfig.requestsConfig)
allRequestSpans.forEach((requestSpan) => {
expect(requestSpan.tags()[CustomHttpTags.HTTP_ROUTER_CACHE_RESULT]).toEqual('MISS')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import buildFullPath from '../../../../../../utils/buildFullPath'
import { Span } from 'opentracing'
import { ROUTER_CACHE_HEADER } from '../../../../../../constants'
import { HeaderKeys } from '../../../../../../constants'
import { CustomHttpTags, OpentracingTags } from '../../../../../../tracing/Tags'
import { cloneAndSanitizeHeaders } from '../../../../../../tracing/utils'

Expand All @@ -24,7 +24,8 @@ export const injectResponseInfoOnSpan = (span: Span | undefined, response: Axios

span?.log({ 'response-headers': cloneAndSanitizeHeaders(response.headers) })
span?.setTag(OpentracingTags.HTTP_STATUS_CODE, response.status)
if (response.headers[ROUTER_CACHE_HEADER]) {
span?.setTag(CustomHttpTags.HTTP_ROUTER_CACHE_RESULT, response.headers[ROUTER_CACHE_HEADER])

if (response.headers[HeaderKeys.ROUTER_CACHE]) {
span?.setTag(CustomHttpTags.HTTP_ROUTER_CACHE_RESULT, response.headers[HeaderKeys.ROUTER_CACHE])
}
}
5 changes: 2 additions & 3 deletions src/clients/janus/Segment.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import parseCookie from 'cookie'
import { prop } from 'ramda'

import { PRODUCT_HEADER } from '../../constants'
import { HeaderKeys } from '../../constants'
import { inflightUrlWithQuery, RequestTracingConfig } from '../../HttpClient'
import { JanusClient } from './JanusClient'

Expand Down Expand Up @@ -87,7 +86,7 @@ export class Segment extends JanusClient {
forceMaxAge: SEGMENT_MAX_AGE_S,
headers: {
'Content-Type': 'application/json',
[PRODUCT_HEADER]: product || '',
[HeaderKeys.PRODUCT]: product || '',
},
inflightKey: inflightUrlWithQuery,
metric,
Expand Down
Loading
Loading