Let's say you have an AWS SNS topic that sends a lot of information. And you're overwhelmed and you want a more streamlined solution such as a dashboard with database backend. And for the sake of this scenario, we'll leave AWS Gateway API and Lambda out of it. Because you already have a ColdFusion just sitting around.
Step 1: Write the CFC files
- Go to your website's physical directory and create a new folder called "rest". You don't have to call it that, but I do just for example sake.
- Create two files:
- application.cfc
- sns.cfc
- application.cfc
component output="false" { this.name = "my-rest"; this.applicationTimeout = createTimespan(0,1,0,0); this.datasource = "myDB"; this.restSettings.skipCFCWithError = true; public boolean function onRequestStart() { request._body = toString(getHttpRequestData().content); return true; } public boolean function onRequest() { return true; } }
- It is important that you set "request._body" here. Otherwise, you won't see the content.
- You can put any other functions here to override the one from parent's Application.cfc
- sns.cfc
<cfcomponent rest="true" restpath="sns"> <cffunction name="postSNSTopic" access="remote" httpMethod="POST" returntype="string" produces="application/json"> <cfargument name="body" type="string" restArgumentSource="body"/> <cfscript> response = "y"; messageType = getHttpRequestData().headers["x-amz-sns-message-type"]; messageID = getHttpRequestData().headers["x-amz-sns-message-id"]; topicARN = getHttpRequestData().headers["x-amz-sns-topic-arn"]; subject = "None"; messageJson = ""; content = ""; switch(messageType){ case "SubscriptionConfirmation": //Enter subscription action here break; case "Notification": //Enter notification action here break; default: response = "n"; } if(response IS "y"){ content = getHttpRequestData().content; contentLen = len(content); if(contentLen GT 0){ contentStruct = deserializeJson(toString(content)); subject = contentStruct["Subject"]; if(len(subject) EQ 0){ subject = "None"; } messageJson = contentStruct["Message"]; messageLen = len(messageJson); if(messageLen EQ 0){ messageJson = "No Content"; } }else{ content = "No Content"; //TroubleShooting //headers = getHttpRequestData().headers; //for(item in headers){ //content = content & "." & item & ":" & getHttpRequestData().headers[item]; //} } } </cfscript> <cfif response EQ "y"> <cfquery name = "sns_insert" datasource="mydb"> insert into sns_listener(messageType, messageID, topicARN, subject, messageJSON, content, timestamp) values ( <cfqueryParam value=#messageType# cfSqlType="cf_sql_varchar" maxlength="100"/>, <cfqueryParam value=#messageID# cfSqlType="cf_sql_varchar" maxlength="100"/>, <cfqueryParam value=#topicARN# cfSqlType="cf_sql_varchar" maxlength="100"/>, <cfqueryParam value=#subject# cfSqlType="cf_sql_varchar" maxlength="100"/>, <cfqueryParam value=#messageJson# cfSqlType="cf_sql_clob" maxlength="100"/>, <cfqueryParam value=#content# cfSqlType="cf_sql_clob" maxlength="100"/>, sysdate) </cfquery> <cfelse> <cfquery name = "sns_insert" datasource="mydb"> insert into sns_listener(messageType, timestamp) values ('error',sysdate) </cfquery> </cfif> </cffunction> </cfcomponent>
- Details about HTTP Header and JSON content from SNS message can be found here.
- Log into ColdFusion Administrator
- Under Server Settings, click Mappings
- Add Logical Path as "/rest"
- Add Directory Path as the actual path of your files, "E:/website/rest"
- Under Data & Services, click REST services
- Add the Logical Path you used above, "/rest"
- Leave Host as blank
- You can leave service mapping blank, it will pick this up from your Application.cfc
- Select "Set as default application"
- Add service
Step 3: Go to AWS SNS and subscribe your endpoint
- Your REST end point will be https://www.mywebsite.com/rest/sns
- "rest" says this is a REST call
- "sns" is the name of your cfc file that contains the POST function
- Once you subscribe, you can manually confirm your subscription by pulling out the subscribeURL in the message or you can write a function in the body of sns.cfc above.
References:
cfqueryparam function
HTTPS SNS Issue with CA
SNS JSON format
No comments:
Post a Comment