In this blog post I'm going to discuss on how to write a simple axis2 service. Here I'm using code first approach to write the service. First of all, we can start from writing a java class with a simple method.
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.http.HTTPConstants;
public class SimpleService {
public void print(String value) throws PrintException {
if (value ==null) {
throw new PrintException("value is null");
}
MessageContext context = MessageContext.getCurrentMessageContext();
context.setProperty(HTTPConstants.RESPONSE_CODE, 200);
System.out.println("Value = " + value);
}
}
The PrintException method would be
public class PrintException extends Exception {
public PrintException(String message) {
super(message);
}
}
In order to archive this as a valid axis2 service there should be a services.xml associated with the service inside the service archive file. It contains the deployment description of the service.
<service>
<parameter name="ServiceClass" locked="false">SimpleService</parameter>
<operation name="echo">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</operation>
</service>
The class name should be the fully
qualified class name. As in my example the SimpleService class in not in any package I have simply used the class name.
Axis2 has a set of built-in message receivers. According to this sample services.xml file it says that operation 'print' of this service should
use the Axis2 Java class 'org.apache.axis2.rpc.receivers.RPCMessageReceiver' as its
message receiver class.
If an operation is an in-only operation you can use
org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver
Create the archive file using
jar cvf SimpleService.aar *
Monday, September 29, 2014
Thursday, June 19, 2014
WSO2 Task Server - Interfacing tasks from other WSO2 Servers
WSO2 TS (At the moment it's 1.1.0) is released with the following key features
1. Download TS and DSS product zip files and extract them.
2. We are going to run 2 carbon servers in the same machine. Therefore, we need to change the port index of DSS in CARBON_HOME/repository/conf/carbon.xml so that the DSS nodes will run without conflicting with other server.
In carbon.xml, change the following element in order to run the DSS in HTTP port 9764 and HTTPS port 9444.
<Offset>1</Offset>
3. Open the tasks-config.xml file of your carbon server (e,g. DSS Server). You can find this file from the <PRODUCT_HOME>/repository/conf/etc directory. Do the following changes.
4. Set the task server mode to REMOTE.
<taskServerMode>REMOTE</taskServerMode>
By setting this mode, we can configure the carbon server to run it's task remotely.
5. Point the taskclientdispatchaddress to the same DSS server address.
<taskClientDispatchAddress>https://localhost:9444</taskClientDispatchAddress>
6. Remote address URL and credentials to login to the server should be defined.
<remoteServerAddress>https://localhost:9443</remoteServerAddress>
<remoteServerUsername>admin</remoteServerUsername>
<remoteServerPassword>admin</remoteServerPassword>
7. Start the Task Server.
8. Start the DSS Server. You can see it is started in REMOTE mode from the startup logs
9. Now you can add a task from management console of the DSS Server.
10. You can verify that the task is running on the Task Server by the logs printed in the TS logs
- Interfacing tasks in Carbon servers.
- Trigger web tasks remotely
1. Download TS and DSS product zip files and extract them.
2. We are going to run 2 carbon servers in the same machine. Therefore, we need to change the port index of DSS in CARBON_HOME/repository/conf/carbon.xml so that the DSS nodes will run without conflicting with other server.
In carbon.xml, change the following element in order to run the DSS in HTTP port 9764 and HTTPS port 9444.
<Offset>1</Offset>
3. Open the tasks-config.xml file of your carbon server (e,g. DSS Server). You can find this file from the <PRODUCT_HOME>/repository/conf/etc directory. Do the following changes.
4. Set the task server mode to REMOTE.
<taskServerMode>REMOTE</taskServerMode>
By setting this mode, we can configure the carbon server to run it's task remotely.
5. Point the taskclientdispatchaddress to the same DSS server address.
<taskClientDispatchAddress>https://localhost:9444</taskClientDispatchAddress>
6. Remote address URL and credentials to login to the server should be defined.
<remoteServerAddress>https://localhost:9443</remoteServerAddress>
<remoteServerUsername>admin</remoteServerUsername>
<remoteServerPassword>admin</remoteServerPassword>
7. Start the Task Server.
8. Start the DSS Server. You can see it is started in REMOTE mode from the startup logs
9. Now you can add a task from management console of the DSS Server.
10. You can verify that the task is running on the Task Server by the logs printed in the TS logs
Thursday, January 16, 2014
Clustering WSO2 Products with Registry Mounting
In this blog post I'm going to explain how to set up a cluster of WSO2 products using registry mounting. This setup method is applicable to products built using 4.2.0 kernel.
Here I will use WSO2 DSS as the product and WSO2 GREG for registry mounting.
This is what we are going to do!
GREG will be our central repository which uses MySQL as the database. The two DSS servers will use the same repository for their shared resources.
Now it is time to configure these products.
1. Download DSS 3.1.1 from here
2. Download GREG 4.6.0 from here
3. Create a database in MySQL and assign user priviledges with the following commands.
mysql>create database regdb;
mysql>use regdb;
mysql>grant all on regdb.* TO regadmin@localhost identified by "regadmin";
4. Extract the GREG 4.6.0 zip file and change the configured datasource in $GREG_HOME/repository/conf/datasources/master-datasources.xml file in order to tell GREG to run on top of the MySQL datasource instead of default H2 datasource
For that replace
<datasource>
<name>WSO2_CARBON_DB</name>
<description>The datasource used for registry and user manager</description>
<jndiConfig>
<name>jdbc/WSO2CarbonDB</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<url>jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url>
<username>wso2carbon</username>
<password>wso2carbon</password>
<driverClassName>org.h2.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
with the following content
<datasource>
<name>WSO2_CARBON_DB</name>
<description>The datasource used for registry and user manager</description>
<jndiConfig>
<name>jdbc/WSO2CarbonDB</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<url>jdbc:mysql://localhost:3306/regdb</url>
<username>regadmin</username>
<password>regadmin</password>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>80</maxActive>
<maxWait>60000</maxWait>
<minIdle>5</minIdle>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
5. Download the MySQL JDBC driver connector JAR from here and place it in the $GREG_HOME/repository/components/lib directory.
6. Start the GREG server with the following command
For Linux : wso2server.sh -Dsetup
For Windows : wso2server.bat -Dsetup
This will start GREG on MySQL and setup the regdb database. The work by GREG is done now.
7. We have to configure DSS products as well. As we are having two DSS instance we have to make two copies.
8. As we are running two WSO2 product instances in the same machine, we have to change running ports for each products. We can change the port by changing the following value in $DSS_HOME/repository/conf/carbon.xml
<Offset>1</Offset>
Then it will run on HTTP port 9764 and HTTPS port 9444.
9. Put the following content to the $DSS_HOME/repository/conf/registry.xml for registry mounting in both DSS instances
<dbConfig name="mysql-reg">
<url>jdbc:mysql://localhost:3306/regdb</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>com.mysql.jdbc.Driver</driverName>
<maxActive>5</maxActive>
<maxWait>60000</maxWait>
<minIdle>50</minIdle>
<validationQuery>SELECT 1</validationQuery>
</dbConfig>
<remoteInstance url="https://localhost:9443/registry">
<id>conf-gov-registry</id>
<dbConfig>mysql-reg</dbConfig>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<!-- Governance data will be stored in /_system/governance collection of central registry instance -->
<mount overwrite="true" path="/_system/governance">
<instanceId>conf-gov-registry</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
<!-- Configuration data will be stored in /_system/dssnodes collection of central registry instance -->
<mount overwrite="true" path="/_system/config">
<instanceId>conf-gov-registry</instanceId>
<targetPath>/_system/esbnodes</targetPath>
</mount>
10. Drop the MySQL driver into $DSS_HOME/repository/components/lib directory which is downloaded in the step5
11. By Default the All WSO2 products starts with STANDALONE mode. We have to tell the DSS product to start in CLUSTERED mode. We can enable it by the setting the following property in $DSS_HOME/repository/conf/axis2/axis2.xml to true
<clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent"
enable="true">
12. We have to tell the cluster how many servers are running explicitly.This can be configured in the $DSS_HOME/repository/conf/etc/tasks-config.xml
<taskServerCount>2</taskServerCount>
With this configuration the server starts first will be waiting for others. (ie. It knows that there are two servers in the cluster and have to wait for the other one.)
12. Now, we are done with the configurations. You can test the clustering and registry mounting through task scheduling. More info available in docs. Once we schedule a task from one DSS instance, that particular task is shared with the other instance as well.
Here I will use WSO2 DSS as the product and WSO2 GREG for registry mounting.
This is what we are going to do!
GREG will be our central repository which uses MySQL as the database. The two DSS servers will use the same repository for their shared resources.
Now it is time to configure these products.
1. Download DSS 3.1.1 from here
2. Download GREG 4.6.0 from here
3. Create a database in MySQL and assign user priviledges with the following commands.
mysql>create database regdb;
mysql>use regdb;
mysql>grant all on regdb.* TO regadmin@localhost identified by "regadmin";
4. Extract the GREG 4.6.0 zip file and change the configured datasource in $GREG_HOME/repository/conf/datasources/master-datasources.xml file in order to tell GREG to run on top of the MySQL datasource instead of default H2 datasource
For that replace
<datasource>
<name>WSO2_CARBON_DB</name>
<description>The datasource used for registry and user manager</description>
<jndiConfig>
<name>jdbc/WSO2CarbonDB</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<url>jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url>
<username>wso2carbon</username>
<password>wso2carbon</password>
<driverClassName>org.h2.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
with the following content
<datasource>
<name>WSO2_CARBON_DB</name>
<description>The datasource used for registry and user manager</description>
<jndiConfig>
<name>jdbc/WSO2CarbonDB</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<url>jdbc:mysql://localhost:3306/regdb</url>
<username>regadmin</username>
<password>regadmin</password>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>80</maxActive>
<maxWait>60000</maxWait>
<minIdle>5</minIdle>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
5. Download the MySQL JDBC driver connector JAR from here and place it in the $GREG_HOME/repository/components/lib directory.
6. Start the GREG server with the following command
For Linux : wso2server.sh -Dsetup
For Windows : wso2server.bat -Dsetup
This will start GREG on MySQL and setup the regdb database. The work by GREG is done now.
7. We have to configure DSS products as well. As we are having two DSS instance we have to make two copies.
8. As we are running two WSO2 product instances in the same machine, we have to change running ports for each products. We can change the port by changing the following value in $DSS_HOME/repository/conf/carbon.xml
<Offset>1</Offset>
Then it will run on HTTP port 9764 and HTTPS port 9444.
9. Put the following content to the $DSS_HOME/repository/conf/registry.xml for registry mounting in both DSS instances
<dbConfig name="mysql-reg">
<url>jdbc:mysql://localhost:3306/regdb</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>com.mysql.jdbc.Driver</driverName>
<maxActive>5</maxActive>
<maxWait>60000</maxWait>
<minIdle>50</minIdle>
<validationQuery>SELECT 1</validationQuery>
</dbConfig>
<remoteInstance url="https://localhost:9443/registry">
<id>conf-gov-registry</id>
<dbConfig>mysql-reg</dbConfig>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<!-- Governance data will be stored in /_system/governance collection of central registry instance -->
<mount overwrite="true" path="/_system/governance">
<instanceId>conf-gov-registry</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
<!-- Configuration data will be stored in /_system/dssnodes collection of central registry instance -->
<mount overwrite="true" path="/_system/config">
<instanceId>conf-gov-registry</instanceId>
<targetPath>/_system/esbnodes</targetPath>
</mount>
10. Drop the MySQL driver into $DSS_HOME/repository/components/lib directory which is downloaded in the step5
11. By Default the All WSO2 products starts with STANDALONE mode. We have to tell the DSS product to start in CLUSTERED mode. We can enable it by the setting the following property in $DSS_HOME/repository/conf/axis2/axis2.xml to true
<clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent"
enable="true">
12. We have to tell the cluster how many servers are running explicitly.This can be configured in the $DSS_HOME/repository/conf/etc/tasks-config.xml
<taskServerCount>2</taskServerCount>
With this configuration the server starts first will be waiting for others. (ie. It knows that there are two servers in the cluster and have to wait for the other one.)
12. Now, we are done with the configurations. You can test the clustering and registry mounting through task scheduling. More info available in docs. Once we schedule a task from one DSS instance, that particular task is shared with the other instance as well.
Wednesday, January 8, 2014
Maven 2 Building error : How to sort it out
Today I tried to build a source using Maven 2. In the pom.xml file it is building build.xml file using ant. Then I got the following error.
An Ant BuildException has occured
Perhaps JAVA_HOME does not point to the JDK. It is currently set to /media/chanika/apps/java/java_1.6/jdk1.6.0_45/jre
So the first thing came to my mind is that the path for java JDK is set to as a wrong one. But when I checked the path it has been set correctly.
So I googled a liitle bit and found out this is because of that Maven2 starts the antrun plugin with the JRE not the JDK.
This can be overcome by doing one of the followings.
1. By editing your pom.xml file in order to add tools.jar dependency.
<profile>
<id>tools.jar</id>
<activation>
<property>
<name>java.vendor</name>
<value>Sun Microsystems Inc.</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
2. Or else you can add the following property to your build.xml file
An Ant BuildException has occured
Perhaps JAVA_HOME does not point to the JDK. It is currently set to /media/chanika/apps/java/java_1.6/jdk1.6.0_45/jre
So the first thing came to my mind is that the path for java JDK is set to as a wrong one. But when I checked the path it has been set correctly.
So I googled a liitle bit and found out this is because of that Maven2 starts the antrun plugin with the JRE not the JDK.
This can be overcome by doing one of the followings.
1. By editing your pom.xml file in order to add tools.jar dependency.
<profile>
<id>tools.jar</id>
<activation>
<property>
<name>java.vendor</name>
<value>Sun Microsystems Inc.</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
2. Or else you can add the following property to your build.xml file
<property name="build.compiler" value="extJavac"/>
Thursday, September 26, 2013
How to connect to Cassandra using WSO2 DSS
WSO2 Data Service Server supports exporting data as a web service, called a data service. It can connect to various data sources and expose those data to do operations on them. This post will guide you to use a Cassandra data source using WSO2 DSS.
1. Download Cassandra from here and install (You may have to change some configurations. Please refer this).
2. Create a keyspace, table and store some data
Now we will look into how to configure DSS
3.You can download DSS from here
4. Extract the pack and goto $DSS_HOME/bin folder and run sh wso2Server.sh (if you are a Windows user run wso2Server.bat file)
5. Add a data source. This step has been described in details here
6. You can test connection and save it
7. Deploy data service
The important thing that I would like to address in here is the versions compatibility of WSO2DSS and Cassandra jdbc drivers.
1. Download Cassandra from here and install (You may have to change some configurations. Please refer this).
2. Create a keyspace, table and store some data
Now we will look into how to configure DSS
3.You can download DSS from here
4. Extract the pack and goto $DSS_HOME/bin folder and run sh wso2Server.sh (if you are a Windows user run wso2Server.bat file)
5. Add a data source. This step has been described in details here
6. You can test connection and save it
7. Deploy data service
The important thing that I would like to address in here is the versions compatibility of WSO2DSS and Cassandra jdbc drivers.
- The WSO2 DSS version older than 3.1.0 compatible with Cassandra JDBC 1.1.1. By default the Cassandra 1.1.x supports CQL (Common Query Language) 2. CQL3 is released with much more functionalities than CQL2 such as schema-free feature.
- But you can connect to CQL3 by starting the Cassandra server with the following command ./cqlsh -3
- From WSO2 DSS (older version starting from 3.0.1) you have to specify the connection url as below. jdbc:cassandra://localhost:9160/keyspace_name?version=3.0.0
- If you do not specify the version in the URL it will connect to CQL2 by default
- But from DSS version 3.1.0 onward it supports Cassandra JDBC 1.2.x and because of that, it will connect to CQL3 by default.
Wednesday, September 25, 2013
Escape non printable characters in WSO2 DSS
WSO2 Dss can be used to expose data from different data sources (ex: MYSQL, ORACLE) as a web service. Escaping non printable characters is a feature introduced from WSO2 DSS 3.1.0 onward.
Lets say in your database there are characters which cannot be printed. But you cannot replace or delete them as those are the data you have. But if you want to retrieve those data through a web service it will not allow to do so as they cannot be represented. For an example when you are invoking a data service (using soap-ui or try-it) and do a select query for a data contains characters which are not in printable format it will throw the following exception.
If it is selected the corresponding characters will be replaced by ? and if it is not, then it will throw the above exception. Find more from here.
Lets say in your database there are characters which cannot be printed. But you cannot replace or delete them as those are the data you have. But if you want to retrieve those data through a web service it will not allow to do so as they cannot be represented. For an example when you are invoking a data service (using soap-ui or try-it) and do a select query for a data contains characters which are not in printable format it will throw the following exception.
ERROR {org.wso2.carbon.dataservices.core.description.query.SQLQuery} - DS Fault Message: Error in XML generation at StaticOutputElement.execute
DS Code: UNKNOWN_ERROR
Nested Exception:-
com.ctc.wstx.exc.WstxIOException: Invalid white space character (0x5) in text to output
{org.wso2.carbon.dataservices.core.description.query.SQLQuery}
DS Fault Message: Error in XML generation at StaticOutputElement.execute
DS Code: UNKNOWN_ERROR
Nested Exception:-
com.ctc.wstx.exc.WstxIOException: Invalid white space character (0x5) in text to output
at org.wso2.carbon.dataservices.core.engine.StaticOutputElement.execute(StaticOutputElement.java:232)
at org.wso2.carbon.dataservices.core.engine.OutputElementGroup.execute(OutputElementGroup.java:121)
at org.wso2.carbon.dataservices.core.description.query.Query.writeResultEntry(Query.java:339)
at org.wso2.carbon.dataservices.core.description.query.SQLQuery.processNormalQuery(SQLQuery.java:822)
at org.wso2.carbon.dataservices.core.description.query.SQLQuery.runQuery(SQLQuery.java:2034)
at org.wso2.carbon.dataservices.core.description.query.Query.execute(Query.java:254)
at org.wso2.carbon.dataservices.core.engine.CallQuery.execute(CallQuery.java:161)
at org.wso2.carbon.dataservices.core.engine.CallQueryGroup.execute(CallQueryGroup.java:118)
at org.wso2.carbon.dataservices.core.description.operation.Operation.execute(Operation.java:73)
at org.wso2.carbon.dataservices.core.engine.DataService.invoke(DataService.java:598)
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.execute(DSOMDataSource.java:135)
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.serialize(DSOMDataSource.java:147)
at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerialize(OMSourcedElementImpl.java:691)
This happened as those characters cannot be serialized to xml when they are going to be printed. But with this newly added feature you can define to escape the those characters with '?' when you define output mapping in the process of creating the data service. You can select "Escape Non Printable Characters" from the UI.
If it is selected the corresponding characters will be replaced by ? and if it is not, then it will throw the above exception. Find more from here.
Sunday, June 30, 2013
Analyze your IBM thread dump in Linux
Last week I had to analyze a heap dump taken from IBM VM. That heap dump was in .txt file and therefore it is readable. Part from the heap dump is shown below.
As the format of this heap dump is different from hprof file format this cannot be analyzed using either MAT analyzer (the eclipse plugin) or JProfiler because those prefer binary data to analyze.
There is a heap dump analyzer specially to the IBM VM called 'IBM Thread and Monitor Dump Analyzer for Java'. You can download the jar from here. (Please note that this version works with only JDK 7). Then you can simply run the jar file using this command
NULL ------------------------------------------------------------------------ 0SECTION TITLE subcomponent dump routine NULL =============================== 1TISIGINFO Dump Event "user" (00004000) received 1TIDATETIME Date: 2004/08/23 at 10:20:50 1TIFILENAME Javacore filename: /u/mcculls/test/javacore.20040823.102050.16908401.txt NULL ------------------------------------------------------------------------ 0SECTION GPINFO subcomponent dump routine NULL ================================ 2XHOSLEVEL OS Level : z/OS 06.00 2XHCPUS Processors - 3XHCPUARCH Architecture : s390x 3XHNUMCPUS How Many : 2
As the format of this heap dump is different from hprof file format this cannot be analyzed using either MAT analyzer (the eclipse plugin) or JProfiler because those prefer binary data to analyze.
There is a heap dump analyzer specially to the IBM VM called 'IBM Thread and Monitor Dump Analyzer for Java'. You can download the jar from here. (Please note that this version works with only JDK 7). Then you can simply run the jar file using this command
chanika@chanika-ThinkPad-T530:/apps/jdk1.7.0/bin$ ./java -jar /home/chanika/Downloads/jca445.jar
Then you will get a window as following
Click on File -> Open Thread Dumps -> Brows the thread dump file and select that.
Then that file will come under thread dump list and the when you select the dump file from the list some information in the header will appear as following screenshot
Then you can analyze the thread dump using options in 'Analyze' tab. This is a sample thread dump analyze I have done.
Subscribe to:
Posts (Atom)





