Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Anuj07
Employee
Employee
0 Kudos

In the Part 2of this blog series, you installed Atlassian SDK and created a plugin for capturing events In this part you will send gamification relevant events to the gamification service.


1. Set-up eclipse project


 

1. Open the file  jira-gamification-plugin/pom.xml as shown in the screenshot  below



2. Add the following dependencies in the dependencies section of pom.xml.


<!--   Apache commons-codec package has a class Base64 which you will be using for encoding and decoding of username and password  -->


<dependency>


<groupId>commons-codec</groupId>


<artifactId>commons-codec</artifactId>


<version>1.10</version>


</dependency>


 

<!—Apache httpclient package will be used for executing HTTP requests -->


<dependency>


<groupId>org.apache.httpcomponents</groupId>


<artifactId>httpclient</artifactId>


<version>4.5</version>


<scope>provided</scope>


</dependency>


 

The dependencies section will look like:



3. To work with the JIRA plugin in the Eclipse IDE, the plugin needs to be converted into an Eclipse project. For this, open a command prompt. Change directory to the folder ‘jira-gamification-plugin’ and run the following command:

 

atlas-mvn eclipse:eclipse


This command will generate Eclipse configuration files for an Eclipse project and print a success message.


 


4. Import this project into Eclipse as described here.



2. Send gamification relevant event to gamification service


Next, a test event will be sent programmatically to the gamification service. This is similar to the event that was triggered from the API terminal in the previous blog.


 

1. Create a class with name EnvironmentUtility in package com.sap.gamification.plugins. Right click on the folder of the project


named jira-Gamification-plugin’ and select New > Class. Enter Package as com.sap.gamification.plugins and Class name as EnvironmentUtility.


Click on button Finish.


Replace the code generated for the file EnvironmentUtility.java with the give code


EnvironmentUtility.java




package com.sap.gamification.plugins;
/**
* This class is used for retrieving environment values.
*/

public class EnvironmentUtility {

public static String technicalUserName=null;
public static String technicalUserPassword=null;
public static String proxy=null;
public static String port=null;
public static String host=null;


public static void readEnvironmentValues(){
EnvironmentUtility.proxy=System.getenv("http_proxy_host");
EnvironmentUtility.port = System.getenv("http_proxy_port");
EnvironmentUtility.technicalUserName = System.getenv("user_name");
EnvironmentUtility.technicalUserPassword = System.getenv("user_password");
EnvironmentUtility.host = System.getenv("host");
}

}

 

The Class EnvironmentUtility


This class is used for retrieving values for some environment variables.


 

2.Create a class with the name GamificationProxy in package com.sap.gamification.plugins.Right click on the folder of the project name


jira-Gamification-plugin and select New > Class. Enter Package as com.sap.gamification.plugins and Class name as GamificationProxy.Click on Finish as shown in the snapshot below.



Replace the code generated in the file GamificationProxy.java with the given code 



package com.sap.gamification.plugins;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import javax.servlet.ServletException;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;

