This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Product Initiation in Bugzilla

The first use case in the Bugzilla business scenario is product initiation. This page describes the relevant tasks and the operations you use in the Bugzilla connector and the other ESB connectors. It contains the following sections:

 

Overview

The flow for product initiation is illustrated in the following diagram. The ESB connectors for TSheets, Zoho Books and Mandrill will be used to connect to each service. 

Creating projects

  1. Using the createProject operation, create a new project in the Zoho Books API and create a project (Job Code) in the TSheets API using the addJobCodes operation.

Zoho Books operations
TSheets operations
Samples
Sample Proxy for creating projects in TSheets API (as job codes) and Zoho Books API
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="bugzilla_createProjects" transports="https,http" statistics="disable"
   trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <!--Zohobooks Properties -->
         <property name="zohobooks.apiUrl" value="https://books.zoho.com" />
         <property name="zohobooks.authToken" expression="json-eval($.zohobooksAuthToken)" />
         <property name="zohobooks.organizationId" expression="json-eval($.zohobooksOrganizationId)" />
         <!--Tsheets Properties -->
         <property name="tsheets.apiUrl" expression="json-eval($.tsheetsApiUrl)" />
         <property name="tsheets.accessToken" expression="json-eval($.tsheetsAccessToken)" />
         <!--Common Properties -->
         <property name="common.projectsDetails" expression="json-eval($.projectsDetails)" />
         <property name="responseString" value="" scope="operation" />
         <property name="projectCount" expression="count(//projectsDetails)" scope="operation" />
         <property name="projectIndex" value="0" scope="operation" />
         <!--FOR EACH Project : BEGIN -->
         <iterate continueParent="false" id="projects" expression="//projectsDetails" sequential="true">
            <target>
               <sequence>
                  <property name="messageType" value="application/json" scope="axis2" />
                  <property name="projectName" expression="json-eval($.projectsDetails.projectName)" />
                  <property name="customerId" expression="json-eval($.projectsDetails.customerId)" />
                  <property name="projectNameObj" expression="fn:concat('projectName:',get-property('projectName'))" />
                  <!-- Create Project in zohobooks -->
                  <zohobooks.init>
                     <authToken>{$ctx:zohobooks.authToken}</authToken>
                     <apiUrl>{$ctx:zohobooks.apiUrl}</apiUrl>
                     <organizationId>{$ctx:zohobooks.organizationId}</organizationId>
                  </zohobooks.init>
                  <zohobooks.createProject>
                     <customerId>{$ctx:customerId}</customerId>
                     <billingType>based_on_task_hours</billingType>
                     <projectName>{$ctx:projectName}</projectName>
                  </zohobooks.createProject>
                  <header name="Transfer-Encoding" scope="transport" action="remove" />
                  <header name="Content-Encoding" scope="transport" action="remove" />
                  <header name="Content-Length" scope="transport" action="remove" />
                  <filter source="$axis2:HTTP_SC" regex="201">
                     <then>
                        <property name="zohobooks.projectId" expression="json-eval($.project.project_id)" />
                        <property name="projectIdObject"
                           expression="fn:concat(get-property('projectNameObj'),',projectId:',get-property('zohobooks.projectId'))" />
                        <property name="message" value="Project has been created successfully." />
                        <property name="status" value="success" />
                     </then>
                     <else>
                        <property name="projectIdObject" expression="get-property('projectNameObj')" />
                        <property name="status" value="error" />
                        <property name="message" expression="json-eval($.)" />
                     </else>
                  </filter>
                  <call-template target="responseHandlerTemplate">
                     <with-param name="id" value="{$ctx:projectIdObject}" />
                     <with-param name="activity" value="zohobooks_createProject" />
                     <with-param name="status" value="{$ctx:status}" />
                     <with-param name="message" value="{$ctx:message}" />
                  </call-template>                  
                  <!-- Create jobCode Object for Tsheets -->
                  <script language="js">
                     <![CDATA[                     
                        var projectName=mc.getProperty("projectName");
                        var jobCodeObj = {};   
                        jobCodeObj.name  = projectName;
                        mc.setPayloadJSON(jobCodeObj);
                       ]]>
                  </script>                  
                  <property name="tsheets.jobCodes" expression="json-eval($.)" />
                  <!-- Create Project(Jobcode) in Tsheets -->
                  <tsheets.init>
                     <accessToken>{$ctx:tsheets.accessToken}</accessToken>
                     <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
                  </tsheets.init>
                  <tsheets.addJobCodes>
                     <jobCodes>{$ctx:tsheets.jobCodes}</jobCodes>
                  </tsheets.addJobCodes>
                  <property name="tsheets.statusCode" expression="json-eval($.results.jobcodes.1._status_code)" />
                  <switch source="get-property('tsheets.statusCode')">
                     <case regex="200">
                        <property name="tsheets.jobCodeId" expression="json-eval($.results.jobcodes.1.id)" />
                        <property name="jobCodeIdObject"
                           expression="fn:concat(get-property('projectNameObj'),',jobCodeId:',get-property('tsheets.jobCodeId'))" />
                        <property name="message" value="Job code has been created successfully." />
                        <property name="status" value="success" />
                     </case>
                     <case regex="202">
                        <property name="tsheets.jobCodeId" expression="json-eval($.results.jobcodes.1.id)" />
                        <property name="jobCodeIdObject"
                           expression="fn:concat(get-property('projectNameObj'),',jobCodeId:',get-property('tsheets.jobCodeId'))" />
                        <property name="message" value="This job code already exists." />
                        <property name="status" value="skipped" />
                     </case>
                     <default>
                        <property name="jobCodeIdObject" expression="get-property('projectNameObj')" />
                        <property name="status" value="error" />
                        <property name="message" expression="json-eval($.)" />
                     </default>
                  </switch>
                  <call-template target="responseHandlerTemplate">
                     <with-param name="id" value="{$ctx:jobCodeIdObject}" />
                     <with-param name="activity" value="tsheets_createJobCode" />
                     <with-param name="status" value="{$ctx:status}" />
                     <with-param name="message" value="{$ctx:message}" />
                  </call-template>
                  <property name="projectIndex" expression="get-property('operation','projectIndex') + 1"
                     scope="operation" />
                  <filter xpath="get-property('operation','projectCount') = get-property('operation','projectIndex') ">
                     <then>
                        <loopback />
                     </then>
                  </filter>
               </sequence>
            </target>
         </iterate>
         <!--FOR EACH Project : END -->
      </inSequence>
      <outSequence>      
         <property name="messageType" value="application/json" scope="axis2" />
         <payloadFactory media-type="json">
            <format>
               {
               "Response":{
                     "process":"bugzilla_createProjects",
                     "activityResponse":[$1]
                  }
               }
            </format>
            <args>
               <arg expression="get-property('operation', 'responseString')" />
            </args>
         </payloadFactory>
         <send />
      </outSequence>
   </target>
   <description />
