Skip to content

Commit

Permalink
Update for Hapi 17
Browse files Browse the repository at this point in the history
  • Loading branch information
martinj committed Nov 30, 2017
1 parent f3ab233 commit 1593263
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 390 deletions.
11 changes: 11 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@aptoma/eslint-config",
"parserOptions": {
"ecmaVersion": "2017"
},
"env": {
"node": true,
"mocha": true,
"es6": true
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
coverage
package-lock.json
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: node_js
node_js:
- 6
- 8

script:
- npm run ci
195 changes: 93 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,29 @@ If you already have subscription setup on SNS for your server

const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection();

server
.register({
register: require('hookido'),
options: {
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'
},
route: {
path: '/path/used/in/subscription'
},
handlers: {
notification: (req, reply, payload) => {
console.log('Got notification from SNS', payload);
reply('OK');
}

await server.register({
plugin: require('hookido'),
options: {
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'
},
route: {
path: '/path/used/in/subscription'
},
handlers: {
notification: (req, h, payload) => {
console.log('Got notification from SNS', payload);
return 'Ok'
}
}
})
.then(() => server.start())
.then(() => {
console.log('Server running and accepting SNS notifications');
});
}
});

await server.start();
console.log('Server running and accepting SNS notifications');

```

Expand All @@ -70,43 +67,40 @@ Register subscription and set custom topic and subscription attributes on startu

const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection();

server
.register({
register: require('hookido'),
options: {
topic: {
arn: 'arn:to:mytopic',
attributes: {
HTTPSuccessFeedbackRoleArn: 'arn:aws:iam::xxxx:role/myRole',
HTTPSuccessFeedbackSampleRate: '100'
},
subscribe: {
protocol: 'HTTP',
endpoint: 'http://myserver.com/hookido',
attributes: {
DeliveryPolicy: '{"healthyRetryPolicy":{"numRetries":5}}'
}
}
},
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'

await server.register({
plugin: require('hookido'),
options: {
topic: {
arn: 'arn:to:mytopic',
attributes: {
HTTPSuccessFeedbackRoleArn: 'arn:aws:iam::xxxx:role/myRole',
HTTPSuccessFeedbackSampleRate: '100'
},
handlers: {
notification: (req, reply, payload) => {
console.log('Got notification from SNS', payload);
reply('OK');
subscribe: {
protocol: 'HTTP',
endpoint: 'http://myserver.com/hookido',
attributes: {
DeliveryPolicy: '{"healthyRetryPolicy":{"numRetries":5}}'
}
}
},
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'
},
handlers: {
notification: (req, h, payload) => {
console.log('Got notification from SNS', payload);
return 'Ok'
}
}
})
.then(() => server.start())
.then(() => {
console.log('Server running and accepting SNS notifications');
});
}
});

await server.start();
console.log('Server running and accepting SNS notifications');

```

Expand All @@ -116,52 +110,49 @@ Configuring multiple SNS topics

const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection();

server
.register({
register: require('hookido'),
options: [{
topic: {
arn: 'arn:to:mytopic'
},
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'
},
route: {
path: '/path/used/in/subscription'
},
handlers: {
notification: (req, reply, payload) => {
console.log('Got notification from SNS', payload);
reply('OK');
}

await server.register({
plugin: require('hookido'),
options: [{
topic: {
arn: 'arn:to:mytopic'
},
aws: {
region: 'eu-west-1',
accessKeyId: 'a',
secretAccessKey: 'a'
},
route: {
path: '/path/used/in/subscription'
},
handlers: {
notification: (req, h, payload) => {
console.log('Got notification from SNS', payload);
return 'Ok';
}
}, {
topic: {
arn: 'arn:to:mytopic2'
},
aws: {
region: 'eu-central-1',
accessKeyId: 'b',
secretAccessKey: 'b'
},
route: {
path: '/second/path'
},
handlers: {
notification: (req, reply, payload) => {
console.log('Got notification from SNS', payload);
reply('OK');
}
}
}, {
topic: {
arn: 'arn:to:mytopic2'
},
aws: {
region: 'eu-central-1',
accessKeyId: 'b',
secretAccessKey: 'b'
},
route: {
path: '/second/path'
},
handlers: {
notification: (req, h, payload) => {
console.log('Got notification from SNS', payload);
return 'Ok';
}
}]
})
.then(() => server.start())
.then(() => {
console.log('Server running and accepting SNS notifications');
});
}
}]
});

await server.start;
console.log('Server running and accepting SNS notifications');

```
51 changes: 25 additions & 26 deletions handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ exports.hook = (sns, {handlers, skipPayloadValidation, topic}) => {
subscriptionconfirmation: confirmSubscription.bind(null, sns, topic)
}, handlers);

return (req, reply) => {
sns
return (req, h) => {
return sns
.validatePayload(req.payload, skipPayloadValidation)
.then(dispatchToHandler.bind(null, handlers, req, reply))
.catch(reply);
.then(dispatchToHandler.bind(null, handlers, req, h));
};
};

function dispatchToHandler(handlers, req, reply, payload) {
function dispatchToHandler(handlers, req, h, payload) {
const handler = handlers[payload.Type.toLowerCase()];

if (!handler) {
Expand All @@ -26,10 +25,10 @@ function dispatchToHandler(handlers, req, reply, payload) {
throw new Error(msg);
}

return handler(req, reply, payload);
return handler(req, h, payload);
}

function confirmSubscription(sns, topicOpts, req, reply, payload) {
async function confirmSubscription(sns, topicOpts, req, h, payload) {
const topicArn = Hoek.reach(topicOpts, 'arn');
if (!topicArn) {
return Promise.reject(new Error('Can\'t confirm subscription when no topic.arn is configured'));
Expand All @@ -41,24 +40,24 @@ function confirmSubscription(sns, topicOpts, req, reply, payload) {
return Promise.reject(new Error(err));
}

return request
.get(payload.SubscribeURL)
.then(() => {
req.log(['hookido', 'info'], `SNS subscription confirmed for ${payload.TopicArn}`);
reply().code(200);
try {
await request.get(payload.SubscribeURL);
req.log(['hookido', 'info'], `SNS subscription confirmed for ${payload.TopicArn}`);

const susbscriptionAttr = Hoek.reach(topicOpts, 'subscribe.attributes');
if (susbscriptionAttr) {
return sns
.findSubscriptionArn(topicOpts.arn, topicOpts.subscribe.protocol, topicOpts.subscribe.endpoint)
.then((arn) => sns.setSubscriptionAttributes(arn, susbscriptionAttr))
.catch((err) => {
req.log(['hookido', 'error'], `Unable to update subscription attributes for ${payload.TopicArn}, err: ${err.message}`);
});
}
})
.catch((err) => {
req.log(['hookido', 'error'], `Unable to confirm SNS subscription for ${payload.TopicArn}, err: ${err.message}`);
throw err;
});
} catch (err) {
req.log(['hookido', 'error'], `Unable to confirm SNS subscription for ${payload.TopicArn}, err: ${err.message}`);
throw err;
}

const susbscriptionAttr = Hoek.reach(topicOpts, 'subscribe.attributes');
if (susbscriptionAttr) {
try {
const arn = await sns.findSubscriptionArn(topicOpts.arn, topicOpts.subscribe.protocol, topicOpts.subscribe.endpoint);
await sns.setSubscriptionAttributes(arn, susbscriptionAttr);
} catch (err) {
req.log(['hookido', 'error'], `Unable to update subscription attributes for ${payload.TopicArn}, err: ${err.message}`);
}
}

return h.response().code(200);
}
23 changes: 10 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ const validOptions = Joi.array().items(Joi.object({
}).required().description('Request handler functions for different kind of sns messages')
})).single();

exports.register = function (server, opts, next) {
function register(server, opts) {
const results = Joi.validate(opts, validOptions);
Hoek.assert(!results.error, results.error);

const snsInstances = [];
results.value.forEach((config) => init(config));
server.expose('snsInstances', snsInstances);
return next();
return;

function init(config) {
const sns = new SNS(config.aws);
Expand All @@ -46,28 +46,24 @@ exports.register = function (server, opts, next) {

if (subscribe) {

server.ext('onPostStart', (srv, next) => {
sns
server.ext('onPostStart', () => {
return sns
.findSubscriptionArn(config.topic.arn, subscribe.protocol, subscribe.endpoint)
.then(() => server.log(['hookido', 'subscribe'], `Subscription already exists for ${config.topic.arn}`))
.catch({code: 'NOT_FOUND'}, requestSubscription)
.catch({code: 'PENDING'}, requestSubscription)
.catch((err) => server.log(['hookido', 'subscribe', 'error'], err));

next();
});

}

const topicAttributes = Hoek.reach(config, 'topic.attributes');
if (topicAttributes) {
server.ext('onPostStart', (srv, next) => {
sns
server.ext('onPostStart', () => {
return sns
.setTopicAttributes(config.topic.arn, topicAttributes)
.then(() => server.log(['hookido', 'setTopicAttributes'], `topicAttributes was updated for ${config.topic.arn}`))
.catch((err) => server.log(['hookido', 'setTopicAttributes', 'error'], err));

next();
});
}

Expand All @@ -81,8 +77,9 @@ exports.register = function (server, opts, next) {
}
}, config.route || {}));
}
};
}

exports.register.attributes = {
name: 'hookido'
module.exports = {
name: 'hookido',
register
};
Loading

0 comments on commit 1593263

Please sign in to comment.