/**
* This is the proxy class for calling Gamification Service APIs.
*
*/
public class GamificationProxy {
private static String SCHEME = "https";
private static String PATH = "/gamification/api/tech/JsonRPC";
public static final String GAMIFICATION_SERVICE_APPNAME = "JIRA";

/**
* This is used for sending gamification event to the Gamification Service.
*
* @param playerId
* @param priority
* @return
* @throws URISyntaxException
* @throws ClientProtocolException
* @throws IOException
*/

public Integer sendEvent(String playerId, String priority,
String eventName) throws URISyntaxException,
ClientProtocolException, IOException {
URIBuilder builder = new URIBuilder();
String value = "{" + "\"method\":\"" + "handleEvent" + "\","
+ "\"params\":[" + "{" + "\"type\":\"" + eventName
+ "\"," + "\"playerid\":\"" + playerId
+ "\"," + "\"data\":{" + "\"relevance\":\""
+ priority + "\"" + "}" + "}" + "]" + "}";
builder.setScheme(SCHEME)
.setHost(EnvironmentUtility.host)
.setPath(PATH)
.setParameter(
"json",
value)
.setParameter("app", GAMIFICATION_SERVICE_APPNAME);
URI url = builder.build();
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
post.setHeader(
"Authorization",
getBase64Auth(EnvironmentUtility.technicalUserName,
EnvironmentUtility.technicalUserPassword));
// If you are running this behind behind some corporate network fire
// wall the you need to set the proxy
if (EnvironmentUtility.proxy != null
&& !EnvironmentUtility.proxy.equalsIgnoreCase("")) {
setHttpHostProxy(post);
}
HttpResponse doPostResponse = client.execute(post);
return Integer.valueOf(doPostResponse.getStatusLine().getStatusCode());
}

/**
* This is for getting player experience points for jira profile page.
*
* @param playerId
* @return
* @throws URISyntaxException
* @throws ClientProtocolException
* @throws IOException
* @throws ServletException
*/

public String getPlayerProfileData(String playerId) throws Exception {
URIBuilder builder = new URIBuilder();
String value = "{" + "\"method\":\"" + "getPlayerRecord" + "\","
+ "\"params\":["
+ "\"" + playerId + "\"" + "]" + "}";
builder.setScheme(SCHEME)
.setHost(EnvironmentUtility.host)
.setPath("/gamification/api/tech/JsonRPC")
.setParameter(
"json",
value)
.setParameter("app", GAMIFICATION_SERVICE_APPNAME);
URI httpsURI = builder.build();
HttpResponse httpResp = executeHttpsURI(httpsURI);
String playerProfileDataResp = getHttpEntityContent(httpResp);
return playerProfileDataResp;
}


/**
* This returns a leader board relative to the player for user profile page.
* @param playerName
* @return
* @throws Exception
*/
public String getRelativeLeaderBoardDetails(String playerName) throws Exception {
URIBuilder builder = new URIBuilder();
java.util.Date date = new java.util.Date();
DateTime today=new DateTime(date);
DateTime todayMinus30Days = today.minusDays(30);
long monthStart = todayMinus30Days.toDate().getTime();
long monthEnd = date.getTime();
String value = "{" + "\"method\":\"getLeaderboardForPlayer\",\"params\":["+ "\"" + playerName + "\","
+ "\"Experience Points\",1,null,"+monthStart+","+monthEnd+"]" + "}";
builder.setScheme(SCHEME)
.setHost(EnvironmentUtility.host)
.setPath("/gamification/api/tech/JsonRPC")
.setParameter(
"json",
value)
.setParameter("app", GAMIFICATION_SERVICE_APPNAME);
URI httpsURI = builder.build();
HttpResponse gamificationServiceResponse = executeHttpsURI(httpsURI);
String leaderBoardDetailsResp = getHttpEntityContent(gamificationServiceResponse);
return leaderBoardDetailsResp;
}


/**
* This is used to fetch player's notifications.
*
* @param playerName
* @param serverTime
* @return
* @throws URISyntaxException
* @throws ClientProtocolException
* @throws IOException
* @throws ServletException
*/
public String getPlayerNotifications(String playerName, String serverTime)
throws URISyntaxException, ClientProtocolException, IOException,
ServletException {
URIBuilder builder = new URIBuilder();
String value = "{" + "\"method\":\"" + "getNotificationsForPlayer"
+ "\", "
+ "\"params\":[" + "\"" + playerName + "\""+","
+ serverTime + "]" + "}";
builder.setScheme(SCHEME)
.setHost(EnvironmentUtility.host)
.setPath("/gamification/api/tech/JsonRPC")
.setParameter(
"json",
value)
.setParameter("app", GAMIFICATION_SERVICE_APPNAME);
URI httpsURI = builder.build();
HttpResponse gamificationServiceResponse = executeHttpsURI(httpsURI);
String userNotificationResponse = getHttpEntityContent(gamificationServiceResponse);
return userNotificationResponse;
}

/**
* This is used to return current server time
* @return
* @throws URISyntaxException
* @throws ServletException
* @throws IOException
*/
public String getSeverTime() throws URISyntaxException, ServletException,
IOException {
URIBuilder builder = new URIBuilder();
builder.setScheme(SCHEME)
.setHost(EnvironmentUtility.host)
.setPath("/gamification/api/tech/JsonRPC")
.setParameter(
"json",
"{" + "\"method\":\"" + "getCurrentServerTime" + "\","
+ "\"params\":["
+ "]" + "}")
.setParameter("app", GAMIFICATION_SERVICE_APPNAME);
URI httpsURI = builder.build();
HttpResponse gamificationServiceResponse = executeHttpsURI(httpsURI);
String serverTimeResponse = getHttpEntityContent(gamificationServiceResponse);
return serverTimeResponse;
}

private HttpResponse executeHttpsURI(URI httpsURI) throws IOException,
ClientProtocolException {
CloseableHttpClient httpClient = null;
httpClient = HttpClients.createDefault();
HttpPost post = createHttpPost(httpsURI);
HttpResponse httpResponse = httpClient.execute(post);
return httpResponse;
}

private HttpPost createHttpPost(URI httpsURI) {
HttpPost post = new HttpPost(httpsURI);
post.setHeader(
"Authorization",
getBase64Auth(EnvironmentUtility.technicalUserName,
EnvironmentUtility.technicalUserPassword));
if (EnvironmentUtility.proxy != null
&& !EnvironmentUtility.proxy.equalsIgnoreCase("")) {
setHttpHostProxy(post);
}
return post;
}


private String getHttpEntityContent(HttpResponse httpResponse)
throws ServletException, IOException {
StringBuffer buffer = new StringBuffer();
HttpEntity httpEntity = httpResponse.getEntity();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
httpEntity.getContent(), Charset.forName("UTF-8")));
String l;
while ((l = reader.readLine()) != null) {
buffer.append(l);
}
} catch (IOException e) {
String errorMessage = "error with POST data. could not be deserialized:"
+ e.getMessage();
throw new ServletException(errorMessage, e);
} finally {
EntityUtils.consume(httpEntity);
if (reader != null) {
reader.close();
}
}
return buffer.toString();
}