</proxy>  
Sample Request for creating projects in TSheets API (as job codes) and Zoho Books API
{
   "tsheetsApiUrl": "https://wso2yas.tsheets.com",
   "tsheetsAccessToken": "S.1__9f247e6537bcc83348cfdadaafdd741e9956b453",
   "zohobooksAuthToken": "c11a87210138ff2e0bf6d049abd3c27e",
   "zohobooksOrganizationId": "51450345",
   "projectsDetails":    [
            {
         "projectName": "Cloud Connector Development",
         "customerId": "135439000000039016"
      },
            {
         "projectName": "Support",
         "customerId": "135439000000039016"
      }
   ]
}

Note

 The following are the parameter descriptions:

  • projectsDetails: An array of JSON objects which has the project name and the Zoho Books customer ID.

Retrieving projects and creating products, components and users

  1. Retrieve selected projects and its relevant sub modules from the TSheets API using the listJobCodes operation and create the projects as 'Products' and sub modules as 'Components' in the Bugzilla API using the createProduct and createComponent operations respectively.

  2. Also retrieve users from the Zoho Books API using the listUsers operation and create users for the components in the Zoho Books API if the user does not exist using the createUser operation and assign users to the project using the assignUsersToProject operation.
Zoho Books operations
TSheets operations
Bugzilla operations
Samples
Sample Proxy for retrieving selected projects (job codes) and its relevant sub modules (child job codes) from the TSheets API and creating the projects as ‘Products’ and sub modules as ‘Components’ in the Bugzilla API. Creating users for the components in the ZohoBooks API and assigning users to the project which was created
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="bugzilla_createProductsAndComponents" transports="https http"
   startOnLoad="true" trace="disable">
   <description />
   <target>
      <inSequence>
         <!--Tsheets Properties -->
         <property name="tsheets.apiUrl" expression="json-eval($.tsheetsApiUrl)" />
         <property name="tsheets.accessToken" expression="json-eval($.tsheetsAccessToken)" />
         <!--Bugzilla Properties -->
         <property name="bugzilla.apiUrl" expression="json-eval($.bugzillaApiUrl)" />
         <property name="bugzilla.apiKey" expression="json-eval($.bugzillaApiKey)" />
         <!--Common Properties -->
         <property name="responseString" value="" scope="operation" />
         <property name="jobCodeCount" expression="count(//jobCodeDetails)" scope="operation" />
         <property name="jobCodeIndex" value="0" scope="operation" />
         <property name="componentsCount" value="0" scope="operation" />
         <property name="componentsIndex" value="0" scope="operation" />
         <!--ZohoBooks Properties -->
         <property name="zohobooks.apiUrl" value="https://books.zoho.com" />
         <property name="zohobooks.authToken" expression="json-eval($.zohobooksAuthToken)" />
         <property name="zohobooks.organizationId" expression="json-eval($.zohobooksOrganizationId)" />
         <!--FOR EACH JobCode Details : BEGIN -->
         <iterate continueParent="true" id="jobCodeDetails" expression="//jobCodeDetails" sequential="true">
            <target>
               <sequence>
                  <property name="messageType" value="application/json" scope="axis2" />
                  <property name="tsheets.parentJobCode" expression="json-eval($.jobCodeDetails.parentJobCode)" />
                  <property name="zohobooks.projectId" expression="json-eval($.jobCodeDetails.zohobooksProjectId)" />
                  <property name="bugzilla.productDesc" expression="json-eval($.jobCodeDetails.description)" />
                  <property name="bugzilla.productVersion" expression="json-eval($.jobCodeDetails.version)" />
                  <property name="bugzilla.defaultAssignee" expression="json-eval($.jobCodeDetails.defaultAssignee)" />
                  <property name="tsheets.childJobCodes" expression="json-eval($.jobCodeDetails.childJobCodes)" />
                  <property name="parentJobCodeObj" expression="fn:concat('jobCode:',get-property('tsheets.parentJobCode'))" />
                  <!-- Retrieve Tsheets child jobcodes by parent jobcode id -->
                  <tsheets.init>
                     <accessToken>{$ctx:tsheets.accessToken}</accessToken>
                     <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
                  </tsheets.init>
                  <tsheets.listJobCodes>
                     <parentIds>{$ctx:tsheets.parentJobCode}</parentIds>
                  </tsheets.listJobCodes>
                  <header name="Transfer-Encoding" scope="transport" action="remove" />
                  <header name="Content-Encoding" scope="transport" action="remove" />
                  <header name="Content-Length" scope="transport" action="remove" />
                  <property name="tsheets.parentJobCodeName" expression="json-eval($.supplemental_data.jobcodes.*.name)" />
                  <!-- Create component object for bugzilla -->
                  <script language="js">
                   <![CDATA[
                     var parentJobCodeName=''+eval("(" + mc.getProperty("tsheets.parentJobCodeName") + ")");
                     var childJobCodes=mc.getProperty("tsheets.childJobCodes");					 
                     mc.setProperty("tsheets.parentJobCodeName",parentJobCodeName);
					 if(childJobCodes.charCodeAt(0) != '91' && childJobCodes.charCodeAt(childJobCodes.length-1) != '93'){
						childJobCodes = '['+childJobCodes+']';
					 }
					 childJobCodes=eval("(" + childJobCodes + ")");
                     payload = mc.getPayloadJSON();
                     var jobCodes = payload.results.jobcodes;
                     var components = [];
                     for (var i = 0; i < childJobCodes.length ; i++) {
						var childJobCode=childJobCodes[i];
                        var jobCodeId = childJobCode.childJobCodeId;
						var email=childJobCode.defaultAsigneeEmail;
						var userName=childJobCode.defaultAssigneeName;
						var billableRate=childJobCode.billableRate;                  
                        var component = {};
                        var jobCode = jobCodes[jobCodeId];
                        component.childJobCode = ''+jobCodeId;
                        //assign component name, description and product name only if child jobcode is valid.
                        if(jobCode){
                           component.name = jobCode['name'];
                           component.description = parentJobCodeName +' : '+ jobCode['name'];
                           component.product = parentJobCodeName;
                           component.userName=userName;
                           component.email=email;
						   if(billableRate!=null && billableRate!=""){
						      component.billableRate=billableRate;
						   }
                        }
                        components.push(component);
                     }
                     mc.setPayloadJSON(components);
                      ]]>
                  </script>
                  <property name="tsheets.componentsArray" expression="json-eval($.)" />
                  <!-- Bugzilla create Product -->
                  <bugzilla.init>
                     <apiUrl>{$ctx:bugzilla.apiUrl}</apiUrl>
                     <apiKey>{$ctx:bugzilla.apiKey}</apiKey>
                  </bugzilla.init>
                  <bugzilla.createProduct>
                     <name>{$ctx:tsheets.parentJobCodeName}</name>
                     <description>{$ctx:bugzilla.productDesc}</description>
                     <version>{$ctx:bugzilla.productVersion}</version>
                  </bugzilla.createProduct>
                  <filter source="$axis2:HTTP_SC" regex="201">
                     <then>
                        <property name="bugzilla.productId" expression="json-eval($.id)" />
                        <property name="productIdObject"
                           expression="fn:concat(get-property('parentJobCodeObj'),',productId:',get-property('bugzilla.productId'))" />
                        <property name="message"
                           expression="fn:concat('Product ',get-property('tsheets.parentJobCodeName'), ' has been created successfully.')" />
                        <property name="status" value="success" />
                     </then>
                     <else>
                        <property name="productIdObject" expression="get-property('parentJobCodeObj')" />
                        <property name="status" value="error" />
                        <property name="message" expression="json-eval($.)" />
                     </else>
                  </filter>
                  <call-template target="responseHandlerTemplate">
                     <with-param name="id" value="{$ctx:productIdObject}" />
                     <with-param name="activity" value="bugzilla_createProducts" />
                     <with-param name="status" value="{$ctx:status}" />
                     <with-param name="message" value="{$ctx:message}" />
                  </call-template>
                  <property name="jobCodeIndex" expression="get-property('operation','jobCodeIndex') + 1"
                     scope="operation" />
                  <!-- Add tsheets.componentsArray to components payload to iterate and create components -->
                  <payloadFactory media-type="json">
                     <format>
                        {
                           "components":$1
                        }
                     </format>
                     <args>
                        <arg evaluator="xml" expression="get-property('tsheets.componentsArray')" />
                     </args>
                  </payloadFactory>
                  <property name="componentsCount" expression="get-property('operation','componentsCount') + count(//components)"
                     scope="operation" />
                  <!--FOR EACH Components : BEGIN -->
                  <iterate continueParent="true" id="components" expression="//components" sequential="true">
                     <target>
                        <sequence>
                           <property name="tsheets.componentName" expression="json-eval($.components.name)" />
                           <property name="tsheets.product" expression="json-eval($.components.product)" />
                           <property name="tsheets.componentDescription" expression="json-eval($.components.description)" />
                           <property name="tsheets.childJobCode" expression="json-eval($.components.childJobCode)" />
						   <property name="tsheets.billableRate" expression="json-eval($.components.billableRate)" />                           
                           <property name="user.name" expression="json-eval($.components.userName)"/>
                           <property name="user.email" expression="json-eval($.components.email)"/>                           
                           <property name="childJobCodeObject"
                              expression="fn:concat(get-property('parentJobCodeObj'),',childJobCode:',get-property('tsheets.childJobCode'))" />
                           <!-- Filter for valid child jobcodes -->
                           <filter source="boolean(get-property('tsheets.componentName'))" regex="false">
                              <then>
                                 <call-template target="responseHandlerTemplate">
                                    <with-param name="id" value="{$ctx:childJobCodeObject}" />
                                    <with-param name="activity" value="bugzilla_createComponents" />
                                    <with-param name="status" value="skipped" />
                                    <with-param name="message" value="Invalid Child Jobcode." />
                                 </call-template>
                              </then>
                              <else>
                                 <!-- Create Bugzilla Components -->
                                 <bugzilla.init>
                                    <apiUrl>{$ctx:bugzilla.apiUrl}</apiUrl>
                                    <apiKey>{$ctx:bugzilla.apiKey}</apiKey>
                                 </bugzilla.init>
                                 <bugzilla.createComponent>
                                    <name>{$ctx:tsheets.componentName}</name>
                                    <product>{$ctx:tsheets.product}</product>
                                    <description>{$ctx:tsheets.componentDescription}</description>
                                    <defaultAssignee>{$ctx:bugzilla.defaultAssignee}</defaultAssignee>
                                 </bugzilla.createComponent>
                                 <filter source="$axis2:HTTP_SC" regex="201">
                                    <then>                                       
                                       <property name="isComponentCreated" value="true"/>                                       
                                       <property name="bugzilla.componentId" expression="json-eval($.id)" />
                                       <property name="componentIdObject"
                                          expression="fn:concat(get-property('childJobCodeObject'),',componentId:',get-property('bugzilla.componentId'))" />
                                       <property name="message"
                                          expression="fn:concat('Component ',get-property('tsheets.componentName'), ' has been created successfully.')" />
                                       <property name="status" value="success" />
                                       <call-template target="responseHandlerTemplate">
                                          <with-param name="id" value="{$ctx:componentIdObject}" />
                                          <with-param name="activity" value="bugzilla_createComponent" />
                                          <with-param name="status" value="{$ctx:status}" />
                                          <with-param name="message" value="{$ctx:message}" />
                                       </call-template>									   
									   <!-- Updating TSheets job code to set the billable rate -->
									   <payloadFactory media-type="json">
									      <format>
										     {
											    "data":[
												   {
												      "id":$1,
												      "billable_rate":"$2"
												   }
												]
											 }
										  </format>
									      <args>
										     <arg expression="get-property('tsheets.childJobCode')" />
											 <arg expression="get-property('tsheets.billableRate')" />
									      </args>
								       </payloadFactory>									   
									   <property name="Authorization" expression="fn:concat('Bearer ', get-property('tsheets.accessToken'))" scope="transport" type="STRING" />
									   <property name="uri.var.location" expression="fn:concat(get-property('tsheets.apiUrl'),'/api/v1/jobcodes')"/>
									   <call>
									      <endpoint>
									         <http method="put" uri-template="{uri.var.location}" />
									      </endpoint>
										</call>
                                       <!-- List users in zohobooks -->
                                       <zohobooks.init>
                                          <authToken>{$ctx:zohobooks.authToken}</authToken>
                                          <apiUrl>{$ctx:zohobooks.apiUrl}</apiUrl>
                                          <organizationId>{$ctx:zohobooks.organizationId}</organizationId>
                                       </zohobooks.init>
                                       <zohobooks.listUsers />
                                       <!-- Preserve listUsers response for future use -->
                                       <property name="zohobooks.users" expression="json-eval($.)" scope="operation" />
                                       <!-- Retreve zohobooks listUser response from operation scope -->
                                       <property name="zohobooks.users" expression="get-property('operation','zohobooks.users')" />
                                       <script language="js">
                                       <![CDATA[                           
                                         //Create JSON object form String
                                          payload = eval("(" + mc.getProperty("zohobooks.users") + ")");
                                          var users = payload.users;
                                          var userEmail = mc.getProperty('user.email');
                                           for(var key in users){
                                             var user = users[key];
                                             var email = user.email;
                                             if(email == userEmail){
                                               mc.setProperty('zohobooks.userId',user.user_id);
                                               break;
                                             }                                            
                                          }                                       
                                       ]]>
                                       </script>                                       
                                       <!-- Create zohobooks user if not exsist -->
                                       <filter source="boolean(get-property('zohobooks.userId'))" regex="false">
                                          <then>
                                             <zohobooks.init>
                                                <authToken>{$ctx:zohobooks.authToken}</authToken>
                                                <apiUrl>{$ctx:zohobooks.apiUrl}</apiUrl>
                                                <organizationId>{$ctx:zohobooks.organizationId}</organizationId>
                                             </zohobooks.init>
                                             <zohobooks.createUser>
                                                <email>{$ctx:user.email}</email>
                                                <name>{$ctx:user.name}</name>
                                                <userRole>timesheetstaff</userRole>
                                             </zohobooks.createUser>
                                             <header name="Transfer-Encoding" scope="transport" action="remove" />
                                             <header name="Content-Encoding" scope="transport" action="remove" />
                                             <header name="Content-Length" scope="transport" action="remove" />
                                             <filter source="$axis2:HTTP_SC" regex="201">
                                                <then>
                                                   <property name="zohobooks.userId" expression="json-eval($.user.user_id)" />
                                                   <property name="userIdObject"
                                                      expression="fn:concat('userId:',get-property('zohobooks.userId'))" />
                                                   <property name="message"
                                                      expression="fn:concat('User ',get-property('user.name'), ' has been created successfully.')" />
                                                   <property name="status" value="success" />
                                                </then>
                                                <else>
                                                   <property name="userIdObject"
                                                      expression="fn:concat('email:',get-property('user.email'))" />
                                                   <property name="status" value="error" />
                                                   <property name="message" expression="json-eval($.)" />
                                                </else>
                                             </filter>
                                             <call-template target="responseHandlerTemplate">
                                                <with-param name="id" value="{$ctx:userIdObject}" />
                                                <with-param name="activity" value="zohobooks_createUser" />
                                                <with-param name="status" value="{$ctx:status}" />
                                                <with-param name="message" value="{$ctx:message}" />
                                             </call-template>
                                          </then>
                                       </filter>
                                       <filter source="boolean(get-property('zohobooks.userId'))" regex="true">
                                          <then>
                                             <property name="uri.var.userAssignemnt"
                                                expression="fn:concat(get-property('zohobooks.apiUrl'),'/api/v3/projects/',get-property('zohobooks.projectId'),'/users/',get-property('zohobooks.userId'),'?authtoken=',get-property('zohobooks.authToken'),'&amp;organization_id=',get-property('zohobooks.organizationId'))" />
                                             <!-- Get zohobooks user assignment details -->
                                             <call>
                                                <endpoint>
                                                   <http method="get" uri-template="{uri.var.userAssignemnt}" />
                                                </endpoint>
                                             </call>
                                             <!-- Add Project assignments if not assigned -->
                                             <filter source="$axis2:HTTP_SC" regex="404">
                                                <then>
                                                   <script language="js">
                                                   <![CDATA[
                                                      var userId = mc.getProperty('zohobooks.userId');
                                                      var users = [];
                                                      var user ={};
                                                      user.user_id = userId;
                                                      users.push(user);
                                                      mc.setPayloadJSON(users); 
                                          
                                                   ]]>
                                                   </script>
                                                   <property name="zohobooks.users" expression="json-eval($.)" />
                                                   <!-- Assign user to zohobooks project -->
                                                   <zohobooks.init>
                                                      <authToken>{$ctx:zohobooks.authToken}</authToken>
                                                      <apiUrl>{$ctx:zohobooks.apiUrl}</apiUrl>
                                                      <organizationId>{$ctx:zohobooks.organizationId}</organizationId>
                                                   </zohobooks.init>
                                                   <zohobooks.assignUsersToProject>
                                                      <users>{$ctx:zohobooks.users}</users>
                                                      <projectId>{$ctx:zohobooks.projectId}</projectId>
                                                   </zohobooks.assignUsersToProject>
                                                   <filter source="$axis2:HTTP_SC" regex="201">
                                                      <then>
                                                         <property name="userIdObject"
                                                            expression="fn:concat('userId:',get-property('zohobooks.userId'))" />
                                                         <property name="status" value="success" />
                                                         <property name="message"
                                                            expression="fn:concat('User ',get-property('user.name'), ' has been added successfully.')" />
                                                      </then>
                                                      <else>
                                                         <property name="userIdObject"
                                                            expression="fn:concat('email:',get-property('user.email'))" />
                                                         <property name="status" value="error" />
                                                         <property name="message" expression="json-eval($.)" />
                                                      </else>
                                                   </filter>
                                                   <call-template target="responseHandlerTemplate">
                                                      <with-param name="id" value="{$ctx:userIdObject}" />
                                                      <with-param name="activity" value="zohobooks_assignUserToProject" />
                                                      <with-param name="status" value="{$ctx:status}" />
                                                      <with-param name="message" value="{$ctx:message}" />
                                                   </call-template>
                                                </then>
                                             </filter>
                                          </then>
                                       </filter>
                                    </then>
                                 </filter>
                              </else>
                           </filter>
                           <property name="componentsIndex" expression="get-property('operation','componentsIndex') + 1"
                              scope="operation" />
                           <filter
                              xpath="(get-property('operation','jobCodeCount') = get-property('operation','jobCodeIndex')) and  (get-property('operation','componentsCount') = get-property('operation','componentsIndex'))">
                              <then>
                                 <loopback />
                              </then>
                           </filter>
                        </sequence>
                     </target>
                  </iterate>
                  <!--FOR EACH Components : END -->
               </sequence>
            </target>
         </iterate>
         <!--FOR EACH JobCode Details : END -->
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" />
         <payloadFactory media-type="json">
            <format>
               {
                  "Response":{
                     "process":"bugzilla_createProjectsAndComponents",
                     "activityResponse":[$1]
                  }
               }
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('operation', 'responseString')" />
            </args>
         </payloadFactory>
         <send />
      </outSequence>
   </target>
