Skip to content

Commit

Permalink
fix: code redesigning
Browse files Browse the repository at this point in the history
  • Loading branch information
shrouti1507 committed Nov 20, 2024
1 parent 8742244 commit 25a5ced
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 216 deletions.
7 changes: 7 additions & 0 deletions src/v0/destinations/iterable/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const ConfigCategory = {
name: 'IterableIdentifyConfig',
action: 'identify',
endpoint: `users/update`,
bulkEndpoint: 'users/bulkUpdate',
},
PAGE: {
name: 'IterablePageConfig',
Expand All @@ -35,6 +36,7 @@ const ConfigCategory = {
name: 'IterableTrackConfig',
action: 'track',
endpoint: `events/track`,
bulkEndpoint: 'events/trackBulk',
},
TRACK_PURCHASE: {
name: 'IterableTrackPurchaseConfig',
Expand Down Expand Up @@ -76,6 +78,10 @@ const constructEndpoint = (dataCenter, category) => {
return `${baseUrl}${category.endpoint}`;
};

const BULK_ENDPOINTS = Object.values(ConfigCategory)
.filter((config) => config.bulkEndpoint)
.map((config) => `/api/${config.bulkEndpoint}`);

const IDENTIFY_MAX_BATCH_SIZE = 1000;
const IDENTIFY_MAX_BODY_SIZE_IN_BYTES = 4000000;

Expand Down Expand Up @@ -105,4 +111,5 @@ module.exports = {
IDENTIFY_MAX_BATCH_SIZE,
IDENTIFY_MAX_BODY_SIZE_IN_BYTES,
API_RESPONSE_PATHS,
BULK_ENDPOINTS,
};
18 changes: 12 additions & 6 deletions src/v0/destinations/iterable/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ const batchUpdateUserEvents = (updateUserEvents, registerDeviceOrBrowserTokenEve

/**
* Processes chunks of catalog events, extracts the necessary data, and prepares batched requests for further processing
* ref : https://api.iterable.com/api/docs#catalogs_bulkUpdateCatalogItems
* @param {*} catalogEventsChunks
* @returns
*/
Expand Down Expand Up @@ -601,12 +602,12 @@ const batchTrackEvents = (trackEvents) => {
*/
const prepareBatchRequests = (filteredEvents) => {
const {
trackEvents,
catalogEvents,
errorRespList,
updateUserEvents,
eventResponseList,
registerDeviceOrBrowserTokenEvents,
trackEvents, // track
catalogEvents, // identify
errorRespList, // track
updateUserEvents, // identify
eventResponseList, // track
registerDeviceOrBrowserTokenEvents, // identify
} = filteredEvents;

const updateUserBatchedResponseList =
Expand Down Expand Up @@ -753,6 +754,11 @@ const filterEventsAndPrepareBatchRequests = (transformedEvents) => {
* 2) https://api.iterable.com/api/docs#events_track
* 3) https://api.iterable.com/api/docs#users_bulkUpdateUser
* 4) https://api.iterable.com/api/docs#events_trackBulk
* 5) https://api.iterable.com/api/docs#catalogs_bulkUpdateCatalogItems
* 6) https://api.iterable.com/api/docs#users_registerDeviceToken
* 7) https://api.iterable.com/api/docs#users_registerBrowserToken
* 8) https://api.iterable.com/api/docs#commerce_trackPurchase
* 9) https://api.iterable.com/api/docs#commerce_updateCart
*
* @param {Object} event - The event object containing various event properties.
* @param {Object} destinationResponse - The response object from the destination.
Expand Down
23 changes: 23 additions & 0 deletions src/v1/destinations/iterable/commonStrategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { ResponseStrategy } = require('./responseStrategy');

class CommonStrategy extends ResponseStrategy {
handleSuccess(responseParams) {
const { destinationResponse, rudderJobMetadata } = responseParams;
const { status } = destinationResponse;

Check warning on line 6 in src/v1/destinations/iterable/commonStrategy.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/iterable/commonStrategy.js#L4-L6

Added lines #L4 - L6 were not covered by tests

const responseWithIndividualEvents = rudderJobMetadata.map((metadata) => ({

Check warning on line 8 in src/v1/destinations/iterable/commonStrategy.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/iterable/commonStrategy.js#L8

Added line #L8 was not covered by tests
statusCode: status,
metadata,
error: 'success',
}));

return {

Check warning on line 14 in src/v1/destinations/iterable/commonStrategy.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/iterable/commonStrategy.js#L14

Added line #L14 was not covered by tests
status,
message: '[ITERABLE Response Handler] - Request Processed Successfully',
destinationResponse,
response: responseWithIndividualEvents,
};
}
}

