Skip to content

Commit cf7aadd

Browse files
committed
support SQS
1 parent 55e6f0e commit cf7aadd

File tree

6 files changed

+235
-30
lines changed

6 files changed

+235
-30
lines changed

lib/apiGateway/validate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ module.exports = {
4545
},
4646

4747
async checkAllowedService(serviceName) {
48-
const allowedProxies = ['kinesis']
48+
const allowedProxies = ['kinesis', 'sqs']
4949
if (allowedProxies.indexOf(serviceName) === NOT_FOUND) {
5050
const errorMessage = [
5151
`Invalid APIG proxy "${serviceName}".`,

lib/index.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ const compileRestApi = require('serverless/lib/plugins/aws/package/compile/event
1010
const compileResources = require('serverless/lib/plugins/aws/package/compile/events/apiGateway/lib/resources')
1111
const compileDeployment = require('serverless/lib/plugins/aws/package/compile/events/apiGateway/lib/deployment')
1212
const getStackInfo = require('serverless/lib/plugins/aws/info/getStackInfo')
13+
// Kinesis
1314
const compileMethodsToKinesis = require('./package/kinesis/compileMethodsToKinesis')
1415
const compileIamRoleToKinesis = require('./package/kinesis/compileIamRoleToKinesis')
1516
const validateKinesisServiceProxy = require('./package/kinesis/validateKinesisServiceProxy')
1617
const compileKinesisServiceProxy = require('./package/kinesis/compileKinesisServiceProxy')
18+
// SQS
19+
const compileMethodsToSqs = require('./package/sqs/compileMethodsToSqs')
20+
const compileIamRoleToSqs = require('./package/sqs/compileIamRoleToSqs')
21+
//const validateKinesisServiceProxy = require('./package/sqs/validateKinesisServiceProxy')
22+
const compileSqsServiceProxy = require('./package/sqs/compileSqsServiceProxy')
1723

1824
class ServerlessApigatewayServiceProxy {
1925
constructor(serverless, options) {
@@ -32,6 +38,9 @@ class ServerlessApigatewayServiceProxy {
3238
compileDeployment,
3339
validateKinesisServiceProxy,
3440
compileKinesisServiceProxy,
41+
compileMethodsToSqs,
42+
compileIamRoleToSqs,
43+
compileSqsServiceProxy,
3544
getStackInfo,
3645
validate,
3746
methods,
@@ -44,12 +53,16 @@ class ServerlessApigatewayServiceProxy {
4453
this.validated = await this.validateServiceProxies()
4554
await this.compileRestApi()
4655
await this.compileResources()
47-
if (await this.existsDeployment()) {
48-
await this.compileDeployment()
49-
}
5056

5157
//Kinesis proxy
5258
await this.compileKinesisServiceProxy()
59+
60+
// SQS getProxy
61+
await this.compileSqsServiceProxy()
62+
63+
if (await this.existsDeployment()) {
64+
await this.compileDeployment()
65+
}
5366
}
5467
},
5568
'after:deploy:deploy': async () => {

lib/package/kinesis/compileMethodsToKinesis.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,39 @@ module.exports = {
77
async compileMethodsToKinesis() {
88
this.apiGatewayMethodLogicalIds = []
99
this.validated.events.forEach(async (event) => {
10-
const resourceId = this.getResourceId(event.http.path)
11-
const resourceName = this.getResourceName(event.http.path)
12-
13-
const template = {
14-
Type: 'AWS::ApiGateway::Method',
15-
Properties: {
16-
HttpMethod: event.http.method.toUpperCase(),
17-
RequestParameters: {},
18-
AuthorizationType: 'NONE',
19-
ApiKeyRequired: Boolean(event.http.private),
20-
ResourceId: resourceId,
21-
RestApiId: this.provider.getApiGatewayRestApiId()
10+
if (event.functionName == 'kinesis') {
11+
const resourceId = this.getResourceId(event.http.path)
12+
const resourceName = this.getResourceName(event.http.path)
13+
14+
const template = {
15+
Type: 'AWS::ApiGateway::Method',
16+
Properties: {
17+
HttpMethod: event.http.method.toUpperCase(),
18+
RequestParameters: {},
19+
AuthorizationType: 'NONE',
20+
ApiKeyRequired: Boolean(event.http.private),
21+
ResourceId: resourceId,
22+
RestApiId: this.provider.getApiGatewayRestApiId()
23+
}
2224
}
23-
}
2425

25-
_.merge(
26-
template,
27-
await this.getKinesisMethodIntegration(event.http),
28-
await this.getMethodResponses(event.http)
29-
)
26+
_.merge(
27+
template,
28+
await this.getKinesisMethodIntegration(event.http),
29+
await this.getMethodResponses(event.http)
30+
)
3031

31-
const methodLogicalId = this.provider.naming.getMethodLogicalId(
32-
resourceName,
33-
event.http.method
34-
)
32+
const methodLogicalId = this.provider.naming.getMethodLogicalId(
33+
resourceName,
34+
event.http.method
35+
)
3536

36-
this.apiGatewayMethodLogicalIds.push(methodLogicalId)
37+
this.apiGatewayMethodLogicalIds.push(methodLogicalId)
3738

38-
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
39-
[methodLogicalId]: template
40-
})
39+
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
40+
[methodLogicalId]: template
41+
})
42+
}
4143
})
4244

4345
return BbPromise.resolve()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict'
2+
const _ = require('lodash')
3+
const BbPromise = require('bluebird')
4+
5+
module.exports = {
6+
async compileIamRoleToSqs() {
7+
await BbPromise.all(
8+
this.getAllServiceProxies().map(async (serviceProxy) => {
9+
Object.keys(serviceProxy).forEach(async (serviceName) => {
10+
if (serviceName == 'sqs') {
11+
const template = {
12+
Type: 'AWS::IAM::Role',
13+
Properties: {
14+
AssumeRolePolicyDocument: {
15+
Version: '2012-10-17',
16+
Statement: [
17+
{
18+
Effect: 'Allow',
19+
Principal: {
20+
Service: 'apigateway.amazonaws.com'
21+
},
22+
Action: 'sts:AssumeRole'
23+
}
24+
]
25+
},
26+
Policies: [
27+
{
28+
PolicyName: 'apigatewaytosqs',
29+
PolicyDocument: {
30+
Version: '2012-10-17',
31+
Statement: [
32+
{
33+
Effect: 'Allow',
34+
Action: [
35+
'logs:CreateLogGroup',
36+
'logs:CreateLogStream',
37+
'logs:PutLogEvents'
38+
],
39+
Resource: '*'
40+
},
41+
{
42+
Effect: 'Allow',
43+
Action: ['sqs:SendMessage'],
44+
Resource: '*'
45+
}
46+
]
47+
}
48+
}
49+
]
50+
}
51+
}
52+
53+
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
54+
ApigatewayToSqsRole: template
55+
})
56+
}
57+
})
58+
})
59+
)
60+
}
61+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
'use strict'
2+
3+
const BbPromise = require('bluebird')
4+
const _ = require('lodash')
5+
6+
module.exports = {
7+
async compileMethodsToSqs() {
8+
this.apiGatewayMethodLogicalIds = []
9+
this.validated.events.forEach(async (event) => {
10+
if (event.functionName == 'sqs') {
11+
const resourceId = this.getResourceId(event.http.path)
12+
const resourceName = this.getResourceName(event.http.path)
13+
14+
const template = {
15+
Type: 'AWS::ApiGateway::Method',
16+
Properties: {
17+
HttpMethod: event.http.method.toUpperCase(),
18+
RequestParameters: {},
19+
AuthorizationType: 'NONE',
20+
ApiKeyRequired: Boolean(event.http.private),
21+
ResourceId: resourceId,
22+
RestApiId: this.provider.getApiGatewayRestApiId()
23+
}
24+
}
25+
26+
_.merge(
27+
template,
28+
await this.getSqsMethodIntegration(event.http),
29+
await this.getMethodResponses(event.http)
30+
)
31+
32+
const methodLogicalId = this.provider.naming.getMethodLogicalId(
33+
resourceName,
34+
event.http.method
35+
)
36+
37+
this.apiGatewayMethodLogicalIds.push(methodLogicalId)
38+
39+
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
40+
[methodLogicalId]: template
41+
})
42+
}
43+
})
44+
45+
return BbPromise.resolve()
46+
},
47+
48+
async getSqsMethodIntegration(http) {
49+
let queueName = http.queueName
50+
if (typeof http.queueName == 'string') {
51+
queueName = `"${queueName}"`
52+
}
53+
const integration = {
54+
IntegrationHttpMethod: 'POST',
55+
Type: 'AWS',
56+
Credentials: {
57+
'Fn::GetAtt': ['ApigatewayToSqsRole', 'Arn']
58+
},
59+
Uri: {
60+
'Fn::Join': [
61+
'',
62+
[
63+
'arn:aws:apigateway:',
64+
{
65+
Ref: 'AWS::Region'
66+
},
67+
':sqs:path//',
68+
{
69+
Ref: 'AWS::AccountId'
70+
},
71+
'/',
72+
queueName
73+
]
74+
]
75+
},
76+
RequestParameters: {
77+
'integration.request.querystring.Action': "'SendMessage'",
78+
'integration.request.querystring.MessageBody': 'method.request.body.message'
79+
},
80+
RequestTemplates: { 'application/json': '{statusCode:200}' }
81+
}
82+
83+
const integrationResponse = {
84+
IntegrationResponses: [
85+
{
86+
StatusCode: 200,
87+
SelectionPattern: 200,
88+
ResponseParameters: {},
89+
ResponseTemplates: {}
90+
},
91+
{
92+
StatusCode: 400,
93+
SelectionPattern: 400,
94+
ResponseParameters: {},
95+
ResponseTemplates: {}
96+
}
97+
]
98+
}
99+
100+
if (http && http.cors) {
101+
let origin = http.cors.origin
102+
if (http.cors.origins && http.cors.origins.length) {
103+
origin = http.cors.origins.join(',')
104+
}
105+
106+
integrationResponse.IntegrationResponses.forEach(async (val, i) => {
107+
integrationResponse.IntegrationResponses[i].ResponseParameters = {
108+
'method.response.header.Access-Control-Allow-Origin': `'${origin}'`
109+
}
110+
})
111+
}
112+
113+
_.merge(integration, integrationResponse)
114+
115+
return {
116+
Properties: {
117+
Integration: integration
118+
}
119+
}
120+
}
121+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict'
2+
module.exports = {
3+
async compileSqsServiceProxy() {
4+
//await this.validateKinesisServiceProxy()
5+
await this.compileIamRoleToSqs()
6+
await this.compileMethodsToSqs()
7+
}
8+
}

0 commit comments

Comments
 (0)