Skip to content

Commit

Permalink
feat: update google_cloud_function implementation as per custom desti…
Browse files Browse the repository at this point in the history
…nation flow
  • Loading branch information
ujjwal-ab committed Sep 25, 2023
1 parent c200ef5 commit 6d39a94
Show file tree
Hide file tree
Showing 5 changed files with 850 additions and 60 deletions.
7 changes: 0 additions & 7 deletions src/v0/destinations/google_cloud_function/config.js

This file was deleted.

16 changes: 3 additions & 13 deletions src/v0/destinations/google_cloud_function/transform.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
const _ = require('lodash');
const {
defaultRequestConfig,
defaultPostRequestConfig,
getSuccessRespEvents,
checkInvalidRtTfEvents,
handleRtTfSingleEventError,
} = require('../../util');

const { generateBatchedPayload, validateDestinationConfig, addHeader } = require('./util');
const { generateBatchedPayload, validateDestinationConfig } = require('./util');

// Main process Function to handle transformation
function process(event) {
const { message, destination } = event;
const { googleCloudFunctionUrl } = destination.Config;

// Config Validation
validateDestinationConfig(destination);

const response = defaultRequestConfig();
// adding header
addHeader(response, destination.Config);
response.method = defaultPostRequestConfig.requestMethod;
response.body.JSON = message;
response.endpoint = googleCloudFunctionUrl;

const response = message;
return response;
}

