Skip to content

Commit

Permalink
Jun15 main (segmentio#1344)
Browse files Browse the repository at this point in the history
* reset

Signed-off-by: kwlandry-acoustic <kip.landry@acoustic.com>

* oauth2

* oauth2

* OAuth2

* Fields tidyup

* RefreshAccessToken

* RefreshAccessToken

* removing redundant function getAccessToken

* removing unused code

* Remove chkTable, refactor doPost tryCatch

Signed-off-by: kwlandry-acoustic <kip.landry@acoustic.com>

* Tidy up exception processing,

Signed-off-by: kwlandry-acoustic <kip.landry@acoustic.com>

* Update Tests

Signed-off-by: kwlandry-acoustic <kip.landry@acoustic.com>

---------

Signed-off-by: kwlandry-acoustic <kip.landry@acoustic.com>
Co-authored-by: joe-ayoub-segment <45374896+joe-ayoub-segment@users.noreply.github.com>
  • Loading branch information
KWLandry-acoustic and joe-ayoub-segment authored Jun 20, 2023
1 parent 83eb26e commit b6e8b05
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 259 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// import get from 'lodash/get'
// import { Settings } from '../../generated-types'
import nock from 'nock'
import { preChecksAndMaint, createSegmentEventsTable, checkRTExist } from '../tablemaintutilities'
import { getAuthCreds, getEventTableListId, getAccessToken, doPOST } from '../tablemaintutilities'
import { getAuthCreds, getAccessToken, doPOST } from '../tablemaintutilities'

//import { IntegrationError, OAuth2ClientCredentials, RefreshAccessTokenResult, RetryableError } from '@segment/actions-core'
//import { RequestClient } from '@segment/actions-core'
Expand All @@ -21,77 +20,8 @@ jest.mock('../../generated-types')
const accessPoint = nock('https://api-campaign-us-2.goacoustic.com').post('/XMLAPI').reply(200)
accessPoint.isDone

describe('preChecksAndMaint', () => {
it('should be present', () => {
expect(preChecksAndMaint).toBeDefined()
})

it('preChecksAndMaint should return expected output', async () => {
// const retValue = await preChecksAndMaint(request,settings);
expect(preChecksAndMaint).toMatchSnapshot()
})
})

describe('createSegmentEventsTable', () => {
it('should expose a function', () => {
expect(createSegmentEventsTable).toBeDefined()
})

it('createSegmentEventsTable should return expected output', async () => {
// const retValue = await createSegmentEventsTable(request,settings,auth);
expect(createSegmentEventsTable).toMatchSnapshot()
})
})

describe('checkRTExist', () => {
afterAll(nock.restore)
afterEach(nock.cleanAll)

it('should expose a function', () => {
expect(checkRTExist).toBeDefined()
})

it('checkRTExist should return expected output', async () => {
const settings = {
a_pod: '2',
a_region: 'US'
}

const accessToken = ''

// nock.recorder.rec()
nock.back.setMode('record')

const checkResult = nock(`https://api-campaign-${settings.a_region}-${settings.a_pod}.goacoustic.com`, {
reqheaders: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'text/xml',
'user-agent': 'Segment (checkforRT)',
Connection: 'keep-alive',
'Accept-Encoding': 'gzip, deflate, br',
Accept: '*/*'
}
})
.persist()
.post(
'/XMLAPI',
`<Envelope>
<Body>
<GetLists>
<VISIBILITY>1 </VISIBILITY>
<LIST_TYPE> 15 </LIST_TYPE>
<INCLUDE_ALL_LISTS> True </INCLUDE_ALL_LISTS>
</GetLists>
</Body>
</Envelope>`
) //, body => body.username && body.password
.reply(200, {})

checkResult.isDone

expect(checkRTExist).toMatchSnapshot()
})
})
// nock.recorder.rec()
nock.back.setMode('record')