module.exports = { CommonStrategy };
212 changes: 14 additions & 198 deletions src/v1/destinations/iterable/networkHandler.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,23 @@
/* eslint-disable @typescript-eslint/naming-convention */
const { TransformerProxyError } = require('../../../v0/util/errorTypes');
const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network');
const { isHttpStatusSuccess } = require('../../../v0/util/index');

const {
processAxiosResponse,
getDynamicErrorType,
} = require('../../../adapters/utils/networkUtils');
const tags = require('../../../v0/util/tags');
const { processAxiosResponse } = require('../../../adapters/utils/networkUtils');
const { BULK_ENDPOINTS } = require('../../../v0/destinations/iterable/config');
const {
checkIfEventIsAbortableAndExtractErrorMessage,
} = require('../../../v0/destinations/iterable/util');
const { CommonStrategy } = require('./commonStrategy');
const { TrackIdentifyStrategy } = require('./trackIdentifyStrategy');

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

if (!isHttpStatusSuccess(status)) {
const errorMessage = JSON.stringify(response.params) || 'unknown error format';
responseWithIndividualEvents = rudderJobMetadata.map((metadata) => ({
statusCode: status,
metadata,
error: errorMessage,
}));
throw new TransformerProxyError(
`ITERABLE: Error transformer proxy during ITERABLE response transformation. ${errorMessage}`,
status,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status),
},
destinationResponse,
'',
responseWithIndividualEvents,
);
}

if (isHttpStatusSuccess(status)) {
// check for Partial Event failures and Successes
// eslint-disable-next-line @typescript-eslint/naming-convention
const { events, users } = destinationRequest.body.JSON;
const finalData = events || users;
finalData.forEach((event, idx) => {
const proxyOutput = {
statusCode: 200,
metadata: rudderJobMetadata[idx],
error: 'success',
};
// update status of partial event if abortable
const { isAbortable, errorMsg } = checkIfEventIsAbortableAndExtractErrorMessage(
event,
destinationResponse,
);
if (isAbortable) {
proxyOutput.statusCode = 400;
proxyOutput.error = errorMsg;
}
responseWithIndividualEvents.push(proxyOutput);
});
return {
status,
message,
destinationResponse,
response: responseWithIndividualEvents,
};
const getResponseStrategy = (endpoint) => {
if (BULK_ENDPOINTS.some((path) => endpoint.includes(path))) {
return new TrackIdentifyStrategy(checkIfEventIsAbortableAndExtractErrorMessage);
}
return new CommonStrategy();

Check warning on line 14 in src/v1/destinations/iterable/networkHandler.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/iterable/networkHandler.js#L14

Added line #L14 was not covered by tests
};

throw new TransformerProxyError(
`ITERABLE: Error transformer proxy during ITERABLE response transformation`,
status,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status),
},
destinationResponse,
'',
responseWithIndividualEvents,
);
const responseHandler = (responseParams) => {
const { destinationRequest } = responseParams;
const strategy = getResponseStrategy(destinationRequest.endpoint);
return strategy.handleResponse(responseParams);
};