Expand All @@ -37,7 +27,7 @@ function batchEvents(successRespList, maxBatchSize = 10) {
const batchEventResponse = generateBatchedPayload(chunk);
batchedResponseList.push(
getSuccessRespEvents(
batchEventResponse.batchedRequest,
batchEventResponse.message,
batchEventResponse.metadata,
batchEventResponse.destination,
true,
Expand Down
50 changes: 10 additions & 40 deletions src/v0/destinations/google_cloud_function/util.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,47 @@
const { defaultBatchRequestConfig } = require('../../util');
const { JSON_MIME_TYPE } = require('../../util/constant');
const { ConfigurationError } = require('../../util/errorTypes');

const { TRIGGERTYPE } = require('./config');

/**
* validate destination config
* @param {*} param0
*/
const validateDestinationConfig = ({ Config }) => {
// throw error if google Cloud Function is not provided
// throw error if google Cloud Function URL is not provided
if (!Config.googleCloudFunctionUrl) {
throw new ConfigurationError('[GCF]:: Url not found. Aborting');
}
if (
Config.triggerType === 'https' && // for triggerType https gcloud Authorization is mandatory
!Config.gcloudAuthorization
) {
throw new ConfigurationError('[GCF]:: Access Token not found. Aborting');
if (Config.requireAuthentication && !Config.credentials) {
throw new ConfigurationError(
'[GCF]:: Service Account credentials are required if your function required authentication. Aborting',
);
}
};

/**
* add headers in the payload that is provided in destination config
* @param {*} response
* @param {*} Config
*/
function addHeader(response, Config) {
const { triggerType, apiKeyId, gcloudAuthorization } = Config;

response.headers = { 'content-type': JSON_MIME_TYPE };
if (apiKeyId) {
const basicAuth = Buffer.from(`apiKey:${apiKeyId}`).toString('base64');
response.headers.ApiKey = `Basic ${basicAuth}`;
}
if (TRIGGERTYPE.HTTPS === triggerType.toLowerCase()) {
response.headers.Authorization = `bearer ${gcloudAuthorization}`;
}
}

/**
* Create GoogleCloudFunction Batch payload based on the passed events
* @param {*} events
* @returns
*/

function generateBatchedPayload(events) {
const batchResponseList = [];
const metadata = [];
// extracting destination
// from the first event in a batch
const { destination } = events[0];
const { googleCloudFunctionUrl } = destination.Config;
let batchEventResponse = defaultBatchRequestConfig();
let batchEventResponse = events.map((event) => event.message);
// Batch event into dest batch structure
events.forEach((ev) => {
batchResponseList.push(ev.message.body.JSON);
// batchResponseList.push(ev.message.body.JSON);
metadata.push(ev.metadata);
});
batchEventResponse.batchedRequest.body.JSON_ARRAY = {
batch: JSON.stringify(batchResponseList),
};
batchEventResponse.batchedRequest.endpoint = googleCloudFunctionUrl;
addHeader(batchEventResponse.batchedRequest, destination.Config);
batchEventResponse = {
...batchEventResponse,
metadata,
message: batchEventResponse,
destination,
metadata,
};
return batchEventResponse;
}

module.exports = {
validateDestinationConfig,
addHeader,
generateBatchedPayload,
};
185 changes: 185 additions & 0 deletions test/integrations/destinations/google_cloud_function/processor/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
export const data = [
{
name: 'google_cloud_function',
description: 'Successful request',
feature: 'processor',
module: 'destination',
version: 'v0',
input: {
request: {
body: [
{
destination: {
Config: {
functionEnvironment: 'gen1',
requireAuthentication: false,
enableBatchInput: false,
googleCloudFunctionUrl:
'https://us-central1-big-query-integration-poc.cloudfunctions.net/rudderv1',
},
},
message: {
channel: 'web',
context: {
app: {
build: '1.0.0',
name: 'RudderLabs JavaScript SDK',
namespace: 'com.rudderlabs.javascript',
version: '1.0.0',
},
library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' },
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
locale: 'en-US',
ip: '0.0.0.0',
os: { name: '', version: '' },
screen: { density: 2 },
},
messageId: '84e26acc-56a5-4835-8233-591137fca468',
session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22',
originalTimestamp: '2019-10-14T09:03:17.562Z',
anonymousId: 'anon_id',
type: 'identify',
traits: {
email: '[email protected]',
name: 'Cosmo Krammer',
linkedinUrl: 'https://linkedin.com/cosmo-krammer',
location: 'New York',
emailOptOut: true,
masterAvatarTypeCode: 10,
},
integrations: { All: true },
sentAt: '2019-10-14T09:03:22.563Z',
},
},
],
method: 'POST',
},
pathSuffix: '',
},
output: {
response: {
status: 200,
body: [
{
output: {
channel: 'web',
context: {
app: {
build: '1.0.0',
name: 'RudderLabs JavaScript SDK',
namespace: 'com.rudderlabs.javascript',
version: '1.0.0',
},
library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' },
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
locale: 'en-US',
ip: '0.0.0.0',
os: { name: '', version: '' },
screen: { density: 2 },
},
messageId: '84e26acc-56a5-4835-8233-591137fca468',
session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22',
originalTimestamp: '2019-10-14T09:03:17.562Z',
anonymousId: 'anon_id',
type: 'identify',
traits: {
email: '[email protected]',
name: 'Cosmo Krammer',
linkedinUrl: 'https://linkedin.com/cosmo-krammer',
location: 'New York',
emailOptOut: true,
masterAvatarTypeCode: 10,
},
integrations: { All: true },
sentAt: '2019-10-14T09:03:22.563Z',
userId: '',
},
statusCode: 200,
},
],
},
},
},
{
name: 'google_cloud_function',
description:
'[GCF]:: Service Account credentials are required if your function required authentication. Aborting',
feature: 'processor',
module: 'destination',
version: 'v0',
input: {
request: {
body: [
{
destination: {
Config: {
functionEnvironment: 'gen1',
requireAuthentication: true,
enableBatchInput: false,
googleCloudFunctionUrl:
'https://us-central1-big-query-integration-poc.cloudfunctions.net/rudderv1',
},
},
message: {
channel: 'web',
context: {
app: {
build: '1.0.0',
name: 'RudderLabs JavaScript SDK',
namespace: 'com.rudderlabs.javascript',
version: '1.0.0',
},
library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' },
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
locale: 'en-US',
ip: '0.0.0.0',
os: { name: '', version: '' },
screen: { density: 2 },
},
messageId: '84e26acc-56a5-4835-8233-591137fca468',
session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22',
originalTimestamp: '2019-10-14T09:03:17.562Z',
anonymousId: 'anon_id',
type: 'identify',
traits: {
email: '[email protected]',
name: 'Cosmo Krammer',
linkedinUrl: 'https://linkedin.com/cosmo-krammer',
location: 'New York',
emailOptOut: true,
masterAvatarTypeCode: 10,
},
integrations: { All: true },
sentAt: '2019-10-14T09:03:22.563Z',
},
},
],
method: 'POST',
},
pathSuffix: '',
},
output: {
response: {
status: 200,
body: [
{
error:
'[GCF]:: Service Account credentials are required if your function required authentication. Aborting',
statTags: {
destType: 'GOOGLE_CLOUD_FUNCTION',
errorCategory: 'dataValidation',
errorType: 'configuration',
feature: 'processor',
implementation: 'native',
module: 'destination',
},
statusCode: 400,
},
],
},
},
},
];
Loading

0 comments on commit 6d39a94

Please sign in to comment.