Introduction
Stored procedure is a powerful mechanism to interact with a relational database. It allows business logic to be embedded inside database as an API. Since procedure is stored (in a precompiled format) within the database itself, execution is faster. Client programs can be restricted to accessing database only via stored procedures. Thus enforcing fine grained security, validation rules to data that goes in/comes out of your database.
All major Database engines support stored procedures. If your application uses complex stored procedures & you want to expose them to outside business systems, WSO2 Data Services is the answer for you.
Objective
In this tutorial I will show you how to call MySQL 5 Stored Procedure using WSO2 Data Services. But Data Services stored procedure support is not limited to MySQL 5. You can try it with any other relational database engine of you choice.
Prerequisites
1. Download latest version of WSO2WSAS from http://dist.wso2.org/products/wsas/java/
2. Install it as a standalone server (Install location will be referred to as WSAS_HOME hereafter.)
3. Start WSO2WSAS-<VERSION> (run WSAS_HOME/bin/wso2wsas.bat | wso2wsas.sh)
4. Open a web browser & navigate to https://localhost:9443/
5. Login to WSAS (using Username/password = admin/admin) & get yourself familiar.
6. Stop WSAS. (Don't worry. We will be starting back soon :-) )
Step 1 : Creating & Populating Sample Database
Use following sql to create & populate sample database, which we will be using for this tutorial.
DROP DATABASE IF EXISTS DATASERVICE_SAMPLE;
CREATE DATABASE DATASERVICE_SAMPLE;
GRANT ALL ON DATASERVICE_SAMPLE.* TO 'dsuser'@'localhost' IDENTIFIED BY 'user123';
USE DATASERVICE_SAMPLE;
DROP TABLE IF EXISTS Employees;
CREATE TABLE Employees(
employeeNumber INTEGER,
lastName VARCHAR(50),
firstName VARCHAR(50),
extension VARCHAR(10),
email VARCHAR(100),
officeCode VARCHAR(10),
reportsTo INTEGER,
jobTitle VARCHAR(50)
);
insert into Employees values (1002,'Murphy','Diane','x5800','dmurphy@classicmodelcars.com','1',null,'President');
insert into Employees values (1056,'Patterson','Mary','x4611','mpatterso@classicmodelcars.com','1',1002,'VP Sales');
insert into Employees values (1076,'Firrelli','Jeff','x9273','jfirrelli@classicmodelcars.com','1',1002,'VP Marketing');
insert into Employees values (1088,'Patterson','William','x4871','wpatterson@classicmodelcars.com','6',1056,'Sales Manager (APAC)');
insert into Employees values (1102,'Bondur','Gerard','x5408','gbondur@classicmodelcars.com','4',1056,'Sale Manager (EMEA)');
insert into Employees values (1143,'Bow','Anthony','x5428','abow@classicmodelcars.com','1',1056,'Sales Manager (NA)');
insert into Employees values (1165,'Jennings','Leslie','x3291','ljennings@classicmodelcars.com','1',1143,'Sales Rep');
DROP PROCEDURE If EXISTS getEmployee;
Alternatively you can find a file called 'mysql.txt' containing all the sql we will be using. Once you login to mysql console, you can run this file (as root) as follows.
sumedha@sumedha:~/articles/data-service/store-procedure-1$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16 to server version: 5.0.24a-Debian_9ubuntu2-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> \. mysql.txt
Step 2 : Writing a simple stored procedure
Following sql will create a stored procedure called 'getEmployee' which accepts employee number as an integer.
CREATE PROCEDURE getEmployee(empNo INTEGER) SELECT employeeNumber,lastName,firstName,email FROM Employees where employeeNumber = empNo;
Step 3 : Updating WSAS libraries (Only if your using WSAS 2.0)
If your using WSAS 2.0, you need to update Data Service library to enable Stored Procedure support.
In order to do this,
1.Download wso2data-service-2.3.jar_.zip from bottom of this document.
2.Extract it to a temporary location & you will find wso2data-service.2.3.jar
3.Place wso2data-service-2.3.jar inside WSAS_HOME/lib. Make sure you delete wso2data-service-2.0.jar located inside the same folder.
Step 4 : MySQL JDBC Driver
1. Download JDBC driver for MySQL from http://www.mysql.com/products/connector/.
2. Copy jar file containing driver class (i.e. mysql-connector-java-<VERSION>-bin.jar) into WSAS_HOME/lib
Step 5 : Creating a Data Service with stored procedure
Paste following content into a file called 'StoredProcedureSampleService.dbs'. (Alternatively you can use the attached file at the bottom of this document. Please change the '.txt' extension to '.dbs' before using.)
<data name="StoredProcedureSampleService">
<config>
<property name="org.wso2.ws.dataservice.driver">com.mysql.jdbc.Driver</property>
<property name="org.wso2.ws.dataservice.protocol">jdbc:mysql://localhost:3306/DATASERVICE_SAMPLE</property>
<property name="org.wso2.ws.dataservice.user">dsuser</property>
<property name="org.wso2.ws.dataservice.password">user123</property>
</config>
<query id="getEmployeeSP">
<sql>call getEmployee(?)</sql>
<result element="Employees" rowName="Employee">
<element name="EmployeeNumber" column="employeeNumber" />
<element name="LastName" column="lastName" />
<element name="FirstName" column="firstName" />
<element name="Email" column="email" />
</result>
<param name="employeeNo" sqlType="INTEGER" />
</query>
<operation name="getEmployee">
<call-query href="getEmployeeSP">
<with-param name="employeeNumber" query-param="employeeNo" />
</call-query>
</operation>
</data>
Start WSA Server. Go to Service -> Upload Service Artifact (.aar,.jar,.zip,.dbs). Browse to location where you saved 'StoredProcedureSampleService.dbs' & upload it to WSAS. (Figure 01 & Figure 02)
Figure 01

Figure 02

Newly created service ('StoredProcedureSampleService') will soon appear on Services screen as follows. (Figure 03)
Figure 03

Step 6 : Invoking Data Service (using SOAP HTTP bindings)
Since 'StoredProcedureSampleService' is similar to any other web service, you can invoke this as you would invoke anyother web service. I will show you how to invoke this using HTTP bindings.
1. Click on 'Services' link (from menu on you left side)
2. Click on 'StoredProcedureSampleService' link under 'Services' heading. (Figure 04)
Figure 04

3. You will be taken to a screen similar to following. Copy the http endpoint reference (i.e. http://127.0.0.1:9762/services/StoredProcedureSampleService in my case.) as highlighted in figure 05.
Figure 05

4. Open a new browser window & paste the copied URL. (http://127.0.0.1:9762/services/StoredProcedureSampleService)
5. Append '/getEmployee?employeeNo=1165' to the end of it.
6. Final URL should look like following.(Only IP part should be different)
http://127.0.0.1:9762/services/StoredProcedureSampleService/getEmployee?employeeNo=1165
7. Submit the URL (press enter) and you will get following result in your browser window. (Figure 06)
Figure 06

Step 7 : Playing around
1. Try replacing '1165' with any of the following.
1002, 1056, 1076, 1088, 1102, 1143, 1165
(These are the Employee numbers used in our insert statements. (Step 1)
2. You can try invoking the service using other clients. (Take a note of highlighted section).(Figure 07)
Figure 07

Step 8 : Java Client Program
Listed bellow is a simple java client program, that will invoke the service. Inorder to compile & run this, simply add all the jar files in WSAS_HOME/lib to you classpath. (You can find source attached in a file called 'StoreProcedureClient.java_.txt'. Please remove '_.txt' part from file name before using it.)
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
public class StoreProcedureClient {
public static void main(String args[]){
EndpointReference targetEPR = new EndpointReference(
"http://127.0.0.1:9762/services/StoredProcedureSampleService");
try {
OMElement payload = getPayload();
Options options = new Options();
options.setTo(targetEPR);
options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, 10000);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
System.out.println("Request : "+payload);
OMElement result = sender.sendReceive(payload);
System.out.println("Response : "+result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
private static OMElement getPayload() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://ws.apache.org/axis2/xsd", "ns1");
OMElement method = fac.createOMElement("getEmployee", omNs);
OMElement employeeNo = fac.createOMElement("employeeNo", omNs);
employeeNo.setText("1165");
method.addChild(employeeNo);
return method;
}
}
Additional reading (if your still interested :-) )
1. (Getting started with Data Service with WSO2 WSAS 2.0) http://www.wso2.org/blog/sumedha/2573
2. (How to expose Excel 97-2002 spreadsheet as a Data Service using WSAS - 2.0) http://www.wso2.org/blog/sumedha/2581
3. (Getting started with Data Service Samples - Movie - might take sometime to load) http://www.wso2.org/blog/sumedha/2590
Comments
You are more than welcome to send us your comments/suggestions/queries. Please use the comments section bellow and let us know what you think.
References
1. Contents in 'StoredProcedureSampleService.dbs' complies to grammer defined by following specification. (http://wso2.org/wiki/display/wsf/Data+Services+and+Resources)
Error running example
faulty services
Example of stored
How to use wso2data-service for WSO2 WSF/PHP
XML as input
Hi Prakash, Nice to have you
How to pass more than one parameter while calling MySQL SP
Passing multiple parameters...
Passing Multiple parameter support
Multiple param example
Passing Mutiple parameter - Works :-)
Great !!!
Define Data Service
Hi,
I tried this and i am getting error while Defining Data Service. Can pls help me out...
Services > Faulty Services
Error: org.apache.axis2.AxisFault: com.mysql.jdbc.Driver at org.wso2.ws.dataservice.DBDeployer.createDBService(DBDeployer.java:250) at org.wso2.ws.dataservice.DBDeployer.processService(DBDeployer.java:360) at org.wso2.ws.dataservice.DBDeployer.deploy(DBDeployer.java:108) at org.apache.axis2.deployment.repository.util.DeploymentFileData.deploy(DeploymentFileData.java:137) at org.apache.axis2.deployment.DeploymentEngine.doDeploy(DeploymentEngine.java:551) at org.apache.axis2.deployment.repository.util.WSInfoList.update(WSInfoList.java:135) at org.apache.axis2.deployment.RepositoryListener.update(RepositoryListener.java:318) at org.apache.axis2.deployment.RepositoryListener.checkServices(RepositoryListener.java:220) at org.apache.axis2.deployment.RepositoryListener.startListener(RepositoryListener.java:312) at org.apache.axis2.deployment.scheduler.SchedulerTask.checkRepository(SchedulerTask.java:64) at org.apache.axis2.deployment.scheduler.SchedulerTask.run(SchedulerTask.java:71) at org.apache.axis2.deployment.scheduler.Scheduler$SchedulerTimerTask.run(Scheduler.java:83) at java.util.TimerThread.mainLoop(Unknown Source) at java.util.TimerThread.run(Unknown Source)
Missing mysql JDBC driver
Hi Prakash,
You do not have mysql driver on WSAS_HOME/lib.
Did you follow "Step 4 : MySQL JDBC Driver"?
If not, please download the JDBC driver from MySQL site as I mentioned in Step 4. The link I mentioned in Step 4 will take you to following page. (http://dev.mysql.com/downloads/connector/j/5.0.html). From here download 'Source and Binaries (zip)'.
Extract the downloaded zip file & you will be able to find 'mysql-connector-java-5.0.5-bin.jar' inside one of the folders that get created.
Drop this 'mysql-connector-java-5.0.5-bin.jar' into WSAS_HOME/lib.
Once you drop this jar file there, just restart WSAS & you will see the service correctly deployed. (I hope you have not deleted the faulty service :-) )
Try out the above you will be able to overcome the error your getting.
I just happened to notice that you have saved & uploaded the file as 'service1.dbs' not as 'StoredProcedureSampleService.dbs', As I mentioned in Step 5.But this would not be a problem.
If you encounter more problems, please post a comment.
/sumedha
Missing mysql JDBC driver
Hi Sumedha,
As you said, i missed out Step-4 :-) i have done the changes and It's working fine now.
Thanks a lot for your support.
Can you pls tell me that in which scenario we can deploy this service ? How this can be used effectively in web ?
Congratulations!!!!
This type of service can be useful in many scenarios.
1.Simply it allows you to expose desired entity (table(s),stored procedure) of a dabase using web service
2.Ideal for integrating systems (you can control the output format of result)
3.You can use it to eliminate the risk of a third party connecting to your database directly.
4.Since it runs on top of axis, you can choose the transport medium(HTTP(S),JMS,SMTP,TCP) over which the data will be transported
5.Data can be transferred over a secure channel
5.No need of tweaking firewall setting to allow third party to connect to your database directly.
6.Supports AJAX based programming model
7.You can expose MS Excel (http://wso2.org/blog/sumedha/2581) & CSV files as a dataservice too.
/sumedha
Java Client Program
Hi Sumedha,
There is another issue here, please find the details given under and help me out to solve this.
The XML page cannot be displayed
Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.
XML document must have a top level element. Error processing resource 'http://192.168.1.24:9762/services/StoredProcedureSam...
Also please explain the Step 8 in detail since i have no idea about java. It would be more helpful if you provide more details about how to reuse the java code which you given.
Step 8 : Java Client Program
Listed bellow is a simple java client program, that will invoke the service. Inorder to compile & run this, simply add all the jar files in WSAS_HOME/lib to you classpath. (You can find source attached in a file called 'StoreProcedureClient.java_.txt'. Please remove '_.txt' part from file name before using it.)
Thank you..
Step 8: Java Client Program
Hi Prakash,
By the end of Step 5, we have a data service deployed with the name 'StoredProcedureSampleService'. (See figure 04)
From Step 6 onwards, I tried to explain different methods of invoking this service.
1. Using HTTP Bindings (explained in Step 6)
2. Using WSAS generated Client (screen shot in Step 7 - Figure 07)
3. Using Try-It (screen shot in Step 7 - Figure 07)
4. using a Java Client (Step 8)
Step 8 gives a brief sample code on how to invoke this service via a java client program. You can run the code as it is. (sometimes you might have to alter the IP part of the following line. But no more changes needed).
You just have to compile this java class & run.
Since your not comfortable with running this, I can bundle this into a small package so that you can straight away run this. (But I might not be able to do this today.)
Do you have Ant (http://ant.apache.org/) installed on your machine? If so I can use 'Ant' to create this package.
/sumedha
XML Page cannot be displayed..
Hi Prakash,
I assume you were on Step 6 when you got this error. I tested this step on IE6,7 & Firefox. But I could not regenerate the issue.
Could you send me the URL you pasted on browser?
In the meantime make sure it is something like the following.
http://127.0.0.1:9762/services/StoredProcedureSampleService/getEmployee?employeeNo=1165
I will reply to your other question on a seperate thread.
/sumedha
XML Page cannot be displayed
Hi Sumedha,
The below given is the posted URL and i using IE6 only.
http://192.168.1.24:9762/services/StoredProcedureSampleService/getEmployee?employeeNo=1002
XML Page cannot be displayed..
Prakash,
URL Looks fine.....
Is your service name 'StoredProcedureSampleService' ? you can check this against Figure 04.
If its different, please change your url as
http://192.168.1.24:9762/services/<REPLACE-WITH-YOUR-SERVICE-NAME>/getEmployee?employeeNo=1002
If above does not solve your problem, Please attach WSDL2 for you service.
You can get this by clicking on WSDL 2.0 link (see Figure 4) & saving it to your machine.
/sumedha
Hi Sumedha, Please find the
Hi Sumedha,
Please find the server log details given below... may be this could be the reason. Can you please look into this one ..
INFO [2007-09-14 15:55:28,156] Creating database connection for StoredProcedureSampleService
INFO [2007-09-14 15:55:38,984] Deploying Web service: StoredProcedureSampleService.dbs
ERROR [2007-09-14 15:55:54,125] Socket error caused by remote host /127.0.0.1
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:723)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1057)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1041)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.handshake(JSSESocketFactory.java:119)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:520)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
thanks...
@ Prakash
Server log...
Prakash,
This error is not related to Data Service. Most probably this error is generated when you hit refresh button in frequent intervals under a SSL connection.
Could you attach the WSDL please? I have described how to generate this in my earlier post.
/sumedha
WSDL
Step 3:
Hi Prakash,
Your WSDL looks fine.
Did you follow Step 3 : Updating WSAS libraries?
By default the data service implementation comming with WSAS 2.0 does not support this. So you need to download 'wso2data-service-2.1.jar_.zip' from bottom of this document, extract it & drop wso2data-service-2.1.jar into you WSAS_HOME/lib. After doing this, you have to delete wso2data-service-2.0.jar which is inside the same folder.
If you have both jars (wso2data-service-2.0.jar & wso2data-service-2.1.jar, precedence will be give to wso2data-service-2.0.jar, thus failing the sample)
If above step does not work for you,
Lets do some debugging ;-).
Click on 'Logging' link on your left. Inside 'Global Log4j Configuration' frame, select Log Level as 'ERROR'. Click 'Update' button.
Invoke your your service again (http://192.168.1.24:9762/services/StoredProcedureSampleService/getEmployee?employeeNo=1002) ,by refreshing your browser.
Send me the stack trace.
BTW, if you get a message like "java.lang.UnsupportedOperationException: The SQL call getEmployee(?) is not supported yet..", this means your still having wso2data-service-2.0.jar inside your WSAS_HOME/lib folder.
Please do get back with your status.
/sumedha
P.S. We will be shipping WSAS 2.1 soon. (Most probably next week). In this version you do not have to perform this step. :-). Sorry for the trouble.
wso2data-service-2.1.jar
Hi Sumetha,
Great job, i have kept both jar files in WSAS_HOME/lib directory. :-) I have delted the old version (wso2data-service-2.0.jar) and it's working fine now.
Thanks a lot..
Congratulations again !!!!
How do you like it?Do you see any use cases of this in your working environment?
BTW... thanks for not letting it go.. I am glad that you managed to see the end result of it.
Do keep posting...if you have any questions..
/sumedha