function networkHandler() {
Expand All @@ -86,129 +27,4 @@ function networkHandler() {
this.responseHandler = responseHandler;
}

module.exports = { networkHandler, checkIfEventIsAbortableAndExtractErrorMessage };

/**
*
class ResponseStrategy {
handleResponse(responseParams) {
const { destinationResponse, rudderJobMetadata } = responseParams;
const { status } = destinationResponse;
if (!isHttpStatusSuccess(status)) {
return this.handleError(responseParams);
}
return this.handleSuccess(responseParams);
}
handleError(responseParams) {
const { destinationResponse, rudderJobMetadata } = responseParams;
const { response, status } = destinationResponse;
const errorMessage = JSON.stringify(response.params) || 'unknown error format';
const responseWithIndividualEvents = rudderJobMetadata.map((metadata) => ({
statusCode: status,
metadata,
error: errorMessage,
}));
throw new TransformerProxyError(
`ITERABLE: Error transformer proxy during ITERABLE response transformation. ${errorMessage}`,
status,
{ [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status) },
destinationResponse,
'',
responseWithIndividualEvents,
);
}
handleSuccess(responseParams) {
throw new Error('handleSuccess must be implemented');
}
}
class TrackIdentifyStrategy extends ResponseStrategy {
constructor(filterFn) {
super();
this.filterFn = filterFn;
}
handleSuccess(responseParams) {
const { destinationResponse, rudderJobMetadata, destinationRequest } = responseParams;
const { status } = destinationResponse;
const responseWithIndividualEvents = [];
const { events, users } = destinationRequest.body.JSON;
const finalData = events || users;
finalData.forEach((event, idx) => {
const proxyOutput = {
statusCode: 200,
metadata: rudderJobMetadata[idx],
error: 'success',
};
const { isAbortable, errorMsg } = this.filterFn(event, destinationResponse);
if (isAbortable) {
proxyOutput.statusCode = 400;
proxyOutput.error = errorMsg;
}
responseWithIndividualEvents.push(proxyOutput);
});
return {
status,
message: '[ITERABLE Response Handler] - Request Processed Successfully',
destinationResponse,
response: responseWithIndividualEvents,
};
}
}
class SimpleStrategy extends ResponseStrategy {
handleSuccess(responseParams) {
const { destinationResponse, rudderJobMetadata } = responseParams;
const { status } = destinationResponse;
const responseWithIndividualEvents = rudderJobMetadata.map(metadata => ({
statusCode: status,
metadata,
error: 'success'
}));
return {
status,
message: '[ITERABLE Response Handler] - Request Processed Successfully',
destinationResponse,
response: responseWithIndividualEvents,
};
}
}
const getResponseStrategy = (endpoint) => {
switch (endpoint) {
case '/api/events/track':
return new TrackIdentifyStrategy(checkIfEventIsAbortableAndExtractErrorMessage);
case '/api/users/update':
return new TrackIdentifyStrategy(checkIfEventIsAbortableAndExtractErrorMessage);
default:
return new SimpleStrategy();
}
};
const responseHandler = (responseParams) => {
const { destinationRequest } = responseParams;
const strategy = getResponseStrategy(destinationRequest.body.endpoint);
return strategy.handleResponse(responseParams);
};
// ... rest of the code remains same ...
*/
module.exports = { networkHandler };
44 changes: 44 additions & 0 deletions src/v1/destinations/iterable/responseStrategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const { isHttpStatusSuccess } = require('../../../v0/util/index');
const { TransformerProxyError } = require('../../../v0/util/errorTypes');
const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils');
const tags = require('../../../v0/util/tags');

class ResponseStrategy {
handleResponse(responseParams) {
const { destinationResponse } = responseParams;
const { status } = destinationResponse;

if (!isHttpStatusSuccess(status)) {
return this.handleError(responseParams);
}

return this.handleSuccess(responseParams);
}

handleError(responseParams) {
const { destinationResponse, rudderJobMetadata } = responseParams;
const { response, status } = destinationResponse;
const errorMessage = JSON.stringify(response.params) || 'unknown error format';

const responseWithIndividualEvents = rudderJobMetadata.map((metadata) => ({
statusCode: status,
metadata,
error: errorMessage,
}));

throw new TransformerProxyError(
`ITERABLE: Error transformer proxy during ITERABLE response transformation. ${errorMessage}`,
status,
{ [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status) },
destinationResponse,
'',
responseWithIndividualEvents,
);
}

handleSuccess(responseParams) {
throw new TransformerProxyError(`success response handling is not added:${responseParams}`);

Check warning on line 40 in src/v1/destinations/iterable/responseStrategy.js

View check run for this annotation

Codecov / codecov/patch

src/v1/destinations/iterable/responseStrategy.js#L39-L40

Added lines #L39 - L40 were not covered by tests
}
}

module.exports = { ResponseStrategy };
Loading

0 comments on commit 25a5ced

Please sign in to comment.