private static void setHttpHostProxy(HttpRequestBase request) {
HttpHost httpProxy = new HttpHost(EnvironmentUtility.proxy,
Integer.parseInt(EnvironmentUtility.port), "http");
RequestConfig config = RequestConfig.custom().setProxy(httpProxy)
.build();
request.setConfig(config);
}

private static String getBase64Auth(String login, String pass) {
String source = login + ":" + pass;
String ret = "Basic " + Base64.encodeBase64String(source.getBytes());
return ret;
}

public static void main(String arg []) throws Exception {

EnvironmentUtility.readEnvironmentValues();
GamificationProxy gamificationProxy= new GamificationProxy();

String playerProfileData = gamificationProxy.getPlayerProfileData("chris.s@mail.com");
System.out.print ("Profile details: \n"+playerProfileData);

String relativeLeaderBoardDetails=gamificationProxy.getRelativeLeaderBoardDetails("chris.s@mail.com");
System.out.print ("\nLeaderboard details: \n"+relativeLeaderBoardDetails);
}


}

 

The class GamificationProxy


The gamification service API is based on JSON-RPC. This is a simple protocol for calling Java methods remotely using a JSON-based serialization via HTTP POST. To execute these Java methods gamification service API endpoints will be used.


The gamification service API comprises two endpoints: Technical Endpoint and User Endpoint.


Technical endpoint is for backend integration. The class GamificationProxy has a method sendEvent which uses Technical Endpoint to send events to gamification service. The HTTP POST request looks like the following:


https://<gamification service host>/gamification/api/tech/JsonRPC?


json={"method":"handleEvent","params":[{"type":"issueCreated","playerid":"JIRA_USER@mail.com"} "data":{"relevance":"Major"}]}&app=JIRA


 
















Query parameter



Value



json



method handleEvent() and parameters (HCP gamification service will process events sent as parameters to this method)



app



JIRA (name of the app which contains the game mechanics as defined in the gamification workbench)



 


Test the class GamificationProxy:


The class GamificationProxy defines a method to test gamification service API.


 

public static void main(String arg[]) throws Exception{


    // arg[0] - player Id


    // arg[1] – priority of the issue created


    EnvironmentUtility.readEnvironmentValues();


    GamificationProxy proxy=new GamificationProxy();


String eventName="issueCreated";


    proxy.sendEvent(arg[0], arg[1], eventName); 


}


 

Run the class GamificationProxy to send an event of type issueCreated to gamification service.


 

1. Provide environment values and runtime arguments as described below.


    Right click on the node GamificationProxy.java select Run As ->Run configurations. Set environment variables


    host, user_name and user_password as shown below. Here host is the gamification service host and user_name ,


    user_ password are HANA Cloud Platform username and password.


 



Backend integration requires a technical user who has roles AppStandard and AppAdmin from gamification service assigned to him. These roles allow the user to send events to gamification service.When you enable gamification service in your HCP trial account, your HCP user (P-User/S-User) is assigned these roles. So you can use your user as the technical user. The technical user authenticates using HTTP Basic authentication to access technical Endpoint. So you need to provide HANA Cloud platform user name and password for the user.


Note:


Here host is the host of gamification service (example gamification- p123456789012trial.hanatrial .ondemand.com). You can get this from the Gamification Workbench URL as shown in the screenshot below




 