</proxy>
Sample Request for retrieving selected projects (job codes) and its relevant sub modules (child job codes) from the TSheets API and creating the projects as ‘Products’ and sub modules as ‘Components’ in the Bugzilla API. Creating users for the components in the ZohoBooks API and assigning users to the project which was created
{
   "tsheetsApiUrl": "https://bugzilla.tsheets.com",
   "tsheetsAccessToken": "S.1__5702cdc8639ffa44e9d935d1736d4979598a15e9",
   "bugzillaApiUrl": "http://172.22.217.15/bugiya/rest.cgi",
   "bugzillaApiKey": "jgvuN3V9aWqMLWFo4gs2UkezswIUCn9qezgOmibG",
   "zohobooksAuthToken": "c11a87210138ff2e0bf6d049abd3c27e",
   "zohobooksOrganizationId": "52064035",
   "jobCodeDetails":    [
            {
         "parentJobCode": "32686958",
         "zohobooksProjectId":"134941000000067005",
         "description":"Wso2 Connector Development",
         "version":"1.0.0",
         "defaultAssignee":"vr@gmail.com",
		 "childJobCodes":[
			{
				"childJobCodeId": "32686960",
				"defaultAsigneeEmail":"johnnie@rtw.com",
				"defaultAssigneeName":"Paul Walker",
				"billableRate":"500"
				
			},
			{
				"childJobCodeId": "32686962",
				"defaultAsigneeEmail":"leone@rtw.com",
				"defaultAssigneeName":"Leonardo Luke",
				"billableRate":"250"
			}			
		]
      }
   ]   
}

