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
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
<?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>
{ "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:
An array of JSON objects which has the project name and the Zoho Books customer ID.projectsDetails:
Â
Retrieving projects and creating products, components and users
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.
- 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
<?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'),'&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>
{ "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:
An array of JSON objects which has the following parameters:jobCodeDetails:
Â
ID of the TSheets job code which was created as a project in case-001.parentJobCode:
Â
ID of the Zoho Books project which created as a project in case-001.zohobooksProjectId:
Description of the project.description:
Â
Product version of Bugzilla.version:
E-mail address of the Bugzilla user to assign to product as default assignee.defaultAssignee:
Â
An array of JSON objects  which has the following data relevant to the component:childJobCodes:
Â
ID of the TSheets job code (child job code) which was created under Project(parent job code) as Component.childJobCodeId:
E-mail address of the Zoho Books user to assign to the component.defaultAsigneeEmail:
Â
Name of the Zoho Books user to create, if it does not exist.defaultAssigneeName:
Â
Billable rate of each component.billableRate:
Â
Retrieving project members, creating users and notifying users
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.
- 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
<?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>
{ "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:
The TSheets job code ID which was created as a project to retrieve job code assignments.ÂjobCodeId:
The default password for the new Bugzilla user accounts.defaultPassword:
bugzillaLoginURL:
The URL of the Bugzilla login page to notify users.
From e-mail address in order to send the Mandrill notification.fromEmail:
fromName:
From name to in order to send the Mandrill notification.Â