Skip to Content
Technical Articles
Author's profile photo yasuyuki uno

SAP Cloud Platform Alert Notification integrate with JIRA Service Desk

In my previous article, I tried to notify the custom alert by E-mail. I’ll try to integrate with JIRA in this article.

You will know..

  • How to integrate SAP Cloud Platform Alert Notification with JIRA Service Desk.

Estimated time

  • 40 minutes

Appendix: About SAP Cloud Platform Alert Notification

Alert Notification offers platform alerts and notifications for resources in the SAP Cloud Platform and gives you the possibility to create custom alerts for these resources.
This GA released at June 2019.


Alert Notification has several action types as below.

  • Email
  • Slack
  • Slack threaded
  • Store
  • Webhook
  • Webhook with Basic Authentication
  • Webhook with OAuth Authentication

Since JIRA provides a REST API, I thought it would be possible to link with webhook.
In the first place, we need to understand what is sent to the webhook destination from Alert Notification, and what parameters JIRA API needs.

When I checked the webhook request body, it was the following JSON.

{
	"eventType": "mycustomevent",
	"resource": {
		"resourceName": "Your Node.js App.",
		"resourceType": "app",
		"tags": {
			"env": "develop environment"
		}
	},
	"severity": "FATAL",
	"category": "ALERT",
	"subject": "SAP CP Alert to JIRA",
	"body": "Hello world\nfoo\nbar",
	"tags": {
		"foo:bar": "baz",
		"customTag": "hello"
	}
}

And what parameters JIRA create issue API needs are like below.

{
  "update": {},
  "fields": {
      "summary": "JIRA Ticket title",
      "description": {
      "type": "doc",
      "version": 1,
      "content": [
        {
          "type": "paragraph",
          "content": [
            {
              "text": "JIRA content",
              "type": "text"
            }
          ]
        }
      ]
    },
    "issuetype": {
      "id": "10103"
    },
    "project": {
      "key": "DEMO"
    }
  }
}

The webhook request body and needed params in JIRA REST API are different. So we need to create a JIRA webhook bridge adapter for convert parameters.

The real system configuration diagram of this article is as follows.


Prerequirements

Outline of the procedure

  1. Configure the Alert Notification.
  2. Acquiring API Access Credentials.
  3. Create a JIRA API token.
  4. Create a JIRA Bridge Adapter.
  5. Deploy the bridge adapter to CF.
  6. Testing.

1.Configure the Alert Notification.

Navigate to the Instances tab in the cockpit and click the New Instance button.

This time, I set the instance name as “alertinstance”.

Navigate to the Subscriptions tab in the cockpit and click the Create button.

This subscription name is not important. Any name is ok.

The Condition name, I set “EventTypelsCustomAlert” this time.

The below setting is important. I set “eventType is Equal To mycustomevent”.

Select the action type Webhook and then choose Next.

URL Address https://<yourbridgeappname>.cfapps.eu10.hana.ondemand.com/webhook

In my case, my bridge adapter app name will be “jirabridge”.

 

2.Acquiring API Access Credentials.

To enable interactions with the Producer API , you need to create a service key.

You also have to option to import a JSON containing the one of the following parameters:
{"type":"BASIC"} - use for creating basic authentication credentials
{"type":"OAUTH"} - use for creating OAuth 2.0 credentials
In this time, we use Basic authentication.

Navigate to the Service Keys tab and click Create Service Keys button.

3.Create a JIRA API token.

Please refer the Atlassian official document. You will get a JIRA API token.

4.Create a JIRA Bridge Adapter.

Open Command Prompt and move to your workspace directory. In my case, the workspace is “D:\html5”.

cd /d D:\html5

Install the express generator. Express is the most popular Node.js framework.

npm install express-generator -g

Generate new project.

express -e jirabridge

Move to your project directory and edit package.json.

cd jirabridge

■package.json (added request module).

{
  "name": "jirabridge",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "ejs": "~2.6.1",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "request": "*"
  }
}

Then install dependencies.

npm install

Then edit app.js
Copy the following code and use it.

■app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var request = require('request');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

