Wednesday, December 3, 2014

Invoking ws-secured (username token) service from WSO2 API Manager

In this blog post I'm going to talk about a usecase scenario where I want to invoke a ws-secured web service (username token) via WSO2 API Manager. For the demonstration purposes I use WSO2 DSS to create a ws-secured web service. Here are the steps

1. Download WSO2 APIManager (at the moment 1.7.0) and WSO2 DSS (at the moment 3.2.2)
2. Extract two products zip files. As both products run in the same machine, change the port offset in either of the instance. Here I'm going to do that change in DSS instance. For that edit the carbon.xml (in $SERVER_ROOT/repository/conf) and change the following in the DSS.

<Offset>0</Offset>
to
<Offset>1</Offset>

3. Run the ant script in the DSS samples
4. Start both servers
5. In the DSS server the sample dataservices should be now deployed. Secure the "samples/ResourcesSample" dataservice with username token ws-security policy.







































6. Try to invoke the following REST URL with username and password as 'admin'

https://localhost:9444/services/samples/ResourcesSample/products

7. Create an API from API Manager. Go to API publisher and add an API


























8. Give the ws-secured service as the endpoint













9. Click on 'Show More Options' link and select 'Secured' from drop down and give admin as credentials.















10. Publish the API. In the API store subscribe to the API and invoke the API with the necessary authorization access token. You will be able to see the result.


Monday, October 27, 2014

Customized login pages in WSO2 IS in OAuth2 flow

Customizing the login page to the server is available for SAML2, OAuth and OpenID flows. In this blog post I'm going to explain how to customize the login page for OAuth2 authentication flow. If you want to know about this on SAML2 the steps are explained in the WSO2 IS docs under customizing login pages.  Here, I'm using WSO2 IS 5.0.0 which is the latest release.

1. Check out the source code of the authenticationendpoint web app from the SVN location
2. Modify the existing org.wso2.carbon.identity.application.authentication.endpoint.oauth2.OAuth2Login.java located at src/main/java/org/wso2/carbon/identity/application/authentication/endpoint/oauth2 as indicated below.

In the doGet method change
String applicationName = request.getParameter("application");
to String applicationName = request.getParameter("relyingParty");

with this modification it identifies the application name as the value for "relyingParty" in the request.

3. Build the source and replace the existing <IS_HOME>/repository/deployment/server/webapps/authenticationendpoint.war file with the new war file. Also, delete the existing expanded authenticationendpoint folder at the same location. (Take a backup of the existing authenticationendpoint folder if needed)

4. Start the server

5. Add init parameters to the "OAuth2Login" servlet in the web.xml file located in the expanded web app as below.
       <init-param>
            <param-name>PugQXfLjByRvHIwHJfSuw2Wh_Koa-LoginPage</param-name>
            <param-value>customized_login.jsp</param-value>
        </init-param>

The param-name should be in the format
$OAuth_Client_Key-LoginPage
(the client key received at the application registration)

The param-value is the customized page location

6. Place the customized login page at the same level as 'login.jsp'. Also, if there are css files and images then put them inside the respective folders in the authenticationendpoint.

7. Restart the server and you will be able to see the new login page when you login to the web app.


Monday, September 29, 2014

Writing a Simple AXIS 2 Service

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 *




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
  • Interfacing tasks in Carbon servers.
  • Trigger web tasks remotely
The first feature will be discussed in this blog post. Carbon servers can be configured to use WSO2 Task Server as the dedicated task provider. I will take WSO2 DSS (Here I'm using DSS 3.2.1) as the WSO2 Server for demonstration purposes. These are the steps to follow.

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.








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

<property name="build.compiler" value="extJavac"/>