Note

 The following are the parameter descriptions:

  • jobCodeDetails: An array of JSON objects which has the following parameters:
    • parentJobCode: ID of the TSheets job code which was created as a project in case-001.
    • zohobooksProjectId: ID of the Zoho Books project which created as a project in case-001.
    • description: Description of the project.
    • version: Product version of Bugzilla.
    • defaultAssignee: E-mail address of the Bugzilla user to assign to product as default assignee.
    • childJobCodes: An array of JSON objects  which has the following data relevant to the component:
      • childJobCodeId: ID of the TSheets job code (child job code) which was created under Project(parent job code) as Component.
      • defaultAsigneeEmail: E-mail address of the Zoho Books user to assign to the component.
      • defaultAssigneeName: Name of the Zoho Books user to create, if it does not exist.
      • billableRate: Billable rate of each component.

Retrieving project members, creating users and notifying users

  1. Retrieve project members from the TSheets API using the listJobCodeAssignments operation and search for these users using the searchUsers operation and if the project members do not exist, create them as users in the Bugzilla API using the createUser operation.

  2. Notify the users with the relevant credentials and other information (e.g. Bugzilla URL, Username/Login ID and Password) using the sendMessage operation in the Mandrill API.
Mandrill operations
TSheets operations
Bugzilla operations

