integration/resources/templates/combination/connector_appsync_to_eventbus.yaml (171 lines of code) (raw):

Resources: EventBus: Type: AWS::Events::EventBus Properties: Name: !Sub "${AWS::StackName}-EventBus" EventBridgeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sts:AssumeRole Principal: Service: - appsync.amazonaws.com - lambda.amazonaws.com AppSyncApi: Type: AWS::AppSync::GraphQLApi Properties: Name: AppSyncApi AuthenticationType: API_KEY ApiSchema: Type: AWS::AppSync::GraphQLSchema Properties: ApiId: !GetAtt AppSyncApi.ApiId Definition: | type EntryDetails { ErrorCode: String ErrorMessage: String EventId: String! } type PutEventsResult { Entries: [EntryDetails!]! FailedEntry: Int } type Query { sayHello: PutEventsResult! } schema { query: Query } AppSyncEventBusDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: !GetAtt AppSyncApi.ApiId Name: AppSyncEventBusDataSource Type: AMAZON_EVENTBRIDGE ServiceRoleArn: !GetAtt EventBridgeRole.Arn EventBridgeConfig: EventBusArn: !GetAtt 'EventBus.Arn' AppSyncSayHelloResolver: DependsOn: ApiSchema Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt AppSyncApi.ApiId TypeName: Query FieldName: sayHello DataSourceName: !GetAtt AppSyncEventBusDataSource.Name Runtime: Name: APPSYNC_JS RuntimeVersion: 1.0.0 Code: | import { util } from '@aws-appsync/utils'; export function request(ctx) { return { "operation" : "PutEvents", "events" : [{ "source": "com.mycompany.myapp", "detail": { "key1" : "value1", "key2" : "value2" }, "resources": ["Resource1", "Resource2"], "detailType": "myDetailType" }] } } export function response(ctx) { if(ctx.error) util.error(ctx.error.message, ctx.error.type, ctx.result) else return ctx.result } Connector: Type: AWS::Serverless::Connector Properties: Source: Id: AppSyncEventBusDataSource Destination: Id: EventBus Permissions: - Write ApiKey: Type: AWS::AppSync::ApiKey Properties: ApiId: !GetAtt AppSyncApi.ApiId TriggerFunction: Type: AWS::Serverless::Function Properties: Role: !GetAtt EventBridgeRole.Arn Environment: Variables: API_KEY: !GetAtt ApiKey.ApiKey GRAPHQL_URL: !GetAtt AppSyncApi.GraphQLUrl EventBusName: !Ref EventBus Runtime: nodejs16.x Handler: index.handler InlineCode: | const https = require("https"); exports.handler = async () => { const queries = { sayHello: /* GraphQL */ ` query { sayHello { Entries { ErrorCode EventId ErrorMessage } FailedEntry } } `, }; const fetch = async (url, options) => new Promise((resolve, reject) => { const req = https.request(url, options, (res) => { const body = []; res.on("data", (chunk) => body.push(chunk)); res.on("end", () => { const resString = Buffer.concat(body).toString(); resolve(resString); }); }); req.on("error", (err) => { reject(err); }); req.on("timeout", () => { req.destroy(); reject(new Error("Request time out")); }); req.write(options.body); req.end(); }); const makeRequest = async (queryName) => { const options = { method: "POST", headers: { "x-api-key": process.env.API_KEY, }, body: JSON.stringify({ query: queries[queryName] }), timeout: 600000, // ms }; const response = await fetch(process.env.GRAPHQL_URL, options); let body = JSON.parse(response); const data = body.data?.[queryName]; if (body.errors !== undefined) { throw JSON.stringify(body.errors); } if (data.FailedEntry != null || data.ErrorCode != null ) { throw new Error( `${queryName} error: failed to send event to eventbus ${process.env.EventBusName}`); } return body.data; }; await makeRequest("sayHello"); }; Metadata: SamTransformTest: true