-
Notifications
You must be signed in to change notification settings - Fork 317
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Upload module skeleton. * Blocking in apollo, very very first version * Move graphql implementation to another module. * Blocking for apollo-server-core, ugly but it works, lets find a better way * Use real blocking data * Set blocking to true. * Throw before resolver execution in order to stop the operation's execution flow. * Use HttpQueryError in apollo-server-core * Blocking test in apollo-server-fastify * Refactor graphql blocking. * Remove previous implementation which only supported monitoring. * Add new waf address in order to check the payload of every resolver. * Use apm start resolver address instead of a new one. * Remove mock and perform an actual call to the waf. * Add non blocking graphql test * Move abortController constructor to context creation. This reduces the performance overhead due to just one instance is shared across the whole query exectution. * Add pollo-server-express block tests * Add unit tests. * Add @apollo/server tests * Update test rules for blocking by `graphql.server.resolver` * Block with graphql templates data * Add tests. * Block with graphql data in graphql endpoint * Fix tests. * Execute @apollo/server and apollo-server-express tests * Unify code in @apollo/server and apollo-server-core * update comments * Add appsec.blocked tag in blocked requests * Add test with non graphql block response * Tests for block with redirect * Prevent creation of resolve span when it is blocked before the execution of the resolve code * Refactor addResolver in order to get directives information. * Add tests to block on directives. * Add test for directives. * Undo prevent creating resolve span * Configurable graphql blocking json * Refactor graphql * Using resolver instead of resolvers. * Change graphql channel name to be consistent with the others. * Small changes in blocking * Move resover information resolution to plugin. * Revert "Move resover information resolution to plugin." This reverts commit 7cc8561. * Remove resolver information from context, pass it in a different field instead. * Throw custom exception rather than send an empty array. * Update packages/datadog-instrumentations/src/graphql.js Co-authored-by: Ugaitz Urien <[email protected]> * Change a bit apollo-server-core instrumentation * Protect Header map, if in future version it is moved/removed, prevent breaks * Remove some duplicated code * Update packages/datadog-instrumentations/src/apollo-server.js Co-authored-by: Carles Capell <[email protected]> * Fix comments in the PR * Fix PR comments. * Fix some comments in the PR * Move resolver information formatting to the plugin. * Fix PR comments. * Fix proper use of Promise.race. --------- Co-authored-by: Ugaitz Urien <[email protected]> Co-authored-by: Carles Capell <[email protected]>
- Loading branch information
1 parent
13eb089
commit 0ccbc34
Showing
30 changed files
with
1,238 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
packages/datadog-instrumentations/src/apollo-server-core.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use strict' | ||
|
||
const { AbortController } = require('node-abort-controller') | ||
const { addHook } = require('./helpers/instrument') | ||
const shimmer = require('../../datadog-shimmer') | ||
const dc = require('dc-polyfill') | ||
|
||
const requestChannel = dc.tracingChannel('datadog:apollo-server-core:request') | ||
|
||
addHook({ name: 'apollo-server-core', file: 'dist/runHttpQuery.js', versions: ['>3.0.0'] }, runHttpQueryModule => { | ||
const HttpQueryError = runHttpQueryModule.HttpQueryError | ||
|
||
shimmer.wrap(runHttpQueryModule, 'runHttpQuery', function wrapRunHttpQuery (originalRunHttpQuery) { | ||
return async function runHttpQuery () { | ||
if (!requestChannel.start.hasSubscribers) { | ||
return originalRunHttpQuery.apply(this, arguments) | ||
} | ||
|
||
const abortController = new AbortController() | ||
const abortData = {} | ||
|
||
const runHttpQueryResult = requestChannel.tracePromise( | ||
originalRunHttpQuery, | ||
{ abortController, abortData }, | ||
this, | ||
...arguments) | ||
|
||
const abortPromise = new Promise((resolve, reject) => { | ||
abortController.signal.addEventListener('abort', (event) => { | ||
// runHttpQuery callbacks are writing the response on resolve/reject. | ||
// We should return blocking data in the apollo-server-core HttpQueryError object | ||
reject(new HttpQueryError(abortData.statusCode, abortData.message, true, abortData.headers)) | ||
}, { once: true }) | ||
}) | ||
|
||
return Promise.race([runHttpQueryResult, abortPromise]) | ||
} | ||
}) | ||
|
||
return runHttpQueryModule | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
'use strict' | ||
|
||
const { AbortController } = require('node-abort-controller') | ||
const dc = require('dc-polyfill') | ||
|
||
const { addHook } = require('./helpers/instrument') | ||
const shimmer = require('../../datadog-shimmer') | ||
|
||
const graphqlMiddlewareChannel = dc.tracingChannel('datadog:apollo:middleware') | ||
|
||
const requestChannel = dc.tracingChannel('datadog:apollo:request') | ||
|
||
let HeaderMap | ||
|
||
function wrapExecuteHTTPGraphQLRequest (originalExecuteHTTPGraphQLRequest) { | ||
return async function executeHTTPGraphQLRequest () { | ||
if (!HeaderMap || !requestChannel.start.hasSubscribers) { | ||
return originalExecuteHTTPGraphQLRequest.apply(this, arguments) | ||
} | ||
|
||
const abortController = new AbortController() | ||
const abortData = {} | ||
|
||
const graphqlResponseData = requestChannel.tracePromise( | ||
originalExecuteHTTPGraphQLRequest, | ||
{ abortController, abortData }, | ||
this, | ||
...arguments) | ||
|
||
const abortPromise = new Promise((resolve, reject) => { | ||
abortController.signal.addEventListener('abort', (event) => { | ||
// This method is expected to return response data | ||
// with headers, status and body | ||
const headers = new HeaderMap() | ||
Object.keys(abortData.headers).forEach(key => { | ||
headers.set(key, abortData.headers[key]) | ||
}) | ||
|
||
resolve({ | ||
headers: headers, | ||
status: abortData.statusCode, | ||
body: { | ||
kind: 'complete', | ||
string: abortData.message | ||
} | ||
}) | ||
}, { once: true }) | ||
}) | ||
|
||
return Promise.race([abortPromise, graphqlResponseData]) | ||
} | ||
} | ||
|
||
function apolloExpress4Hook (express4) { | ||
shimmer.wrap(express4, 'expressMiddleware', function wrapExpressMiddleware (originalExpressMiddleware) { | ||
return function expressMiddleware (server, options) { | ||
const originalMiddleware = originalExpressMiddleware.apply(this, arguments) | ||
|
||
return shimmer.wrap(originalMiddleware, function (req, res, next) { | ||
if (!graphqlMiddlewareChannel.start.hasSubscribers) { | ||
return originalMiddleware.apply(this, arguments) | ||
} | ||
|
||
return graphqlMiddlewareChannel.traceSync(originalMiddleware, { req }, this, ...arguments) | ||
}) | ||
} | ||
}) | ||
return express4 | ||
} | ||
|
||
function apolloHeaderMapHook (headerMap) { | ||
HeaderMap = headerMap.HeaderMap | ||
return headerMap | ||
} | ||
|
||
function apolloServerHook (apolloServer) { | ||
shimmer.wrap(apolloServer.ApolloServer.prototype, 'executeHTTPGraphQLRequest', wrapExecuteHTTPGraphQLRequest) | ||
return apolloServer | ||
} | ||
|
||
addHook({ name: '@apollo/server', file: 'dist/cjs/ApolloServer.js', versions: ['>=4.0.0'] }, apolloServerHook) | ||
addHook({ name: '@apollo/server', file: 'dist/cjs/express4/index.js', versions: ['>=4.0.0'] }, apolloExpress4Hook) | ||
addHook({ name: '@apollo/server', file: 'dist/cjs/utils/HeaderMap.js', versions: ['>=4.0.0'] }, apolloHeaderMapHook) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.