Prerequisites

 When retrieving users which are created in TSheets to Bugzilla, the respective TSheets user must have an e-mail address.

Samples
Sample Proxy for retrieving project members from the TSheets API and if they do not exist in Bugzilla, creating them as users in the Bugzilla API and notifying the users with the relevant credentials and other information (Eg: BugZilla URL, Username/Login ID, and Password) using the Mandrill API
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="bugzilla_createUsersForProjects" transports="https http"
   startOnLoad="true" trace="disable">
   <description />
   <target>
      <inSequence>
         <!--Tsheets Properties -->
         <property name="tsheets.apiUrl" expression="json-eval($.tsheetsApiUrl)" />
         <property name="tsheets.accessToken" expression="json-eval($.tsheetsAccessToken)" />
         <property name="tsheets.jobCode" expression="json-eval($.jobCodeId)" />
         <!--Bugzilla Properties -->
         <property name="bugzilla.apiUrl" expression="json-eval($.bugzillaApiUrl)" />
         <property name="bugzilla.apiKey" expression="json-eval($.bugzillaApiKey)" />
         <property name="bugzilla.defaultPassword" expression="json-eval($.defaultPassword)" />
         <property name="bugzilla.bugzillaLoginURL" expression="json-eval($.bugzillaLoginURL)" />
         <!--Mandrill Properties -->
         <property name="mandrill.apiUrl" value="https://mandrillapp.com" />
         <property name="mandrill.apiKey" expression="json-eval($.mandrillApiKey)" />
         <property name="mandrill.fromEmail" expression="json-eval($.fromEmail)" />
         <property name="mandrill.fromName" expression="json-eval($.fromName)" />
         <!--Common Properties -->
         <property name="responseString" value="" scope="operation" />

         <!-- Retrieve jobcode assignments by parent jobcodeId -->
         <tsheets.init>
            <accessToken>{$ctx:tsheets.accessToken}</accessToken>
            <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
         </tsheets.init>
         <tsheets.listJobCodeAssignments>
            <jobcodeParentId>{$ctx:tsheets.jobCode}</jobcodeParentId>
         </tsheets.listJobCodeAssignments>
         <property name="tsheets.jobCodeAssignments" expression="json-eval($.supplemental_data)" />
         <!-- Filter to check available jobcode assignments -->
         <filter source="boolean(get-property('tsheets.jobCodeAssignments'))" regex="false">
            <then>
               <property name="id" value="{}" />
               <call-template target="responseHandlerTemplate">
                  <with-param name="id" value="{$ctx:id}" />
                  <with-param name="status" value="skipped" />
                  <with-param name="message" value="There are no Job Assignments to process." />
               </call-template>
               <loopback />
            </then>
            <else>
               <!-- Create array of user details object to process -->
               <script language="js">
                  <![CDATA[
                        
                  	payload = mc.getPayloadJSON();
                  	var assignedUsers = payload.supplemental_data.users;
                  	var users = [];
                      for(var key in assignedUsers){
                          userObj = assignedUsers[key];
                          var user = {};
                          user.firstName = userObj.first_name;
                          user.lastName = userObj.last_name;
                          user.email = userObj.email;
                          user.userName = userObj.username;
                          users.push(user);
                      }
                      payload = {};
                      payload.users = users ;
                      mc.setPayloadJSON(payload);                        
                  ]]>
               </script>
               <property name="userCount" expression="count(//users)" scope="operation" />
               <property name="userIndex" value="0" scope="operation" />
               <!--FOR EACH User Details : BEGIN -->
               <iterate continueParent="true" id="users" expression="//users" sequential="true">
                  <target>
                     <sequence>
                        <property name="messageType" value="application/json" scope="axis2" />
                        <property name="tsheets.firstName" expression="json-eval($.users.firstName)" />
                        <property name="tsheets.lastName" expression="json-eval($.users.lastName)" />
                        <property name="tsheets.email" expression="json-eval($.users.email)" />
                        <property name="tsheets.userName" expression="json-eval($.users.userName)" />
                        <property name="bugzilla.fullName"
                           expression="fn:concat(get-property('tsheets.firstName'),' ',get-property('tsheets.lastName'))" />
                        <!-- Search Bugzilla users from email -->
                        <bugzilla.init>
                           <apiUrl>{$ctx:bugzilla.apiUrl}</apiUrl>
                           <apiKey>{$ctx:bugzilla.apiKey}</apiKey>
                        </bugzilla.init>
                        <bugzilla.searchUsers>
                           <names>{$ctx:tsheets.email}</names>
                        </bugzilla.searchUsers>
                        <!-- check user in Bugzilla and create if not exsist -->
                        <property name="bugzilla.users" expression="json-eval($.users)" />
                        <filter source="boolean(get-property('bugzilla.users'))" regex="false">
                           <then>
                              <!-- Create Bugzilla user -->
                              <bugzilla.init>
                                 <apiUrl>{$ctx:bugzilla.apiUrl}</apiUrl>
                                 <apiKey>{$ctx:bugzilla.apiKey}</apiKey>
                              </bugzilla.init>
                              <bugzilla.createUser>
                                 <email>{$ctx:tsheets.email}</email>
                                 <fullName>{$ctx:bugzilla.fullName}</fullName>
                                 <password>{$ctx:bugzilla.defaultPassword}</password>
                              </bugzilla.createUser>
                              <filter source="$axis2:HTTP_SC" regex="201">
                                 <then>
                                    <property name="bugzilla.userId" expression="json-eval($.id)" />
                                    <property name="userIdObject" expression="fn:concat('userId:',get-property('bugzilla.userId'))" />
                                    <property name="message"
                                       expression="fn:concat('User ',get-property('bugzilla.fullName'), ' has been created successfully.')" />
                                    <property name="status" value="success" />
                                 </then>
                                 <else>
                                    <property name="userIdObject" expression="fn:concat('email:',get-property('tsheets.email'))" />
                                    <property name="status" value="error" />
                                    <property name="message" expression="json-eval($.)" />
                                 </else>
                              </filter>
                              <call-template target="responseHandlerTemplate">
                                 <with-param name="id" value="{$ctx:userIdObject}" />
                                 <with-param name="activity" value="bugzilla_createUsers" />
                                 <with-param name="status" value="{$ctx:status}" />
                                 <with-param name="message" value="{$ctx:message}" />
                              </call-template>
                           </then>
                        </filter>
                        <!-- Send notification to user if Bugzilla account is being created -->
                        <filter source="boolean(get-property('bugzilla.userId'))" regex="true">
                           <then>
                              <script language="js">
                                 <![CDATA[
                                    //Create Email in HTML format      
                                    var greetingLine= 'Dear ' + mc.getProperty('tsheets.firstName') + ' , <br/><br/>';
                                    var message = 'Bugzilla account has been created for you successfully. Following are the details of your account.<br/><br/>';
                                    var url = '<li>Bugzilla account URL: '+mc.getProperty('bugzilla.bugzillaLoginURL')+'</li>';
                                    var userName = '<li>Username: '+mc.getProperty('tsheets.email')+'</li>';
                                    var password = '<li>Password: '+mc.getProperty('bugzilla.defaultPassword')+'</li>';
                                    var signature = '</br>Regards, </br> Bugzilla Admin';
                                    message =greetingLine +  message + '<ul>'+ url + userName + password + '</ul>'+ signature;                                    
                                    mc.setProperty('mandril.htmlText',message);
                                    var toArray = [];
                                    var toObject = {};
                                    toObject.email = mc.getProperty('tsheets.email');
                                    toObject.name = mc.getProperty('bugzilla.fullName');
                                    toObject.type = 'to';
                                    toArray.push(toObject);                                    
                                    mc.setPayloadJSON(toArray);
                                 ]]>
                              </script>
                              <property name="mandrill.toArray" expression="json-eval($.)" />
                              <!-- Send notification using Mandrill -->
                              <mandrill.init>
                                 <apiKey>{$ctx:mandrill.apiKey}</apiKey>
                                 <apiUrl>{$ctx:mandrill.apiUrl}</apiUrl>
                                 <format>json</format>
                              </mandrill.init>
                              <mandrill.sendMessage>
                                 <html>{$ctx:mandril.htmlText}</html>
                                 <subject>Bugzilla account has been created</subject>
                                 <fromEmail>{$ctx:mandrill.fromEmail}</fromEmail>
                                 <fromName>{$ctx:mandrill.fromName}</fromName>
                                 <to>{$ctx:mandrill.toArray}</to>
                              </mandrill.sendMessage>
                              <property name="mandrill.status" expression="json-eval($..status[0])" />
                              <filter xpath="get-property('mandrill.status') = 'sent'">
                                 <then>
                                    <property name="mandrill.notificationId" expression="json-eval($.._id[0])" />
                                    <property name="notificationIdObject"
                                       expression="fn:concat('email:',get-property('tsheets.email'),',notificationId:',get-property('mandrill.notificationId'))" />
                                    <property name="status" value="success" />
                                    <property name="message" value="Notification e-mail has been sent successfully." />
                                 </then>
                                 <else>
                                    <property name="notificationIdObject" expression="fn:concat('email:',get-property('tsheets.email'))" />
                                    <property name="status" value="error" />
                                    <property name="message" expression="json-eval($.)" />
                                 </else>
                              </filter>
                              <call-template target="responseHandlerTemplate">
                                 <with-param name="id" value="{$ctx:notificationIdObject}" />
                                 <with-param name="activity" value="mandrill_sendNotifications" />
                                 <with-param name="status" value="{$ctx:status}" />
                                 <with-param name="message" value="{$ctx:message}" />
                              </call-template>
                           </then>
                        </filter>
                        <property name="userIndex" expression="get-property('operation','userIndex') + 1"
                           scope="operation" />
                        <filter xpath="get-property('operation','userCount') = get-property('operation','userIndex') ">
                           <then>
                              <loopback />
                           </then>
                        </filter>
                     </sequence>
                  </target>
               </iterate>
            </else>
         </filter>
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" />
         <filter source="boolean(get-property('operation', 'responseString'))" regex="false">
            <then>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response":{
                     "process":"bugzilla_manageUsers",
                     "activityResponse":"All users are synchronized."
                     }
                     }
                  </format>
               </payloadFactory>
            </then>
            <else>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response":{
                     "process":"bugzilla_manageUsers",
                     "activityResponse":[$1]
                     }
                     }
                  </format>
                  <args>
                     <arg evaluator="xml" expression="get-property('operation', 'responseString')" />
                  </args>
               </payloadFactory>
            </else>
         </filter>
         <send />
      </outSequence>
   </target>
