Skip to content

Commit

Permalink
Add scheduler client
Browse files Browse the repository at this point in the history
  • Loading branch information
razor-x committed Jun 9, 2024
1 parent d834bb7 commit e4c4cac
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 0 deletions.
60 changes: 60 additions & 0 deletions lib/clients/scheduler.doc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* AWS SchedulerClient client.
* @class SchedulerClient
* @see {@link https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-eventbridge/index.html|@aws-sdk/client-scheduler}
* @param {Object} parameters
* @param {string} [parameters.name=scheduler] Client name.
* @param {string} [parameters.reqId=<uuid>] Request id.
* @param {Object} [parameters.log=<logger>] Pino compatible logger.
* @param {Constructor} [parameters.AwsSdkSchedulerClient=SchedulerClient]
* Constructor for a SchedulerClient from the AWS SDK.
* @param {Object} [parameters.params={}]
* Additional params to pass to the AwsSdkSchedulerClient constructor.
*/

/**
* Get a schedule.
* @async
* @function getSchedule
* @memberof SchedulerClient
* @instance
* @param {Object[]} [name] Name of the schedule to get.
* @param {Object} [params=[]] Additional params to pass to the GetScheduleCommand.
* @return {Promise<Object>} Response normalized to camel case.
*/

/**
* Create a schedule.
* @async
* @function createSchedule
* @memberof SchedulerClient
* @instance
* @param {Object[]} [name] Name of the schedule to create.
* @param {Object} [params=[]] Additional params to pass to the CreateScheduleCommand.
* @return {Promise<Object>} Response normalized to camel case.
*/

/**
* Delete a schedule.
* @async
* @function deleteSchedule
* @memberof SchedulerClient
* @instance
* @param {Object[]} [name] Name of the schedule to delete.
* @param {Object} [params=[]] Additional params to pass to the DeleteScheduleCommand.
* @return {Promise<Object>} Response normalized to camel case.
*/

/**
* Update a schedule.
* AWS uses a replace all attributes strategy when updating schedules.
* This method simplifies updates by getting the existing schedule first and merging all existing top level keys with the new parameter values.
* AWS schedules
* @async
* @function deleteSchedule
* @memberof SchedulerClient
* @instance
* @param {Object[]} [name] Name of the schedule to update.
* @param {Object} [params=[]] Additional params to pass to the UpdateScheduleCommand.
* @return {Promise<Object>} Response normalized to camel case.
*/
138 changes: 138 additions & 0 deletions lib/clients/scheduler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import {
SchedulerClient as AwsSdkSchedulerClient,
CreateScheduleCommand,
DeleteScheduleCommand,
GetScheduleCommand,
UpdateScheduleCommand
} from '@aws-sdk/client-scheduler'
import { v4 as uuidv4 } from 'uuid'
import { createLogger } from '@meltwater/mlabs-logger'

import { createCache } from '../cache.js'
import { keysToCamelCase, keysToPascalCase } from '../case.js'

const createClient = createCache()

export class SchedulerClient {
#client
#reqId
#log

constructor({
name = 'scheduler',
reqId = uuidv4(),
log = createLogger(),
AwsSchedulerClient = AwsSdkSchedulerClient,
params = {}
}) {
this.#client = createClient(name, () => new AwsSchedulerClient(params))
this.#reqId = reqId
this.#log = log.child({
params,
client: name,
class: SchedulerClient.name,
reqId
})
}

async getSchedule(scheduleName, params = {}) {
const log = this.#log.child({
scheduleName,
meta: params,
method: SchedulerClient.prototype.getSchedule.name
})
try {
log.info('start')
const req = formatReq({ ...params, name: scheduleName })
const command = new GetScheduleCommand(req)

const res = await this.#client.send(command)

const data = formatRes(res)

log.debug({ data }, 'data')
log.info('end')
return data
} catch (err) {
log.error({ err }, 'fail')
throw err
}
}

async createSchedule(scheduleName, params = {}) {
const log = this.#log.child({
scheduleName,
meta: params,
method: SchedulerClient.prototype.createSchedule.name
})
try {
log.info('start')
const req = formatReq({ ...params, name: scheduleName })
const command = new CreateScheduleCommand(req)

const res = await this.#client.send(command)

const data = formatRes(res)

log.debug({ data }, 'data')
log.info('end')
return data
} catch (err) {
log.error({ err }, 'fail')
throw err
}
}

