Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: enable labels for api calls #3476

Merged
merged 24 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6ce30f0
chore: enable labels for api calls
Jun 18, 2024
9a39d67
chore: propagate metadata to api call fn in intercom dest
Jun 18, 2024
8c90cf7
chore: metadata propagation in mautic & optimizely_fullstack
Jun 19, 2024
40ed6b1
Merge remote-tracking branch 'origin/develop' into chore.labels-int-api
Jun 19, 2024
57eafca
chore: metadata propagation in active_campaign
Jun 19, 2024
73fcf87
Merge remote-tracking branch 'origin/develop' into chore.labels-int-api
Jun 19, 2024
35dbf6e
chore: metadata propagation in delighted & klaviyo
Jun 19, 2024
39e3d56
chore: add method doc to getRelativePathFromURL
Jun 19, 2024
0df0791
ƒMerge remote-tracking branch 'origin/develop' into chore.labels-int-api
Jun 19, 2024
925206b
chore: add test-cases to test firing of stats based on metadata
Jun 20, 2024
ca78546
Merge remote-tracking branch 'origin/develop' into chore.labels-int-api
Jun 21, 2024
de6f59f
chore: enable labels for api calls - 2 (#3479)
sanpj2292 Jul 2, 2024
b40f7ea
Merge branch 'develop' into chore.labels-int-api
Jul 2, 2024
8f48f01
Merge branch 'develop' into chore.labels-int-api
Jul 2, 2024
0890d1d
chore: remove duplicate metadata key in statTags obj klaviyo
Jul 2, 2024
b9686ce
Merge branch 'develop', remote-tracking branch 'origin' into chore.la…
Jul 5, 2024
744f9d3
Merge branch 'develop' into chore.labels-int-api
Jul 15, 2024
b91ff6f
Merge remote-tracking branch 'origin' into chore.labels-int-api
Jul 16, 2024
8b077bc
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 16, 2024
236f145
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 18, 2024
dff749d
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 18, 2024
c51150c
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 19, 2024
41a408e
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 22, 2024
e4b381e
Merge branch 'develop' of github.com:rudderlabs/rudder-transformer in…
Jul 24, 2024
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
18 changes: 13 additions & 5 deletions src/adapters/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ const lodash = require('lodash');
const http = require('http');
const https = require('https');
const axios = require('axios');
const logger = require('../logger');
const { isDefinedAndNotNull } = require('@rudderstack/integrations-lib');
const stats = require('../util/stats');
const { removeUndefinedValues, isDefinedAndNotNullAndNotEmpty } = require('../v0/util');
const {
removeUndefinedValues,
getErrorStatusCode,
isDefinedAndNotNullAndNotEmpty,
} = require('../v0/util');
const logger = require('../logger');
const { processAxiosResponse } = require('./utils/networkUtils');
// Only for tests
const { setResponsesForMockAxiosAdapter } = require('../../test/testHelper');
Expand Down Expand Up @@ -83,7 +88,9 @@ const fireHTTPStats = (clientResponse, startTime, statTags) => {
const endpointPath = statTags.endpointPath ? statTags.endpointPath : '';
const requestMethod = statTags.requestMethod ? statTags.requestMethod : '';
const module = statTags.module ? statTags.module : '';
const statusCode = clientResponse.success ? clientResponse.response.status : '';
const statusCode = clientResponse.success
? clientResponse.response.status
: getErrorStatusCode(clientResponse.response);
const defArgs = {
destType,
endpointPath,
Expand All @@ -94,9 +101,9 @@ const fireHTTPStats = (clientResponse, startTime, statTags) => {
startTime,
clientResponse,
};
if (statTags?.metadata) {
if (statTags?.metadata && typeof statTags?.metadata === 'object') {
const metadata = !Array.isArray(statTags?.metadata) ? [statTags.metadata] : statTags.metadata;
metadata?.forEach((m) => {
metadata?.filter(isDefinedAndNotNull)?.forEach((m) => {
fireOutgoingReqStats({
...defArgs,
metadata: m,
Expand Down Expand Up @@ -448,4 +455,5 @@ module.exports = {
getFormData,
handleHttpRequest,
enhanceRequestOptions,
fireHTTPStats,
};
313 changes: 312 additions & 1 deletion src/adapters/network.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
const mockLoggerInstance = {
info: jest.fn(),
};
const { getFormData, httpPOST, httpGET, httpSend } = require('./network');
const { getFormData, httpPOST, httpGET, httpSend, fireHTTPStats } = require('./network');
const { getFuncTestData } = require('../../test/testHelper');
jest.mock('../util/stats', () => ({
timing: jest.fn(),
timingSummary: jest.fn(),
increment: jest.fn(),
counter: jest.fn(),
gauge: jest.fn(),
histogram: jest.fn(),
}));
const stats = require('../util/stats');

jest.mock('@rudderstack/integrations-lib', () => {
return {
Expand Down Expand Up @@ -39,6 +48,308 @@ describe(`${funcName} Tests`, () => {
});
});

describe('fireHTTPStats tests', () => {
beforeEach(() => {
stats.timing.mockClear();
stats.counter.mockClear();
});
it('should not throw error when metadata is sent as correctly defined object', () => {
const clientResponse = {
success: true,
response: {
data: { a: 1, b: 2 },
status: 200,
headers: { 'Content-Type': 'application/json' },
},
};
const startTime = new Date();
const statTags = {
metadata: {
destType: 'DT',
destinationId: 'd1',
workspaceId: 'w1',
sourceId: 's1',
},
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);
expect(stats.timing).toHaveBeenCalledTimes(1);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destinationId: 'd1',
workspaceId: 'w1',
sourceId: 's1',
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
it('should not throw error when metadata is sent as correctly defined object[]', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: [
{
destType: 'DT',
destinationId: 'd1',
workspaceId: 'w1',
jobId: 1,
sourceId: 's1',
},
{
destType: 'DT',
jobId: 2,
destinationId: 'd1',
workspaceId: 'w2',
sourceId: 's2',
},
],
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(2);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destinationId: 'd1',
workspaceId: 'w1',
sourceId: 's1',
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
expect(stats.timing).toHaveBeenNthCalledWith(2, 'outgoing_request_latency', startTime, {
destinationId: 'd1',
workspaceId: 'w2',
sourceId: 's2',
destType: 'DT',
module: '',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
it('should not throw error when metadata is not sent', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(1);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
it('should not throw error when metadata is sent as empty array', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: [],
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(0);
});
it('should not throw error when metadata is sent as empty object', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: {},
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(1);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
it('should not throw error when metadata is sent as [null, null]', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: [null, null],
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(0);
});
it('should not throw error when metadata is sent as [1, 2]', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: [1, 2],
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(2);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
expect(stats.timing).toHaveBeenNthCalledWith(2, 'outgoing_request_latency', startTime, {
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
it('should not throw error when metadata is sent as 1', () => {
const clientResponse = {
success: false,
response: {
response: {
data: { errors: [{ e: 'something went bad' }] },
status: 400,
headers: { 'Content-Type': 'application/json' },
},
headers: { 'Content-Type': 'application/json' },
status: 400,
},
};
const startTime = new Date();
const statTags = {
metadata: 1,
destType: 'DT',
feature: 'feat',
endpointPath: '/some/url',
requestMethod: 'post',
};
expect(() => {
fireHTTPStats(clientResponse, startTime, statTags);
}).not.toThrow(Error);

expect(stats.timing).toHaveBeenCalledTimes(1);
expect(stats.timing).toHaveBeenNthCalledWith(1, 'outgoing_request_latency', startTime, {
destType: 'DT',
feature: 'feat',
module: '',
endpointPath: '/some/url',
requestMethod: 'post',
});
});
});

describe('logging in http methods', () => {
beforeEach(() => {
mockLoggerInstance.info.mockClear();
Expand Down
Loading
Loading