Here we get into the details of creating an extension endpoint in CDC (a.k.a Gigya) and its deployment in cloud foundry.
The challenge faced by CDC developer is to understand the behavior of CDC extension that is hosted elsewhere, the blog is an attempt to explain the intricacies of creating such an extension using Node.js , this will help in testing an extension events.
Review a step-by-step guide below to create extension using Node.js and test this using postman followed by steps to deploy this on a cloud foundry.
-
- Getting the right plugins:
VS Code
- Getting the right plugins:
-
- Create a project: From your visual studio editor, choose Terminal->New Terminal
and create folder ‘Register’(parent folder) and ‘myapp’ (subfolder).
$ mkdir register
$ cd register
$ mkdir myapp
$ cd myapp
- Create a project: From your visual studio editor, choose Terminal->New Terminal
-
- Initialize the App: Navigate to the subfolder myapp
$ npm init
Press enter for every question that is being asked in your CLI, this will create a package.json file
- Initialize the App: Navigate to the subfolder myapp
-
- Install downloads a package and it’s dependencies.
$ npm install express –save
$ npm install memory-cache –save
$ npm install jws
$ npm install jws-jwk
$ npm install gigya
- Install downloads a package and it’s dependencies.
-
- Create server.js and app.js in sub folder (myapp)
server.js : Define the file to call, when running npm start and to start the server at a given port.// require http modules first const http = require('http'); //import app.js file const app = require('./app'); app.get('/', (req, res, next) => { res.status(200).send('You have called the root directory'); }); //define port to be used const port = process.env.PORT || 3100; const server = http.createServer(app); server.listen(port, () => { // let's print a message when the server run successfully console.log("Server restarted successfully") });
app.js : Define the routes which should handle request( GET, POST)
Initialize code below with your API Key, data center, user key and Secret key
// ********************** // AUXILIAR FUNCTIONS // ********************** const express = require('express'); const cache = require('memory-cache'); const jws = require('jws'); const jws_jwk = require('jws-jwk'); const Gigya = require('gigya').Gigya // Initialize SDK with your API Key , data center, user key and Secret. const gigya = new Gigya('<API_Key>', '<data_center>', '<user_key>' , '<Secret_key>'); const app = express(); const router = express.Router(); // import body-parser app.use(express.json()); // to support JSON-encoded bodies app.use(express.urlencoded({ // to support URL-encoded bodies extended: true })); // Routes which should handle request app.get('/register', (req, res, next) => { res.json(["Array1","Array2","Array3"]); }); app.post('/register', async (req, res) => { var token = req.body.jws; var decoded = jws.decode(token); var jwk = cache.get('jwk'); //verify token var body = JSON.parse(decoded.payload); var ret = { status: 'OK' }; if (body.extensionPoint === 'OnBeforeAccountsRegister' && !body.data.params.email.endsWith('@xyz.com')) { ret.status = 'FAIL'; var customMessage = 'Email should belong to domain "xyz.com" '; ret.data = { validationErrors: [ { fieldName: 'profile.email', message: customMessage }, ] } } res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(ret)); }); // Global error handler - route handlers/middlewares which throw end up here app.use((err, req, res, next) => { res.status(err.status || 500); res.end(); }); //export app module.exports = app;
- Create server.js and app.js in sub folder (myapp)
-
- Start the Server: within myapp folder
- Start the Server: within myapp folder
-
- Convert to JWS format
The validation here is for the event OnBeforeAccountsRegister when email id ends with domain other than ‘xyz.com’, it throws an error ‘Email should belong to domain “xyz.com’Sample payload for OnBeforeAccountsRegister is available at the link below
https://help.sap.com/viewer/8b8d6fffe113457094a17701f63e3d6a/GIGYA/en-US/4153ec2f70b21014bbc5a10ce40…
This is in “json” format which needs to be converted into “jws” format, online tool like jwt.io can help with conversion( here you can edit the decoded information one at a time as per our requirement and this in turn encoded the format in jws ), finally we need this( jws) to test in postman.the payload include the email id: test1@abc.com which doesn’t end with “xyz” and the extension event is OnBeforeAccountsRegister, the expectation here is status ‘FAIL’ with validation error ‘
Email should belong to domain “xyz.com” ‘
- Convert to JWS format
"apiKey": "3_ve...tyu",
"callID": "809.....169f",
"extensionPoint": "OnBeforeAccountsRegister",
"data": {
"params": {
"email": "test1@abc.com",
"password": "what ever password the user entered",
"profile": {
"firstName": "test"
},
"data": {
"terms": true
}
},
"context": {
"clientIP": "1.0.0.0"
}
}
}
{
"jws": "eyJhbGciOiJIUzI1NiIsImtpZCI6IlJEQXpSRVl5TmpCRk5USTVSak5ETURrd1JEUkJNMEZDUkRRM1FqQkNSRUpDUmpZNE9ESkZRUSJ9.eyJhcGlLZXkiOiIzX3ZlLi4udHl1IiwiY2FsbElEIjoiODA5Li4uLi4xNjlmIiwiZXh0ZW5zaW9uUG9pbnQiOiJPbkJlZm9yZUFjY291bnRzUmVnaXN0ZXIiLCJkYXRhIjp7InBhcmFtcyI6eyJlbWFpbCI6InRlc3QxQGFiYy5jb20iLCJwYXNzd29yZCI6IndoYXQgZXZlciBwYXNzd29yZCB0aGUgdXNlciBlbnRlcmVkIiwicHJvZmlsZSI6eyJmaXJzdE5hbWUiOiJ0ZXN0In0sImRhdGEiOnsidGVybXMiOnRydWV9fSwiY29udGV4dCI6eyJjbGllbnRJUCI6IjEuMC4wLjAifX19.3tzVu5n3NvXPDIDQaVpJ5UYEA8zs8KpsxAnacovkMac"
}
-
- Test Using Postman( try the desktop agent, not on the browser)
The final step is to test using postman and check for the response in case the email ends with domain other than xyz.com.
URL: http://localhost:3100/register
Body: the JWS format encoded in step above
Type: JSON
Response
-
- Deploy in cloud foundry.1. As a next step we will deploy Node.js App to SCP Cloud Foundry for this we need to create yml in the folder register.
Manifest Folder
Run the Powershell/msdos in administrator mode and navigate to folder that contain manifest.yml file
cf api api-end-point( example https://api.cf.eu10.hana.ondemand.com )
A. cf api https://api.cf.us10.hana.ondemand.com/ for example
B. cf login and if you have multiple org, choose the org where you shall upload this.
C. cf push
D . Make Note of the URL as this will be used in extension in CDC. You can find this URL within the service that is created in cloud foundry.
-
- Configure CDC extension with new endpoint and activate it.
Mention the folder name at the end of the Cloud foundry endpoint URL ,here in this example its register.https://myapp-unexpected-camel-ze.cfapps.us10.hana.ondemand.com/register ( you can also test the URL in postman)Its is better to Increase the default timeout to 6000ms as it may take some time to receive response from the Server.
- Configure CDC extension with new endpoint and activate it.
-
-
Test the extension by registering an account with email ending with domain other than ‘xyz.com’ .
With the response received from the server, fail the registration and registration response returned to the client.
-
Test the extension by registering an account with email ending with domain other than ‘xyz.com’ .