async deleteSchedule(scheduleName, params = {}) {
const log = this.#log.child({
scheduleName,
meta: params,
method: SchedulerClient.prototype.deleteSchedule.name
})
try {
log.info('start')
const req = formatReq({ name: scheduleName })
const command = new DeleteScheduleCommand(req)

const res = await this.#client.send(command)

const data = formatRes(res)

log.debug({ data }, 'data')
log.info('end')
return data
} catch (err) {
log.error({ err }, 'fail')
throw err
}
}

async updateSchedule(scheduleName, params = {}) {
const log = this.#log.child({
scheduleName,
meta: params,
method: SchedulerClient.prototype.updateSchedule.name
})
try {
log.info('start')
const schedule = await this.getSchedule(scheduleName)

const req = formatReq({ ...schedule, ...params, name: scheduleName })
const command = new UpdateScheduleCommand(req)

const res = await this.#client.send(command)

const data = formatRes(res)

log.debug({ data }, 'data')
log.info('end')
return data
} catch (err) {
log.error({ err }, 'fail')
throw err
}
}
}

const formatReq = keysToPascalCase
const formatRes = keysToCamelCase
72 changes: 72 additions & 0 deletions lib/clients/scheduler.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import test from 'ava'
import * as td from 'testdouble'
import { v4 as uuidv4 } from 'uuid'
import { createLogger } from '@meltwater/mlabs-logger'
import {
CreateScheduleCommand,

Check failure on line 6 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'CreateScheduleCommand' is defined but never used

Check failure on line 6 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'CreateScheduleCommand' is defined but never used

Check failure on line 6 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / fix

'CreateScheduleCommand' is defined but never used

Check failure on line 6 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'CreateScheduleCommand' is defined but never used

Check failure on line 6 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'CreateScheduleCommand' is defined but never used
DeleteScheduleCommand,

Check failure on line 7 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'DeleteScheduleCommand' is defined but never used

Check failure on line 7 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'DeleteScheduleCommand' is defined but never used

Check failure on line 7 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / fix

'DeleteScheduleCommand' is defined but never used

Check failure on line 7 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'DeleteScheduleCommand' is defined but never used

Check failure on line 7 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'DeleteScheduleCommand' is defined but never used
GetScheduleCommand,
UpdateScheduleCommand

Check failure on line 9 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'UpdateScheduleCommand' is defined but never used

Check failure on line 9 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'UpdateScheduleCommand' is defined but never used

Check failure on line 9 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / fix

'UpdateScheduleCommand' is defined but never used

Check failure on line 9 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (14)

'UpdateScheduleCommand' is defined but never used

Check failure on line 9 in lib/clients/scheduler.spec.js

View workflow job for this annotation

GitHub Actions / lint (16)

'UpdateScheduleCommand' is defined but never used
} from '@aws-sdk/client-scheduler'

import { registerTestdoubleMatchers } from '../../testdouble-matchers.js'

import { SchedulerClient } from './scheduler.js'

test.before(() => {
registerTestdoubleMatchers(td)
})

test.beforeEach((t) => {
t.context.AwsSchedulerClient = td.constructor(['send'])

t.context.createClient = (t, options) => {
const client = new SchedulerClient({
name: uuidv4(),
AwsSchedulerClient: t.context.AwsSchedulerClient,
reqId,
log: createLogger({ t }),
...options
})

return client
}
})

test('constructor: passes params to AWS SchedulerClient', (t) => {
const { AwsSchedulerClient } = t.context
const params = { foo: 'bar' }
const client = new SchedulerClient({
name: uuidv4(),
AwsSchedulerClient,
params,
log: createLogger({ t })
})
td.verify(new AwsSchedulerClient(params))
t.truthy(client)
})

test('getSchedule: returns response', async (t) => {
const { AwsSchedulerClient, createClient } = t.context
const client = createClient(t)

td.when(
AwsSchedulerClient.prototype.send(
td.matchers.isAwsSdkCommand(
new GetScheduleCommand({ Name: scheduleName })
)
)
).thenResolve(getScheduleResponse)

const data = await client.getSchedule(scheduleName)

t.deepEqual(data, getScheduleResponseFormatted)
})

const reqId = 'mock-req-id'

const scheduleName = 'mock-schedule-name'

const getScheduleResponse = { ScheduleArn: 'mock-schedule-arn' }

const getScheduleResponseFormatted = { scheduleArn: 'mock-schedule-arn' }

0 comments on commit e4c4cac

Please sign in to comment.