app.post("/webhook", function(req,res,next){

	console.log(req.body);
	var options = {
	   method: 'POST',
	   url: req.body.tags["jira:endpointURL"]+"/rest/api/3/issue",
	   auth: {
	     user: req.body.tags["jira:user"],
	     password: req.body.tags["jira:token"]
	   },
	   headers: {
	      'Content-Type': 'application/json'
	   },
	   json: {
		  "update": {},
		  "fields": {
		  	"summary": req.body.subject,
		    "description": {
		      "type": "doc",
		      "version": 1,
		      "content": [
		        {
		          "type": "paragraph",
		          "content": [
		            {
		              "text": req.body.body,
		              "type": "text"
		            }
		          ]
		        }
		      ]
		    },
		    "issuetype": {
		      "id": req.body.tags["jira:issueType"]
		    },
		    "project": {
		      "key": req.body.tags["jira:project"]
		    }
		  }
		}
	};

	request(options, function (error, response, body) {
		if (error) throw new Error(error);
		console.log(
		      'Response: ' + response.statusCode + ' ' + response.statusMessage
		);
		console.log(body);
		res.send("OK");
	});
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

 

5.Deploy the bridge adapter to CF.

Using CF CLI, login and deploy the app into Cloud Foundly.

cf api https://api.cf.eu10.hana.ondemand.com
cf login

# Deploy command.
cf push jirabridge
Pushing app jirabridge to org XXXXXXXX.XXXXXXXX / space dev as unoys@qunie.com...
Getting app info...
Updating app with these attributes...
  name:                jirabridge
  path:                D:\html5\jirabridge
  buildpack:           nodejs
  command:             npm start
  disk quota:          1G
  health check type:   port
  instances:           1
  memory:              1G
  stack:               cflinuxfs3
  routes:
    jirabridge.cfapps.eu10.hana.ondemand.com

Updating app jirabridge...
Mapping routes...
Comparing local files to remote cache...
Packaging files to upload...
Uploading files...
 1.40 MiB / 1.40 MiB [=====================================================================================] 100.00% 6s

Waiting for API to complete processing files...

Stopping app...

Staging app and tracing logs...
   Downloaded app package (1.8M)

Now the bridge adapter works on your CF space.

6.Testing.

Call the custom alerts from API Business Hub or from Node.js app I previously created.

Please set these properties in your Producer API request.

{
	  "eventType": "mycustomevent",
	  "resource": {
	    "resourceName": "Your Node.js App.",
	    "resourceType": "app",
	    "tags": {
	      "env": "develop environment"
	    }
	  },
	  "severity": "FATAL",
	  "category": "ALERT",
	  "subject": "SAP CP Alert to JIRA",
	  "body": "Hello world\nfoo\nbar",
	  "tags": {
	    "jira:endpointURL": "https://your-jira-domain.atlassian.net", // Change to your JIRA domain.
	    "jira:user": "example@yourdomain.com",  // Change to Your JIRA account.
	    "jira:token": "**********",  // Change to Your JIRA API token.
	    "jira:project": "DEMO",		 // Change to Your JIRA project name. In my case, "DEMO".
	    "jira:issueType": "10103"
	  }
}

You will get an email from JIRA.

And You can confirm the ticket has been issued to JIRA Service Desk.

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Martin Lakov
      Martin Lakov

      Hello yasuyuki uno,

      once again awesome blog post! Thank you very much for taking the time creating it!

      I think that sometime in the near future the Alert Notification service is going to provide some extra  functions and capabilities in that area. What seems to be a prominent one is the possibility for  for re-formatting of the webhook payloads so that no bridge or adapter applications will be needed for communicating with systems like JIRA.

      Best Regards,
      Martin

      Author's profile photo yasuyuki uno
      yasuyuki uno
      Blog Post Author

      Hello Martin

      I hope so too. In particular, I hope the Alert Notification is going to strengthen collaboration with SAP services (for ex. HANA Service, Application Logging....) .

      Author's profile photo Martin Lakov
      Martin Lakov

      Recently the SAP Cloud Platform Alert Notification service has extended its functions in regards of web hooks with payload templating. This can now be utilised for opening JIRA issues as seen in this blog post: https://blogs.sap.com/2019/09/19/posting-alerts-to-jira-and-other-issue-tracking-systems-with-sap-cloud-platform-alert-notification/