describe('getAuthCreds', () => {
it('should expose a function', () => {
Expand All @@ -103,16 +33,7 @@ describe('getAuthCreds', () => {
expect(false) //.toBeTruthy();
})
})
describe('getEventTableListId', () => {
it('should expose a function', () => {
expect(getEventTableListId).toBeDefined()
})

it('getEventTableListId should return expected output', () => {
// const retValue = getEventTableListId();
expect(false) //.toBeTruthy();
})
})
describe('getAccessToken', () => {
it('should expose a function', () => {
expect(getAccessToken).toBeDefined()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,6 @@ export function addUpdateEvents(payload: Payload, email: string, limit: number)
...propertiesTraitsKV,
...parseSections(payload.context as { [key: string]: string }, 0)
}

if (Object.keys(propertiesTraitsKV).length > limit) {
throw new IntegrationError(
'Properties Exceed Max. Use Mapping to limit the number of Attributes (Properties, Traits) present and thereby reduce the Campaign Relational Table Rows consumed.',
'EXCEEDS_MAX_PROPERTIES_MAX',
400
)
}
} catch (e) {
throw new IntegrationError(
'Unexpected Exception processing payload \n ${e}',
Expand All @@ -94,6 +86,17 @@ export function addUpdateEvents(payload: Payload, email: string, limit: number)
)
}

//Check Size - Number of Attributes
const l = Object.keys(propertiesTraitsKV).length
if (l > limit) {
throw new IntegrationError(
`There are ${l} Attributes in this Event. This exceeds the max of ${limit}. Use Mapping to limit the number of Attributes and thereby reduce the Campaign Relational Table Rows consumed.`,
'EXCEEDS_MAX_PROPERTIES_MAX',
400
)
}

//Audience
// Identify events generated by an audience have the audience key set to true or false based on whether the user is entering or exiting the audience:
// {
// "type": "identify",
Expand All @@ -115,7 +118,7 @@ export function addUpdateEvents(payload: Payload, email: string, limit: number)

let ak = ''
let av = ''
//Audience

const getValue = (o: object, part: string) => Object.entries(o).find(([k, _v]) => k.includes(part))?.[1]

if (getValue(propertiesTraitsKV, 'computation_class')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { RequestClient } from '@segment/actions-core'
import { Settings } from '../generated-types'
import { AuthTokens } from '@segment/actions-core/src/destination-kit/parse-settings'

export let eventTableListId = ''
// export let eventTableListId = ''
export interface accessResp {
access_token: string
token_type: string
Expand Down Expand Up @@ -48,10 +48,6 @@ export function getAuthCreds() {
return authCreds
}

export function getEventTableListId() {
return eventTableListId
}

export async function getAccessToken(
request: RequestClient,
settings: Settings
Expand All @@ -65,7 +61,6 @@ export async function getAccessToken(
authCreds.refreshTokenUrl = `https://api-campaign-${settings.region}-${settings.pod}.goacoustic.com/oauth/token`

const requestAToken = await request(authCreds.refreshTokenUrl, {
//return await request(authCreds.refreshTokenUrl, {
method: 'POST',
body: new URLSearchParams({
refresh_token: authCreds.refreshToken,
Expand Down Expand Up @@ -105,6 +100,8 @@ export async function doPOST(
}

let resultTxt = ''
let res = ''

try {
const postResults = await request(`https://api-campaign-${settings.region}-${settings.pod}.goacoustic.com/XMLAPI`, {
method: 'POST',
Expand All @@ -118,150 +115,23 @@ export async function doPOST(
},
body: `${body}`
})
const res = await postResults.data

//check for success, hard fails throw error, soft fails throw retryable error
resultTxt = res as string
if (resultTxt.indexOf('<SUCCESS>FALSE</SUCCESS>') > -1 || resultTxt.indexOf('<SUCCESS>false</SUCCESS>') > -1) {
const rx = /<FaultString>(.*)<\/FaultString>/gm
const r = rx.exec(resultTxt) as RegExpExecArray
if (r.indexOf('max number of concurrent') > -1)
throw new RetryableError(
'Currently exceeding Max number of concurrent authenticated requests via API, retrying',
429
)
resultTxt = ''
}
res = (await postResults.data) as string
} catch (e) {
throw new IntegrationError(`Unexpected Request Exception \n${e}`, 'UNEXPECTED_REQUEST_EXCEPTION', 400)
}
return resultTxt
}

export async function preChecksAndMaint(request: RequestClient, settings: Settings, auth: AuthTokens) {
//check for Segment Events table, if not exist create it
eventTableListId = await checkRTExist(request, settings, auth)

if (eventTableListId === '') {
const crt = await createSegmentEventsTable(request, settings, auth)
if (!crt) {
throw new IntegrationError(
'Error attempting to create the Acoustic Segment Events Table',
'CANNOT_CREATE_EVENTS_TABLE',
400
)
}
}
return eventTableListId
}

export async function checkRTExist(request: RequestClient, settings: Settings, auth: AuthTokens) {
if (settings.tableListId != '') {
const checkDefinedTableId = `
<Envelope> <Body>
<GetListMetaData> <LIST_ID>${settings.tableListId}</LIST_ID>
</GetListMetaData> </Body>
</Envelope>`

const respText = (await doPOST(request, settings, auth, checkDefinedTableId, 'CheckDefinedTable')) ?? ''

const rx = /<SUCCESS>TRUE<\/SUCCESS>(?:\s)*<ID>(.*)<\/ID/gm
if (respText != null) {
const r = rx.exec(respText)
if (r) eventTableListId = r[1]
else
throw new IntegrationError(
'Defined Events Table List Id is invalid, please refer to documentation to configure the Segment Events Table in Acoustic',
'INVALID_LIST_ID',
400
)
}
} else {
const getTableList = `<Envelope>
<Body>
<GetLists>
<VISIBILITY>1 </VISIBILITY>
<LIST_TYPE> 15 </LIST_TYPE>
<INCLUDE_ALL_LISTS> True </INCLUDE_ALL_LISTS>
</GetLists>
</Body>
</Envelope>`

const respText = (await doPOST(request, settings, auth, getTableList, 'GetTableList')) ?? ''

const lists = respText

if (lists.indexOf('Segment Events Table') > 0) {
const simplify = lists.substring(
lists.indexOf('Segment Events Table') - 40,
lists.indexOf('Segment Events Table') + 40
)
const rx = /<ID>(.*)<\/ID>/gm
const setListId = rx.exec(simplify) ?? '999999999'

eventTableListId = setListId[1]
} else {
eventTableListId = '999999999' //Make it obvious - should not be 999999999

throw new IntegrationError(
`Cannot determine the Segment Events Table in the defined Acoustic environment. Please check the documentation and confirm the configuration`,
'CANNOT_DETERMINE_EVENTS_TABLE',
400
//check for success, hard fails throw error, soft fails throw retryable error
resultTxt = res
if (resultTxt.indexOf('<SUCCESS>FALSE</SUCCESS>') > -1 || resultTxt.indexOf('<SUCCESS>false</SUCCESS>') > -1) {
const rx = /<FaultString>(.*)<\/FaultString>/gm
const r = rx.exec(resultTxt) as RegExpExecArray
if (r[1].indexOf('max number of concurrent') > -1)
throw new RetryableError(
'Currently exceeding Max number of concurrent authenticated requests via API, retrying',
429
)
}
resultTxt = ''
}
return eventTableListId
}

export async function createSegmentEventsTable(request: RequestClient, settings: Settings, auth: AuthTokens) {
const createSET = `<Envelope>
<Body>
<CreateTable>
<TABLE_NAME>${settings.tableName}</TABLE_NAME>
<COLUMNS>
<COLUMN>
<NAME>EmailId</NAME>
<TYPE>EMAIL</TYPE>
<IS_REQUIRED>true</IS_REQUIRED>
<KEY_COLUMN>TRUE</KEY_COLUMN>
</COLUMN>
<COLUMN>
<NAME>EventSource</NAME>
<TYPE>TEXT</TYPE>
<IS_REQUIRED>TRUE</IS_REQUIRED>
<KEY_COLUMN>FALSE</KEY_COLUMN>
</COLUMN>
<COLUMN>
<NAME>EventName</NAME>
<TYPE>TEXT</TYPE>
<IS_REQUIRED>TRUE</IS_REQUIRED>
<KEY_COLUMN>TRUE</KEY_COLUMN>
</COLUMN>
<COLUMN>
<NAME>EventValue</NAME>
<TYPE>TEXT</TYPE>
<IS_REQUIRED>TRUE</IS_REQUIRED>
<KEY_COLUMN>FALSE</KEY_COLUMN>
</COLUMN>
<COLUMN>
<NAME>EventTimestamp</NAME>
<TYPE>DATE_TIME</TYPE>
<IS_REQUIRED>TRUE</IS_REQUIRED>
<KEY_COLUMN>FALSE</KEY_COLUMN>
</COLUMN>
</COLUMNS>
</CreateTable>
</Body>
</Envelope>`

const cset = (await doPOST(request, settings, auth, createSET, 'CreateSegmentEventsTable')) ?? ''

const rx = /<SUCCESS>TRUE<\/SUCCESS>(?:\s)*<TABLE_ID>(.*)<\/TABLE_ID/gm
let tid = ''
if (cset != null) {
const r = rx.exec(cset)
if (r) tid = r[1]
}
eventTableListId = tid
return eventTableListId
return resultTxt
}
Loading

0 comments on commit b6e8b05

Please sign in to comment.