2. If you are developing behind corporate firewall, you need to set two additional environment variables http_proxy_host,http_proxy_port.


  Set these as shown in the snapshot below.



3. Set the arguments  JIRA_USER@mail.com , Major in the same run configuration as shown in the snapshot below. JIRA _USER @mail.com is the player Id and Major is the priority of the issue created.



4. Click on button Run to execute the GamificationProxy class. Upon execution, the event has been sent to the gamification service.


5. Login to gamification workbench by opening the webpage which you bookmarked in the Part1 of this blog post series.


6. Navigate to the tab PLAYERS. There you should see an entry with Logon Name JIRA_USER and Experience points with 4 points as shown in the             screenshot below



 

Note:


If you execute the class GamificationProxy again, Experience Points will be advanced by 2 points.


Perfect!! :smile: Now it’s time to integrate and test gamification service API with JIRA where you will send actual event to gamification service.


 

3. Integrate GamificationProxy with JIRA plugin


 

1. Add the following lines of code to the method onIssueEvent of IssueCreatedResolvedListner class

 

Priority priorityObject = issue.getPriorityObject();


String eventType="issueCreated";                     


if (priorityObject != null) {


        String priority = priorityObject.getName();


        GamificationProxy.sendEvent (username, priority, eventType);


}


 

The onIssueEvent() method should look like the following:

 

61 @EventListener


62  public void onIssueEvent(IssueEvent issueEvent) {


63        Long eventTypeId = issueEvent.getEventTypeId();


64        Issue issue = issueEvent.getIssue();


65        UserProfile remoteUser = manager.getRemoteUser();


66          String username= remoteUser.getUsername();


67              if (eventTypeId.equals(EventType.ISSUE_CREATED_ID)) {


68                     log.info(username+ "has created issue {} at {}.", issue.getKey(),


69                                  issue.getCreated());


70                      Priority priorityObject = issue.getPriorityObject();


71                      GamificationProxy gamificationProxy=new GamificationProxy();


72                      String eventType="issueCreated";                                                     


73                        if (priorityObject != null) {


74                                String priority = priorityObject.getName();


75                                  try {


76                                            gamificationProxy.sendEvent (username, priority, eventType);


77                                        } catch (Exception e) {


78                                              log.error ("Exception" + e.getMessage());


79                                      }


80                          }     


81                }


82                           


83        }


Organize imports by typing Ctrl+Shift+O.


 

2. Add the following line of code into the method afterPropertiesSet() of class IssueCreatedResolvedListener.


 


EnvironmentUtility.readEnvironmentValues();


 


The AfterPropertiesSet method should look like this:


 

41 @Override


42  public void afterPropertiesSet() throws Exception {


43        // register ourselves with the EventPublisher


44            eventPublisher.register(this);


45            EnvironmentUtility.readEnvironmentValues();


46    }


Organize imports by typing Ctrl+Shift+O.


 

4. Test Integration with JIRA

1. Set the environment variables from the Windows command prompt.


 

set user_name=<HANA Cloud Platform user name>


set user_password=<HANA Cloud Platform password>


set host = < gamification service host>


 

If you are running this application behind the firewall you also need to set http_proxy_host and http_proxy_port by using following commands if not then please ignore these.


 

set http_proxy_host= <Http proxy name>


set http_proxy_port=<Http port number>


 

2. Change directory to the folder jira-gamification-plugin and run the following command


 

atlas-run


 

3. Once JIRA has started successfully, open the URL printed in the message.



4. Log in with following username and password.


 


Username: admin


Password:  admin


 


5. Select the user management from menu bar as shown in the snapshot



6. Create user JIRA_USER on clicking Create User button as shown in the snapshot below.


 


7. Enter details for new user as shown below in ‘Create New User’ dialog and click on ‘Create’.


 


8. Log out from the JIRA and login with JIRA_USER@mail.com


 

9. Create an issue by clicking on ‘Create’ action as shown in the snapshot below.



10. Enter details for the new issue as shown below in the Create Issue Dialog and click on ‘Create



11. Verify that the experience points were successfully advanced. Repeat the steps 5-7 of Test the class Gamification Proxy as described earlier.


12. Stop the JIRA server by typing Ctrl+C in the command prompt


Great Job!! :smile:


Part 3 is complete now. With this you have reached the half way point of this blog post series. :smile: :smile:


Now it’s time to show user’s achievement (Experience points) in User Profile page in JIRA. We do that next in Part 4



5 Comments