In WSO2 API Manager it is possible to add workflow extensions for events such as user registration, application creation, API subscription etc. There are several standard workflows provided in API Manager, you can read documentation here. In this post I want to show how to customize a BPEL process used in User Signup Workflow of the API Manager.
Open WSO2 Developer Studio dashboard. Under Create menu tab select BPEL workflow:
Select Import BPEL workflow and click Next:
Give the BPEL archive file destination and click Next: (You can find the standard user signup BPEL process in <APIM_HOME>/business-processes/user-signup/BPEL/)
Provide maven details for your project and click Finish:
After you have imported the project you will see that there are errors in some files. You can ignore them, the BPEL compiler won’t throw an error during compilation. Optionally you can correct the files that give errors as follows:
- Open UserSignupProcess.bpel in source view and remove attribute outputVariable in the last <bpel:invoke> element of the source file. This gave an error because the port type which is used to define the partner link doesn’t define an output (see WorkflowCallbackService.wsdl).
- Open UserApproval.wsdl and remove <wsdl:message> element that gives an error. This element isn’t used anywhere in the wsdl file, BPEL process or related human task and is therefore redundant.
Open UserSignupProcess.bpel in design view:
You can see the graphical representation of the orchestration logic of the process. The process receives input data and stores it in a variable ‘input’. Then it calls approval service which initiates a human task to approve/reject a user signup. The response of the approval service is then sent to workflow callback service.
I will extend the process by adding extra logic to its flow. My process will checks if the email address of the registered user is a valid student email address. If the email address is valid, the approval service will be called, if not the workflow status REJECTED is passed directly to the workflow callback service.
To get the email address of a registered user I will use a JAX-WS web service (GetEmailService) which i have created in my previous post.
To check if the email address is a valid email address I have created a SoapUI mock service (VerifyEmailService) based on the attached wsdl. Downloads:
Change the soap address in <wsdl:service> element if you want to use the mock service and wsdl I have provided:
<wsdl:service name="StudentContestService"> <wsdl:port name="StudentContestPort" binding="tns:StudentContestBinding"> <soap:address location="http://your_ip:8081/verifyEmail"/> </wsdl:port> </wsdl:service>
Before we start adding extra web service calls to the orchestration logic we need to add wsdl files of the web services we use into ‘bpelContent’ directory of the project:
- Wsdl of GetEmailService can be found in API Manager management console as explained in my previous post.
- Download wsdl of the VerifyEmailService here:
We can now add extra activities to the orchestration logic of the process.
Right click on AssignInputs activity and select Insert before -> Assign. Rename it to ‘AssignGetEmailInput’. We need this activity to assign input values for GetEmailService.
Right-click again on AssignInputs activity and select Insert before -> Invoke and rename it to ‘InvokeGetEmail’. This element will invoke GetEmailService.
Let’s now implement the ‘InvokeGetEmail’ activity. Click on the activity and go to Properties -> Details tab. From Partner Link drop down list, select Create Global Partner Link, give a name to your partner link and click OK:
Click Add WSDL:
Select the wsdl file corresponding to GetEmailService and click OK:
In the Partner Link Type window, select the correct PortType and click OK:
Give a name to the Partner Link Type and click Next:
Give a name to the partner role, choose the port type and click Finish:
Since GetEmailService is synchronous we only need to define one role(partner role), but if you use asynchronous services you need to define two roles(partner role and my role).
Select Operation of this invoke activity by double-clicking it in the Quick Pick menu:
Note that input and output variables are automatically created and added to the invoke activity.
(Note: if you have more than one operation in one port you will need to create variables manually in the source code of UserSignupProcess.bpel since the Developer Studio doesn’t seem to fill the variables correctly in this case. After creating necessary variables, you can then add them to your activity from Properties -> Details tab.)
So, we have implemented ‘InvokeGetEmail’ activity. Next we need to implement the ‘AssignGetEmailInput’ activity. Click on the assign activity, go to Properties -> Details tab and click New. Do the mapping as follows:
It will automatically prompt for the initialization. Click Yes.
In a similar way add and implement two more activities: ‘AssignVerifyEmailInput’ and ‘InvokeVerifyEmail’. Use the result from GetEmailService as input of VerifyEmailService.
Next we will add an If construct to change flow depending on the result of VerifyEmailService. Right-click on AssignInputs and select Insert before -> If. Then drag all the underlying activities except the last invoke into the If area in the same order they appear:
Click on If and in Properties -> Details tab add the following XPath1.0 expression as condition (the namespace prefix ‘ns3’ might be different in your case):
According to the schema, if the condition is true the approval service will be invoked initiating a human task. We need to add logic in case the conditions is false. Right-click on If and select Add Else. Under Else add an assign activity and name it ‘AssignFailureOutputs’. Do the following mapping (when you are prompted for the initialization, click Yes):
You should get a similar flow:
The final step is adding two new outbound interfaces (invokes) we have used to the deployment descriptor. Open deploy.xml of the project in xml editor. Add namespace declarations to <deploy> element:
and two <invoke> elements to <process> element:
<invoke partnerLink="getEmailPL"> <service name="services.i8c.be:EmailService" port="EmailServicePort"> </service> </invoke> <invoke partnerLink="verifyEmailPL"> <service name="new.webservice.namespace:StudentContestService" port="StudentContestPort"> </service> </invoke>
Now we are ready to export the project and deploy it in WSO2 Business Process Server. Save all changes you made to the original process, right-click on the project, select Export Project as Deployable Archive and choose destination location. Start the WSO2 BPS and open the management console. Under Processes select Add and upload the archive you have exported in the previous step:
To use this customized process in User Signup Workflow provided in API Manager follow the steps described here. In step 5 upload your version of the BPEL process instead of the standard one.