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

feat: cm360 transformerproxy V1 features.json update #2848

Merged
merged 7 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
18 changes: 15 additions & 3 deletions src/adapters/networkHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const { getIntegrations } = require('../routes/utils');

const handlers = {
generic: GenericNetworkHandler,
v0: {},
v1: {},
};

// Dynamically import the network handlers for all
Expand All @@ -16,16 +18,26 @@ SUPPORTED_VERSIONS.forEach((version) => {
const destinations = getIntegrations(path.resolve(__dirname, `../${version}/destinations`));
destinations.forEach((dest) => {
try {
handlers[dest] = require(`../${version}/destinations/${dest}/networkHandler`).networkHandler;
// handles = {
// v0: {
// dest: handler
// },
// v1: {
// dest: handler
// },
// generic: GenericNetworkHandler,
// }
handlers[version][dest] =
require(`../${version}/destinations/${dest}/networkHandler`).networkHandler;
} catch {
// Do nothing as exception indicates
// network handler is not defined for that destination
}
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
});
});

const getNetworkHandler = (type) => {
const NetworkHandler = handlers[type] || handlers.generic;
const getNetworkHandler = (type, version) => {
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
const NetworkHandler = handlers[version][type] || handlers.generic;
return new NetworkHandler();
};
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
25 changes: 25 additions & 0 deletions src/adapters/networkHandlerFactory.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { getNetworkHandler } = require('./networkHandlerFactory');
const { networkHandler: GenericNetworkHandler } = require('./networkhandler/genericNetworkHandler');

describe(`Network Handler Tests`, () => {
it('Should return v0 networkhandler', () => {
let proxyHandler = getNetworkHandler('campaign_manager', `v0`);
const cmProxy = require(`../v0/destinations/campaign_manager/networkHandler`).networkHandler;
expect(proxyHandler).toEqual(new cmProxy());
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved

proxyHandler = getNetworkHandler('braze', `v0`);
const brazeProxy = require(`../v0/destinations/braze/networkHandler`).networkHandler;
expect(proxyHandler).toEqual(new brazeProxy());
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
});

it('Should return v1 networkhandler', () => {
let proxyHandler = getNetworkHandler('campaign_manager', `v1`);
const cmProxy = require(`../v1/destinations/campaign_manager/networkHandler`).networkHandler;
expect(proxyHandler).toEqual(new cmProxy());
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
});

it('Should return genericHandler if v1 proxy and handler is not present for destination', () => {
let proxyHandler = getNetworkHandler('braze', `v1`);
expect(proxyHandler).toEqual(new GenericNetworkHandler());
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
});
});
8 changes: 7 additions & 1 deletion src/controllers/delivery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ export class DeliveryController {
const requestMetadata = MiscService.getRequestMetadata(ctx);
const event = ctx.request.body as ProcessorTransformationOutput;
const { destination }: { destination: string } = ctx.params;
const { version }: { version: string } = ctx.params;
const integrationService = ServiceSelector.getNativeDestinationService();
try {
deliveryResponse = await integrationService.deliver(event, destination, requestMetadata);
deliveryResponse = await integrationService.deliver(
event,
destination,
requestMetadata,
version,
);
} catch (error: any) {
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
const metaTO = integrationService.getTags(
destination,
Expand Down
3 changes: 2 additions & 1 deletion src/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@
"ONE_SIGNAL": true,
"TIKTOK_AUDIENCE": true
},
"supportSourceTransformV1": true
"supportSourceTransformV1": true,
"transformerProxyV1": true
}
1 change: 1 addition & 0 deletions src/interfaces/DestinationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface DestinationService {
event: ProcessorTransformationOutput,
destinationType: string,
requestMetadata: NonNullable<unknown>,
version: string,
): Promise<DeliveryResponse>;
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved

processUserDeletion(
Expand Down
6 changes: 3 additions & 3 deletions src/routes/utils/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const SUPPORTED_VERSIONS = ['v0'];
const SUPPORTED_VERSIONS = ['v0', 'v1'];
const API_VERSION = '2';
const INTEGRATION_SERVICE = {
COMPARATOR: 'comparator',
Expand All @@ -7,8 +7,8 @@ const INTEGRATION_SERVICE = {
NATIVE_DEST: 'native_dest',
NATIVE_SOURCE: 'native_source',
};
const CHANNELS= {
sources: 'sources'
const CHANNELS = {
sources: 'sources',
};

const RETL_TIMESTAMP = 'timestamp';
Expand Down
2 changes: 2 additions & 0 deletions src/services/comparator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,13 @@
event: ProcessorTransformationOutput,
destinationType: string,
requestMetadata: NonNullable<unknown>,
version: string,

Check warning on line 371 in src/services/comparator.ts

View check run for this annotation

Codecov / codecov/patch

src/services/comparator.ts#L371

Added line #L371 was not covered by tests
): Promise<DeliveryResponse> {
const primaryResplist = await this.primaryService.deliver(
event,
destinationType,
requestMetadata,
version,
);
logger.error('[LIVE_COMPARE_TEST] not implemented for delivery routine');

Expand Down
3 changes: 2 additions & 1 deletion src/services/destination/nativeIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,10 @@ export class NativeIntegrationDestinationService implements DestinationService {
destinationRequest: ProcessorTransformationOutput,
destinationType: string,
_requestMetadata: NonNullable<unknown>,
version: string,
): Promise<DeliveryResponse> {
try {
const networkHandler = networkHandlerFactory.getNetworkHandler(destinationType);
const networkHandler = networkHandlerFactory.getNetworkHandler(destinationType, version);
const rawProxyResponse = await networkHandler.proxy(destinationRequest, destinationType);
const processedProxyResponse = networkHandler.processAxiosResponse(rawProxyResponse);
return networkHandler.responseHandler(
Expand Down
117 changes: 117 additions & 0 deletions src/v1/destinations/campaign_manager/networkHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* eslint-disable no-param-reassign */
/* eslint-disable no-restricted-syntax */
const { NetworkError } = require('@rudderstack/integrations-lib');
const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network');
const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../../v0/util/index');

const {
processAxiosResponse,
getDynamicErrorType,
} = require('../../../adapters/utils/networkUtils');
const tags = require('../../../v0/util/tags');

function isEventRetryableAndExtractErrMsg(element, proxyOutputObj) {
let isRetryable = false;
let errorMsg = '';

Check warning on line 15 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L13-L15

Added lines #L13 - L15 were not covered by tests
// success event
if (!element.errors) {
return isRetryable;

Check warning on line 18 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L18

Added line #L18 was not covered by tests
}
for (const err of element.errors) {
errorMsg += `${err.message}, `;

Check warning on line 21 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L20-L21

Added lines #L20 - L21 were not covered by tests
aashishmalik marked this conversation as resolved.
Show resolved Hide resolved
if (err.code === 'INTERNAL') {
isRetryable = true;

Check warning on line 23 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L23

Added line #L23 was not covered by tests
}
}
if (errorMsg) {
proxyOutputObj.error = errorMsg;

Check warning on line 27 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L27

Added line #L27 was not covered by tests
}
return isRetryable;

Check warning on line 29 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L29

Added line #L29 was not covered by tests
}

function isEventAbortableAndExtractErrMsg(element, proxyOutputObj) {
let isAbortable = false;
let errorMsg = '';

Check warning on line 34 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L32-L34

Added lines #L32 - L34 were not covered by tests
// success event
if (!element.errors) {
return isAbortable;

Check warning on line 37 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L37

Added line #L37 was not covered by tests
}
for (const err of element.errors) {
errorMsg += `${err.message}, `;

Check warning on line 40 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L39-L40

Added lines #L39 - L40 were not covered by tests
// if code is any of these, event is not retryable
if (
err.code === 'PERMISSION_DENIED' ||
err.code === 'INVALID_ARGUMENT' ||
err.code === 'NOT_FOUND'

Check warning on line 45 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L43-L45

Added lines #L43 - L45 were not covered by tests
) {
isAbortable = true;

Check warning on line 47 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L47

Added line #L47 was not covered by tests
}
}
if (errorMsg) {
proxyOutputObj.error = errorMsg;

Check warning on line 51 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L51

Added line #L51 was not covered by tests
}
return isAbortable;

Check warning on line 53 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L53

Added line #L53 was not covered by tests
}

const responseHandler = (destinationResponse) => {
const message = `[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully`;
const responseWithIndividualEvents = [];
const { response, status, rudderJobMetadata } = destinationResponse;

Check warning on line 59 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L57-L59

Added lines #L57 - L59 were not covered by tests

if (isHttpStatusSuccess(status)) {
// check for Partial Event failures and Successes
const destPartialStatus = response.status;

Check warning on line 63 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L63

Added line #L63 was not covered by tests

for (const [idx, element] of destPartialStatus.entries()) {
const proxyOutputObj = {

Check warning on line 66 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L65-L66

Added lines #L65 - L66 were not covered by tests
statusCode: 200,
metadata: rudderJobMetadata[idx],
error: 'success',
};
// update status of partial event as per retriable or abortable
if (isEventRetryableAndExtractErrMsg(element, proxyOutputObj)) {
proxyOutputObj.statusCode = 500;

Check warning on line 73 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L73

Added line #L73 was not covered by tests
} else if (isEventAbortableAndExtractErrMsg(element, proxyOutputObj)) {
proxyOutputObj.statusCode = 400;

Check warning on line 75 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L75

Added line #L75 was not covered by tests
}
responseWithIndividualEvents.push(proxyOutputObj);

Check warning on line 77 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L77

Added line #L77 was not covered by tests
}

return {

Check warning on line 80 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L80

Added line #L80 was not covered by tests
status,
message,
destinationResponse,
response: responseWithIndividualEvents,
};
}

// in case of failure status, populate response to maintain len(metadata)=len(response)
const errorMessage = response.error?.message || 'unknown error format';
for (const metadata of rudderJobMetadata) {
responseWithIndividualEvents.push({

Check warning on line 91 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L90-L91

Added lines #L90 - L91 were not covered by tests
statusCode: 500,
metadata,
error: errorMessage,
});
}

throw new NetworkError(

Check warning on line 98 in src/v1/destinations/campaign_manager/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/campaign_manager/networkHandler.js#L98

Added line #L98 was not covered by tests
`Campaign Manager: Error proxy v1 during CAMPAIGN_MANAGER response transformation`,
500,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status),
},
destinationResponse,
getAuthErrCategoryFromStCode(status),
responseWithIndividualEvents,
);
};

function networkHandler() {
this.prepareProxy = prepareProxyRequest;
this.proxy = proxyRequest;
this.processAxiosResponse = processAxiosResponse;
this.responseHandler = responseHandler;
}

module.exports = { networkHandler };
Loading