Skip to content

Commit

Permalink
feat: add w3c support to 233a
Browse files Browse the repository at this point in the history
  • Loading branch information
dweber019 committed May 25, 2024
1 parent 1b5cb29 commit 2fc1f3a
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ npm run lint-fix # format source files
| [#229][#229] | [SHOULD consider to design `POST` and `PATCH` idempotent][#229] | :grey_exclamation: | :grey_exclamation: | - |
| [#230][#230] | [MAY consider to support `Idempotency-Key` header][#230] | :grey_exclamation: | :grey_exclamation: | - |
| [#231][#231] | [Should use secondary key for idempotent `POST` design][#231] | :grey_exclamation: | :grey_exclamation: | - |
| [#233a][#233a] | [MUST request must use b3 tracing headers][#233a] | - | :heavy_check_mark: | - |
| [#233a][#233a] | [MUST request must use tracing headers][#233a] | - | :heavy_check_mark: | - |
| [#234][#234] | [MUST only use durable and immutable remote references][#234] | :grey_exclamation: | :grey_exclamation: | - |
| [#235][#235] | [SHOULD name date/time properties with `_at` suffix][#235] | - | - | - |
| [#236][#236] | [SHOULD design simple query languages using query parameters][#236] | :grey_exclamation: | :grey_exclamation: | - |
Expand Down Expand Up @@ -368,7 +368,7 @@ npm run lint-fix # format source files
[#230]: https://opensource.zalando.com/restful-api-guidelines/#230
[#231]: https://opensource.zalando.com/restful-api-guidelines/#231
[#233]: https://opensource.zalando.com/restful-api-guidelines/#233
[#233a]: ./doc/rules/requests-must-use-b3-tracing.md
[#233a]: ./doc/rules/requests-must-use-tracing.md
[#234]: https://opensource.zalando.com/restful-api-guidelines/#234
[#235]: https://opensource.zalando.com/restful-api-guidelines/#235
[#236]: https://opensource.zalando.com/restful-api-guidelines/#236
Expand Down
18 changes: 9 additions & 9 deletions baloise.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extends: [./zalando.yml] # We're extending the zalando ruleset by replacing or adding baloise specific rules.

functions:
- validate-b3-tracing
- validate-tracing
- assert-http-codes-for-operation

rules:
Expand Down Expand Up @@ -149,21 +149,21 @@ rules:
'default': [ ALL ]


# MUST request must provide b3 tracing [233a]
# MUST request must provide tracing [233a]
# => Alternative to https://opensource.zalando.com/restful-api-guidelines/#233

must-use-b3-tracing:
message: B3 header X-B3-Traceid or X-B3-Spanid missing
description: MUST use b3 tracing [233a]
documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/requests-must-use-b3-tracing.md
must-use-tracing:
message: Header X-B3-Traceid, X-B3-Spanid or traceparent (w3c) missing
description: MUST use b3 or w3c tracing [233a]
documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/requests-must-use-tracing.md
severity: error
given: $.paths.*
then:
function: validate-b3-tracing
function: validate-tracing


# MUST provide API audience [219]
# => https://opensource.zalando.com/restful-api-guidelines/#219
# MUST provide API audience [219]
# => https://opensource.zalando.com/restful-api-guidelines/#219

must-provide-api-audience: off

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# MUST request must provide b3 tracing headers
# MUST request must provide tracing headers
The following header parameter must be provided for any request:

- `X-B3-Traceid`
- `X-B3-Spanid`
or
- `traceparent`

Specification: You can find the specification for b3 [here](https://github.com/openzipkin/b3-propagation)
Specification: You can find the specification for b3 [here](https://github.com/openzipkin/b3-propagation) and w3c [here](https://www.w3.org/TR/trace-context/)
Rationale: We have an internal survey with all developers and the decision was b3 [Internal link](https://confluence.baloisenet.com/atlassian/x/LxWJj).
20 changes: 17 additions & 3 deletions functions/validate-b3-tracing.js → functions/validate-tracing.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,22 @@ function isB3Valid(targetValue) {
return !(b3Params.length !== 2 || !b3Params.every((param) => param.in === 'header'));
}

function isW3cValid(targetValue) {
if (!Array.isArray(targetValue)) {
return [
{
message: `No array given, provide $.paths.*.*.parameters`,
},
];
}

const w3cParams = targetValue.filter((param) => param.name && param.name.toLowerCase() === 'traceparent');

return !(w3cParams.length !== 1 || !w3cParams.every((param) => param.in === 'header'));
}

export default (targetValue) => {
if (targetValue.parameters && isB3Valid(targetValue.parameters)) {
if (targetValue.parameters && (isB3Valid(targetValue.parameters) || isW3cValid(targetValue.parameters))) {
return [];
}

Expand All @@ -27,12 +41,12 @@ export default (targetValue) => {
['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'].includes(verb.toLowerCase()),
)
.map((verb) => targetValue[verb])
.some((operation) => operation.parameters && !isB3Valid(operation.parameters));
.some((operation) => operation.parameters && !isB3Valid(operation.parameters) && !isW3cValid(operation.parameters));

if (hasInvalidEntry) {
return [
{
message: `B3 header X-B3-Traceid or X-B3-Spanid missing`,
message: `Header X-B3-Traceid, X-B3-Spanid or traceparent (w3c) missing`,
},
];
}
Expand Down
34 changes: 30 additions & 4 deletions tests/233a-MUST-request-must-provide-b3-tracing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ describe('MUST request must provide b3 tracing [233a]', () => {
const result = await lint(openApi, 'baloise');
expect(result).toEqual([
expect.objectContaining({
code: 'must-use-b3-tracing',
message: 'B3 header X-B3-Traceid or X-B3-Spanid missing',
code: 'must-use-tracing',
message: 'Header X-B3-Traceid, X-B3-Spanid or traceparent (w3c) missing',
severity: DiagnosticSeverity.Error,
}),
]);
Expand All @@ -27,8 +27,8 @@ describe('MUST request must provide b3 tracing [233a]', () => {
const result = await lint(openApi, 'baloise');
expect(result).toEqual([
expect.objectContaining({
code: 'must-use-b3-tracing',
message: 'B3 header X-B3-Traceid or X-B3-Spanid missing',
code: 'must-use-tracing',
message: 'Header X-B3-Traceid, X-B3-Spanid or traceparent (w3c) missing',
severity: DiagnosticSeverity.Error,
}),
]);
Expand Down Expand Up @@ -59,4 +59,30 @@ describe('MUST request must provide b3 tracing [233a]', () => {
const result = await lint(openApi, 'baloise');
expect(result).toEqual([]);
});

test('Assert w3c tracing headers valid', async () => {
const openApi = await loadOpenApiSpec('base-openapi.yml');
openApi.paths['/example'].get.parameters = openApi.paths['/example'].get.parameters.filter(
(param: { $ref: string }) =>
!param['$ref'] &&
param['$ref'] !== '#/components/parameters/HeaderB3TraceId' &&
param['$ref'] !== '#/components/parameters/HeaderB3SpanId',
);
openApi.paths['/example'].get.parameters.push({
$ref: '#/components/parameters/HeaderW3cTraceparent',
});

const result = await lint(openApi, 'baloise');
expect(result).toEqual([]);
});

test('Assert w3c and b3 tracing headers valid', async () => {
const openApi = await loadOpenApiSpec('base-openapi.yml');
openApi.paths['/example'].get.parameters.push({
$ref: '#/components/parameters/HeaderW3cTraceparent',
});

const result = await lint(openApi, 'baloise');
expect(result).toEqual([]);
});
});
6 changes: 6 additions & 0 deletions tests/fixtures/base-openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ components:
required: false
schema:
type: string
HeaderW3cTraceparent:
in: header
name: traceparent
required: true
schema:
type: string
schemas:
Example:
type: object
Expand Down

0 comments on commit 2fc1f3a

Please sign in to comment.