</proxy>
Sample Request for retrieving project members from the TSheets API and if they do not exist in Bugzilla, creating them as users in the Bugzilla API and notifying the users with the relevant credentials and other information (Eg: BugZilla URL, Username/Login ID, and Password) using the Mandrill API
{
   "tsheetsApiUrl": "https://wso2yas.tsheets.com",
   "tsheetsAccessToken": "S.1__9f247e6537bcc83348cfdadaafdd741e9956b453",
   "bugzillaApiUrl": "http://172.22.217.30/bugiya/rest.cgi",
   "bugzillaApiKey": "jgvuN3V9aWqMLWFo4gs2UkezswIUCn9qezgOmibG",
   "jobCodeId":"32000178",
   "defaultPassword":"123456",
   "bugzillaLoginURL":"http://172.22.217.30/bugiya/",
   "mandrillApiKey": "YkT77awdFCTbvCuwhJo4jw",
   "fromEmail": "test@gmail.com",
   "fromName": "Bugzilla Admin"
}

Note

 The following are the parameter descriptions:

  • jobCodeId: The TSheets job code ID which was created as a project to retrieve job code assignments. 
    • defaultPassword: The default password for the new Bugzilla user accounts.
    • bugzillaLoginURL: The URL of the Bugzilla login page to notify users.
    • fromEmail: From e-mail address in order to send the Mandrill notification.
    • fromName: From name to in order to send the Mandrill notification.Â