-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: move hubspot to transformer proxy to enable partial batch handling
- Loading branch information
Showing
5 changed files
with
767 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* eslint-disable no-param-reassign */ | ||
/* eslint-disable no-restricted-syntax */ | ||
const { removeUndefinedAndNullValues } = require('@rudderstack/integrations-lib'); | ||
const { TransformerProxyError } = require('../../../v0/util/errorTypes'); | ||
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'); | ||
|
||
const populateErrorMessage = (response) => { | ||
const errorResponse = { | ||
message: response?.message || null, | ||
category: response?.category || null, | ||
correlationId: response?.correlationId || null, | ||
}; | ||
removeUndefinedAndNullValues(errorResponse); | ||
if (Object.keys(errorResponse).length === 0) { | ||
return 'unknown error format'; | ||
} | ||
return JSON.stringify(errorResponse); | ||
}; | ||
|
||
const responseHandler = (responseParams) => { | ||
const { destinationResponse, rudderJobMetadata } = responseParams; | ||
const message = `[HUBSPOT Response V1 Handler] - Request Processed Successfully`; | ||
const responseWithIndividualEvents = []; | ||
const { response, status } = destinationResponse; | ||
|
||
if (isHttpStatusSuccess(status)) { | ||
// populate different response for each event | ||
const results = response?.results; | ||
if (Array.isArray(results)) { | ||
for (const [idx] of results.entries()) { | ||
const proxyOutputObj = { | ||
statusCode: 200, | ||
metadata: rudderJobMetadata[idx], | ||
error: 'success', | ||
}; | ||
responseWithIndividualEvents.push(proxyOutputObj); | ||
} | ||
} | ||
|
||
return { | ||
status, | ||
message, | ||
destinationResponse, | ||
response: responseWithIndividualEvents, | ||
}; | ||
} | ||
|
||
// in case of failure status, populate response to maintain len(metadata)=len(response) | ||
const errorMessage = populateErrorMessage(response); | ||
|
||
// At least one event in the batch is invalid. | ||
if (status === 400 && rudderJobMetadata.length > 1) { | ||
if (rudderJobMetadata.length > 1) { | ||
for (const metadata of rudderJobMetadata) { | ||
metadata.dontBatch = true; | ||
responseWithIndividualEvents.push({ | ||
statusCode: status, | ||
metadata, | ||
error: errorMessage, | ||
}); | ||
} | ||
} | ||
// sending back 500 for retry only when events came in a batch | ||
throw new TransformerProxyError( | ||
`HUBSPOT: Error transformer proxy v1 during HUBSPOT response transformation`, | ||
500, | ||
{ | ||
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(500), | ||
}, | ||
destinationResponse, | ||
'', | ||
responseWithIndividualEvents, | ||
); | ||
} | ||
throw new TransformerProxyError( | ||
`HUBSPOT: Error transformer proxy v1 during HUBSPOT response transformation`, | ||
status, | ||
{ | ||
[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 }; |
261 changes: 261 additions & 0 deletions
261
test/integrations/destinations/hs/dataDelivery/business.ts
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,261 @@ | ||
import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; | ||
|
||
const commonStatTags = { | ||
destType: 'HS', | ||
destinationId: 'default-destinationId', | ||
errorCategory: 'network', | ||
errorType: 'retryable', | ||
feature: 'dataDelivery', | ||
implementation: 'native', | ||
module: 'destination', | ||
workspaceId: 'default-workspaceId', | ||
}; | ||
export const businessData = [ | ||
{ | ||
name: 'hs', | ||
description: 'successfully creating users from a batch', | ||
feature: 'dataDelivery', | ||
module: 'destination', | ||
version: 'v1', | ||
input: { | ||
request: { | ||
body: generateProxyV1Payload( | ||
{ | ||
endpoint: 'https://api.hubapi.com/crm/v3/objects/contacts/batch/update', | ||
JSON: { | ||
inputs: [ | ||
{ | ||
properties: { | ||
firstname: 'testmail1217', | ||
}, | ||
id: '12877907024', | ||
}, | ||
{ | ||
properties: { | ||
firstname: 'test1', | ||
email: '[email protected]', | ||
}, | ||
id: '12877907025', | ||
}, | ||
], | ||
}, | ||
}, | ||
[generateMetadata(1), generateMetadata(2)], | ||
), | ||
}, | ||
}, | ||
output: { | ||
response: { | ||
status: 200, | ||
body: { | ||
output: { | ||
status: 200, | ||
message: '[HUBSPOT Response V1 Handler] - Request Processed Successfully', | ||
response: [ | ||
{ | ||
error: 'success', | ||
metadata: generateMetadata(1), | ||
statusCode: 200, | ||
}, | ||
{ | ||
error: 'success', | ||
metadata: generateMetadata(2), | ||
statusCode: 200, | ||
}, | ||
], | ||
destinationResponse: { | ||
response: { | ||
status: 'COMPLETE', | ||
results: [ | ||
{ | ||
id: '12877907025', | ||
properties: { | ||
createdate: '2024-04-16T09:50:16.034Z', | ||
email: '[email protected]', | ||
firstname: 'test1', | ||
hs_is_unworked: 'true', | ||
hs_object_id: '12877907025', | ||
hs_pipeline: 'contacts-lifecycle-pipeline', | ||
lastmodifieddate: '2024-04-23T11:52:03.723Z', | ||
lifecyclestage: 'lead', | ||
}, | ||
createdAt: '2024-04-16T09:50:16.034Z', | ||
updatedAt: '2024-04-23T11:52:03.723Z', | ||
archived: false, | ||
}, | ||
{ | ||
id: '12877907024', | ||
properties: { | ||
createdate: '2024-04-16T09:50:16.034Z', | ||
firstname: 'testmail1217', | ||
hs_is_unworked: 'true', | ||
hs_object_id: '12877907024', | ||
hs_pipeline: 'contacts-lifecycle-pipeline', | ||
lastmodifieddate: '2024-04-23T11:52:03.723Z', | ||
lifecyclestage: 'lead', | ||
}, | ||
createdAt: '2024-04-16T09:50:16.034Z', | ||
updatedAt: '2024-04-23T11:52:03.723Z', | ||
archived: false, | ||
}, | ||
], | ||
startedAt: '2024-04-24T05:11:51.090Z', | ||
completedAt: '2024-04-24T05:11:51.190Z', | ||
}, | ||
status: 200, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: 'hs', | ||
description: 'failed due to duplicate object in a batch', | ||
feature: 'dataDelivery', | ||
module: 'destination', | ||
version: 'v1', | ||
input: { | ||
request: { | ||
body: generateProxyV1Payload( | ||
{ | ||
endpoint: 'https://api.hubapi.com/crm/v3/objects/contacts/batch/update', | ||
JSON: { | ||
inputs: [ | ||
{ | ||
properties: { | ||
firstname: 'test5', | ||
email: '[email protected]', | ||
}, | ||
id: '12877907025', | ||
}, | ||
{ | ||
properties: { | ||
firstname: 'testmail1217', | ||
email: '[email protected]', | ||
}, | ||
id: '12877907025', | ||
}, | ||
], | ||
}, | ||
}, | ||
[generateMetadata(1), generateMetadata(2)], | ||
), | ||
}, | ||
}, | ||
output: { | ||
response: { | ||
status: 200, | ||
body: { | ||
output: { | ||
message: 'HUBSPOT: Error transformer proxy v1 during HUBSPOT response transformation', | ||
response: [ | ||
{ | ||
error: | ||
'{"status":"error","message":"Duplicate IDs found in batch input: [12877907025]. IDs must be unique","correlationId":"d24ec5cd-8998-4674-a928-59603ae6b0eb","context":{"ids":["12877907025"]},"category":"VALIDATION_ERROR"}', | ||
metadata: { | ||
...generateMetadata(1), | ||
dontBatch: true, | ||
}, | ||
statusCode: 500, | ||
}, | ||
{ | ||
error: | ||
'{"status":"error","message":"Duplicate IDs found in batch input: [12877907025]. IDs must be unique","correlationId":"d24ec5cd-8998-4674-a928-59603ae6b0eb","context":{"ids":["12877907025"]},"category":"VALIDATION_ERROR"}', | ||
metadata: { | ||
...generateMetadata(2), | ||
dontBatch: true, | ||
}, | ||
statusCode: 500, | ||
}, | ||
], | ||
statTags: commonStatTags, | ||
status: 500, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: 'hs', | ||
description: 'failed due to wrong email format in a batch', | ||
feature: 'dataDelivery', | ||
module: 'destination', | ||
version: 'v1', | ||
input: { | ||
request: { | ||
body: generateProxyV1Payload( | ||
{ | ||
endpoint: 'https://api.hubapi.com/crm/v3/objects/contacts/batch/update', | ||
JSON: { | ||
inputs: [ | ||
[ | ||
{ | ||
properties: { | ||
firstname: 'test1', | ||
email: '[email protected]', | ||
}, | ||
}, | ||
{ | ||
properties: { | ||
firstname: 'testmail1217', | ||
email: '[email protected]', | ||
}, | ||
}, | ||
{ | ||
properties: { | ||
firstname: 'test5', | ||
email: '[email protected]', | ||
}, | ||
}, | ||
], | ||
], | ||
}, | ||
}, | ||
[generateMetadata(1), generateMetadata(2), generateMetadata(3)], | ||
), | ||
}, | ||
}, | ||
output: { | ||
response: { | ||
status: 200, | ||
body: { | ||
output: { | ||
message: 'HUBSPOT: Error transformer proxy v1 during HUBSPOT response transformation', | ||
response: [ | ||
{ | ||
error: | ||
'{"status":"error","message":"Invalid input JSON on line 3, column 9: Cannot deserialize value of type `com.hubspot.inbounddb.publicobject.core.v2.SimplePublicObjectBatchInput$Json` from Array value (token `JsonToken.START_ARRAY`)","correlationId":"99df04b9-da11-4504-bd97-2c15f58d0943"}', | ||
metadata: { | ||
...generateMetadata(1), | ||
dontBatch: true, | ||
}, | ||
statusCode: 500, | ||
}, | ||
{ | ||
error: | ||
'{"status":"error","message":"Invalid input JSON on line 3, column 9: Cannot deserialize value of type `com.hubspot.inbounddb.publicobject.core.v2.SimplePublicObjectBatchInput$Json` from Array value (token `JsonToken.START_ARRAY`)","correlationId":"99df04b9-da11-4504-bd97-2c15f58d0943"}', | ||
metadata: { | ||
...generateMetadata(2), | ||
dontBatch: true, | ||
}, | ||
statusCode: 500, | ||
}, | ||
{ | ||
error: | ||
'{"status":"error","message":"Invalid input JSON on line 3, column 9: Cannot deserialize value of type `com.hubspot.inbounddb.publicobject.core.v2.SimplePublicObjectBatchInput$Json` from Array value (token `JsonToken.START_ARRAY`)","correlationId":"99df04b9-da11-4504-bd97-2c15f58d0943"}', | ||
metadata: { | ||
...generateMetadata(3), | ||
dontBatch: true, | ||
}, | ||
statusCode: 500, | ||
}, | ||
], | ||
statTags: commonStatTags, | ||
status: 500, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
]; |
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,4 @@ | ||
import { businessData } from './business'; | ||
import { otherData } from './other'; | ||
|
||
export const data = [...businessData, ...otherData]; |
Oops, something went wrong.