Eclipse or SUNrise...

Eclipse or SUNrise...
...JAVA for sure

Friday, December 10, 2010

Customize WebSphere web console

Today, IT systems are more and more complex and usually there are couple of environments for each of them. In most of the cases there are Integration, Testing (QA or UAT) or Production environments. In case of administering the WebSphere Application Server - the administrator have to log in to many different consoles to do his tasks. It is easy to make a mistake and instead of updating the application on integration - the administrator does it on test or maybe even worse - on live production.

Of course there should be some restrictions like different passwords, VPNs for the environment (especially production), and so on to harden making the mistake. But again, it IS possible to do a mistake. In WAS version 7 there is a simple feature which enables labeling the console with a custom name. In this way, the administrator can see on which console he is logged in. But what can we do with older versions of WAS?

Well since the graphical console is nothing else but an Enterprise application that we can tune a little bit (or maybe not only little:-)). What I did to achieve it, is that I changed the login screen of the console into this:



Those of you who work with WAS will notice the difference at the first glance. What I acctually did was that I modified two images supplying them simply with a name of each enviroment. You will find these images in

{INSTALL_ROOT}/systemApps/isclite.ear/isclite.war/images


I changed two images:

  • Login.gif

  • iscbannerLeft-.gif



Changing the iscbanner* will result in exactly the same functionality as in WAS7 - the change will be visible during the work in the console - in every screen.

This solution will of course not avert a mistake of an administrator, doing his human task but it can prevent such a situation quite nicely.

Tuesday, November 30, 2010

Running RAD 7.5.4 on Linux

Well, finally the 3GB RAM limit under Windows XP forced me to change my work environment to Linux (in my case it is Ubuntu 10.10). Unfortunately after installing Rational Application Developer I received a following error message:

Error: java.lang.RuntimeException: Widget disposed too early


I followed many solutions on IBM's pages and tried different versions of my software (it said that it was a Firefox fault), but nothing helped me. Finally I tried with overriding the .metadata folder from my old RAD's workspace and it actually worked!

I found also on the Developer Works forum (http://www.ibm.com/developerworks/forums/thread.jspa?messageID=14385876) that some other people tried the same as well and it also worked for them.

At the end I have to say that under Linux RAD works twice as fast (but not as fast as it should and could) so I can highly recommend Linux as the platform for these havy-waight Eclipse tools.

Friday, November 26, 2010

Configuration of WebSphere Application Server and IBM HTTP Server Plugin

Several times I came across problematic configuration of IBM HTTP Server with WebSphere Application Server. Most of the times it works out of the box, but sometimes, especially when these components are installed separately or works in different versions it somehow brings trouble. I guess the configuration propagation isn't perfect for these components.

The standard way to create a IHS instance with WAS console, mapping each modules of applications and then propagating WAS Plugin works fine, but although that it turns out that IHS won't redirect you to the apps. Standard error for this is (in this example the request was made for snoop servlet - a sample application which is bundled with WAS):

[error] [client 9.x.x.x] File does not exist: /opt/IBM/HTTPServer/htdocs/snoop


To resolve this problem you can simply add this lines to the httpd.conf file:

LoadModule was_ap22_module /opt/IBM/HTTPServer/Plugins/bin/mod_was_ap22_http.so

WebSpherePluginConfig /opt/IBM/HTTPServer/Plugins/config/webserver1/plugin-cfg.xml


where the was_ap22_module varies from your IHS and WAS version (IHS 7.0 for example is build upon Apache 2.2 so it uses was_ap22_module, older IHS built upon Apache 2.0 would use was_ap20_module). The second line loads the plugin-cfg.xml file which is propagated from WAS (is copied to IHS location to be strict).

Another common problem with IHS is that, WAS by default is configured to map its application on port 80 (the virtual host mapping * is set to 80). If the IHS will use different port then 80, be sure to correct this in the WAS.

Monday, November 22, 2010

Oracle datasource configuration on WAS

Lately, while configuring WebSphere Application Server 6.1 to Oracle 11g database connectivity via datasource I found that there is very little information in WAS documentation explaining couple of things.

The creation of datasource is very similar to other DBs but, the docs really don't say anything about the URL convenience. Sure, there is a sample but without any additional explanation.

  • jdbc:oracle:thin:@host:port:SID


Maybe for Oracle specialist it is clear but it wasn't for me ;-). Firs of all - what does 'thin' mean? Well, it means that we use the standard JDBC type 4 driver (which by default translate JDBC calls into DB calls). We can type also use 'thick', which would mean that we want to use older type (1 or 2) of ODBC drivers.

While configuring the datasource for Oracle on WAS you have to remember also that you have to supply user information (name of user in Oracle is related with database schema). If you won't supply the 'JAAS - J2C authentication data', WAS will report a confusing error about incorrect Oracle destination address. It is because you lack a valid user account.

The last thing about the Oracle configuration is the server. You will have to set a special variable for this:
ORACLE_JDBC_DRIVER_PATH
, which points to a directory with a driver jar. There are couple of versions available: ojdbc14.jar, ojdbc5.jar and ojdbc6.jar (build with Java version 1.4, 5 and 6).

Hope that helped someone :-).

Wednesday, November 17, 2010

How to find out what is consumig most of resources under UNIX

Today just a couple of handy UNIX commands, which I often use under AIX/Linux OS.

To list the 20 biggest files in the /opt file system:

find /opt -xdev -ls | sort +6 -nr | head -20


To list top 10 processes which consume most of CPU

ps aux | head -1; ps aux | sort -rn +2 | head -10


Additionally you can use top on Linux or topas or nmon on AIX.

To list top 10 processes which consume most memory

ps aux | head -1; ps aux | sort -rn +3 | head


And finally to find out java application processes (i.e. application servers)

ps -ef | grep java

Monday, October 11, 2010

Configuration of WebSphere Application Server with WebSphere MQ to implement Message Driven Beans part 2

In my last post I showed how to configure WebSphere Application Server with WebSphere MQ. In this post I will implement a sample Message Driven Bean and use it in this environment.

I want to stress that I will create MDB using EJB2.1 specification. I explained the reasons for that in previus post. To create and test the MDB I will use Rational Application Developer version 7.5, but any current version of Eclipse will be good enough.

To start with, let's create a Java Project. Under New Project wizard select EJB project. In next window input the project name (TestAppMDB in my case) and select EJB Module version to 2.1. Also be sure to add an EAR project for our MDB jar. My EAR project which I will deploy on WebSphere Application Server is TestAppMDBEAR. Click finish, we will use the default options for the rest of EJB configurations.



Now, we will create the MDB instance implementation. To do that, switch to Java EE perspective and open Deployment Descriptor. Under Bean tab click "Add..." button to add new bean. In the popup window select Message-driven-bean



For purpose of this sample, you can leave the default options and finish the creator wizard. Now we have to configure couple of settings of the bean. First find a WebSphere Bindings tab under the same Bean tab and select Listener Port checkbox. Under Listener port name type your listener port. In my case it is EmdebListenerPort.



Now another important thing - the references. Go to the next, References tab, select the bean and click Add... button again. A popup window will appear. We have to create two references - both of Resource reference type. Click next and fill the input of the next screen in the following way:



The most important thing is to select Type javax.jms.ConnectionFactory for the factory reference and javax.jms.Queue for the queue reference.



After creating both properties, select one of them. You should see the following screen:



Note that after creating a reference which is a local resource, we have to bind it with the real - JNDI resource. The place to do this is under WebSphere Bindings tab in JNDI name field. Type real JNDI context defined in the WebSphere in previous part. In my case it was jms/EmdebOutConnectionFactory. Remember to do the same thing for the queue definition.

After this part we can finally prepare some implementation. Remember that we will use local references to show the proper J2EE design pattern. The most important method of the MDB is onMessage, which is invoked when the bean instance is created. My, sample onMessage code looks like this:


public void onMessage(javax.jms.Message message) {
System.out.println("onMessage");

try {
if (message instanceof javax.jms.TextMessage) {

String recievedMsg = ((javax.jms.TextMessage) message)
.getText();
System.out.println("[EmdebBean] Recieved Text Message: "
+ recievedMsg);

System.out.println("Message ID: " + message.getJMSMessageID());
System.out.println("Correlation ID: "
+ message.getJMSCorrelationID());

String newTextMessage = "1400";

System.out.println("Messege to sent: " + newTextMessage);
sendResponse((javax.jms.TextMessage) message, message
.getJMSMessageID(), newTextMessage);

} else if (message instanceof javax.jms.BytesMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Bytes Message ");
} else if (message instanceof javax.jms.StreamMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Stream Message ");
} else if (message instanceof javax.jms.ObjectMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Object Message ");
} else if (message instanceof javax.jms.MapMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Map Message ");
} else {
System.out
.println("[EmdebBean] SAMPLE MDB: Unknown Message Type ");
}
} catch (javax.jms.JMSException e) {
...
} catch (Exception e) {
...
} finally {
...
}
}


Following method prints out the message, which it received and sends a response. To simplify the code I will show the rest of the logic inside on method (which reads properties for the JNDI resources). The code for sendResponse method:


public void sendResponse(javax.jms.TextMessage message, String messageId, String data) {

Context ctx = new InitialContext();
ConnectionFactory connFactory = (ConnectionFactory) ctx
.lookup("java:comp/env/jms/OutConnectionFactory");

connection = connFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = (Queue) ctx.lookup("java:comp/env/jms/OutQueue");
producer = session.createProducer(dest);

System.out.println("copying the msg id to corellation id");
message.setJMSCorrelationID(messageId);
message.clearBody();
message.setText(data);
System.out.println("Sending...");
producer.send(message);

System.out.println("Succesfully sent");
}


Remember about the catches and finally clause in your code and some better logging capabilities like common loggings or log4j. Not that in my code I rewrite the message ID to correlation ID. It is important for the client to let him know that this is a response for his request. Also note, thet I use local names to lookup JNDI resources:

  • java:comp/env/jms/OutConnectionFactory,

  • java:comp/env/jms/OutQueue


This is a clear and nice way to separete the configuration of JNDI in J2EE. And that's it. Now, you can test the MDB by deploying it in the application server environment and putting a sample text message in the queue.

You can check the response message attributes using RFHUtil tool for example - just like in my previous post.

Wednesday, September 29, 2010

Configuration of WebSphere Application Server with WebSphere MQ to implement Message Driven Beans part 1

In my last post I showed how to use DataPower Appliance in WebSphere MQ environment. Now I'll show you how to configure WebSphere Application Server to use MQ. This is first part of the configuration, the second part will deal with a sample implementation of Message Driven Bean which will be deployed on WAS.

I will not cover the MQ itself, I assume that you already have a Queue Manager with proper queues up and running. Preparing WebSphere MQ is a topic of its own, If you would like me to post an article about it write to me.

Anyway, let's get stared. What we want to achieve is to deploy an MDB on WAS which uses JMS over MQ to send messages. To prepare environment for the MDB log on to the WAS console. Oh, and one important thing though. I will use EJB2.1 standard, not the most recent one. Why? Well, commercial software - like WAS in opposite to open source is
evolving much slower. There are many reasons for that, but I don't want to deal with it now. One of them reason (technical) is that currently many people want to use WAS6.1, not the current WAS7.0. The older WAS6.1 has an ability to implement EJB3.0 by feature pack but the base product sticks to original J2EE 1.4 spec, plus a feature pack is not a 100% satisfactory solution (using it can cause another issues and so forth).

Let's start then. First we need a connection factory to connect to Queue Manager; this one will be used for the listeners which raise the MDB instance. In the WebSphere Application Console go to:
Resources > JMS > Connection factories. Now select appropriate WebSphere scope (if you don’t know which one, choose the cell scope and click new. Select the WebSphere MQ messaging provider as your provider and fill the information bellow:

  • Name (EmdebConnectionFactory)

  • JNDI name (jms/EmdebConnectionFactory)

  • Queue manager (Name of your QM)

  • Transport (Client)

  • Hostname (Hostname or IP of your QM)

  • Port (Port of your QM, 1414 if default)

  • Server connection channel (Channel name of your QM)


If the QM is secured you will also need to create a JAAS user alias providing a user name and his password and then selecting it in Component-managed authentication alias or Container-managed authentication alias depending what you need in the J2EE application.

Listener

To add a Listener you have to click through: Application servers > name of the server > Message listener service > Listener Ports and click New. Input the following information (you can use your own names). Note that the Initial State of the listener is started by default. It is useful in a debug environment but can cause trouble when we initially start the application and there are invalid messages in the queue or the connection to the Queue Manager cannot be established.



Connection factory for the MDB sender

The configuration is similar to the listener connection factory; I will only use different JNDI names:

  • Name (EmdebOutConnectionFactory)

  • JNDI name (jms/EmdebOutConnectionFactory)


This is what you should achieve in the WebSphere administrative console view after creating both connection factories:



Input queue for the listener connection factory
To create input queue, you have to select ‘Queues’ link bellow the ‘Connection factories’ link. Apply these values to add a new queue (remember to select the same scope):

  • Select JMS resource provider (WebSphere MQ messaging provider)

  • Name (EmdebInQueue)

  • JNDI name (jms/ EmdebInQueue)

  • Base queue name (MDB.IN)


Output queue for the MDB sender

  • Select JMS resource provider (WebSphere MQ messaging provider)

  • Name (EmdebOutQueue)

  • JNDI name (jms/ EmdebOutQueue)

  • Base queue name (MDB.OUT)


After creating both queues, you should see as follows:



And that's all for now. We prepared our WebSphere App Server to host the MDB. In the next part I will show how to create a sample MDB using Eclipse IDE.

Thursday, September 23, 2010

Integrating WebSphere DataPower Appliance with Custom J2EE Applications and WebSphere MQ

In this post, I'll deal with something a little bit different - but still tightly connected with Java environment. Lately I had a challenge and another opportunity to work with a very powerful machine - DataPower Appliance. To be precise, the XB60 and XI50 models.

To get started I have to say, that I will cover only the DataPower part, the whole solution is a topic of its own. Maybe a field for future posts. Oh, and because I was using WebSphere Application Servers as hosts of test applications I noted them on the drawing, but you can use any app server instead (any which support at least J2EE 1.3). The important thing is the MQ protocol which is specific for this case (MQMD and MQRFH2 headers).

The scenario

The scenario implemented in this article demonstrates an example of the DataPower appliance usability in a SOA environment pattern where we have a Service Provider and Service Consumer. In our case, the Service Consumer is simulated by a Java EE component (MDB) which runs on WebSphere Application Server and invokes an external service for particular information. The simulated, external system is also a JEE application (a web application). Each component is deployed in a separate environment and uses WebSphere MQ or HTTP protocol to communicate. Intentially I used two popular but different type of technologies (MDB and web based application) to demonstrate the feasibility and capabilities of Java and WebSphere environment.



Detailed steps of the scenario are as follows:

1. A valid XML message with RFH2 header is placed in a DP.INIT.IN queue using RFHUtil tool (for example, it could come from a business process - i.e. WebSphere Process Server).
2. DataPower gets the message from the DP.INIT.IN queue using Front Side Handler.
3. The message is processed by DataPower and then is being sent to web application.
4. The web application (servlet in this case) receives the message.
5. The servlet process the message and returns a HTTP result.
6. The DataPower picks up the HTTP response.
7. DataPower process the message and puts it in queue MDB.IN
8. The MDB component, which listens on MDB.IN queue picks it up and process it.
9. In the end the MDB puts it in the MDB.OUT queue.

Setting up the environment

Creating MQ Resources
Configuration of Application Server

- Connection factory for the listener
- Listener (or activation specification if you want to use EJB3.0 MDB)
- Connection factory for the MDB sender
- Input queue for the listener connection factory
- Output queue for the MDB sender

I explained above configuration in this post.

Configuration of DataPower appliance

Configuration of the DataPower Appliance will be explained in certain order. On this screen I show each of the steps of its configuration:



- Create new Multiprotocol Gateway

First of all create a new Multiprotocol Gateway using a wizard from the welcome page. In my case, I named it My_MQ_HTTP_MPGW (1)

- Configure the static backend

Be sure to switch the static-backend option (which is the default one) and in Backend URL (3) type the http URL of your service. In ma case it was

http://localhost:9081/SimpleWeb/testService but remember to type the real IP address of the server because DataPower appliance will not resolve the localhost host alias.

- Configure the Front Side Handler

Click the ‘+’ sign (4) to add a new Front Side Handler and select the MQ Handler and fill the wizard fields. On this screen I show the most important settings. Note that I switched on Rules and Formatting Header for MQRFH and MQRFH2. This is very important because it will allow DataPower to understand the messages putted using JMS into WebSphere MQ.




- Configure the message types

In my case I require the messages in the flow to be a valid XML messages so select both response and request type to XML (5)

- Configure the Policy for the Gateway

The last but very important step of the configuration is to set up the policy – which is what is going on inside the DataPower with the message. What we want to achieve is to receive a XML message, remember its MQ MessageId retrieved from MQMD header and sent it to backend. Then we want to receive response, add a new MQRFH2 header and copy the MessageId to CorrelationId (because we want the MDB or other listener to mach the response message with the sent request). To achieve this click the ‘+’ sign and create a following policy.



On the picture above you can see that I created a Policy with a name My_MQ_HTTP_Policy. In the policy I created two, one-way rules. First (Client to Server) rule maches all URLs and has got a Transform step. In the transform I used a following XSL style sheet to copy the MessageId and save it in the var://context/MQMD/messageId context variable:


<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform" dp="http://www.datapower.com/extensions" prefixes="dp">
<xsl:template match="/">
<!-- Retrieve old MQMD if it exists -->
<xsl:variable name="oldMQMD">
<xsl:value-of select="dp:request-header('MQMD')" escaping="yes">
</xsl:value-of>

<!-- copy the Message Id for later use (correlation) -->
<xsl:variable name="mqmd" select="dp:parse(dp:request-header('MQMD'))">
<dp:set-variable name="'var://context/MQMD/messageId'" value="normalize-space($mqmd//MsgId/text())">
<!-- copy all elements and their attributes-->
<xsl:copy-of select="node()">
</xsl:copy-of>
</dp:set-variable>
</xsl:variable></xsl:variable></xsl:template></xsl:stylesheet>


We will inspect this variable while testing the scenario.

In the second rule, I have used another XSL style sheet which makes a little more with the headers. This is my XSL template that I have used:

<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform" dp="http://www.datapower.com/extensions" prefixes="dp">

<xsl:template match="/">

<xsl:variable name="MQMDStr">
<mqmd>
<format>MQHRF2</format>
<correlid>
<xsl:value-of select="dp:variable('var://context/MQMD/messageId')">
</xsl:value-of>
</correlid>
</mqmd>

<xsl:variable name="MQMDStr2">
<dp:serialize select="$MQMDStr" decl="yes">
</dp:serialize>
<dp:set-response-header name="'MQMD'" value="$MQMDStr2">

<xsl:variable name="RFH2">
<mqrfh2>
<strucid>RFH</strucid>
<version>2</version>
<encoding>546</encoding>
<format>MQSTR</format>
<flags>0</flags>
<namevalueccsid>1208</namevalueccsid>
<namevaluedata>
<namevalue>
<mcd>
<msd>jms_test</msd>
</mcd>
</namevalue>
<namevalue>
<jms>
<dst>queue:///</dst>
<rto>queue:///</rto>
</jms>
</namevalue>
</namevaluedata>
</mqrfh2>

</xsl:variable>

<!-- SERIALIZED MQRFH2 HEADER -->
<xsl:variable name="rfh2Str">
<dp:serialize select="$RFH2" decl="yes">
</dp:serialize>
<dp:set-response-header name="'MQRFH2'" value="$rfh2Str">

<xsl:message priority="info">
<xsl:copy-of select="concat('New RFH2 header : ', $rfh2Str)">
</xsl:copy-of>

<!-- copy all elements and their attributes-->
<xsl:copy-of select="node()">

</xsl:copy-of>

</dp:set-variable>


Note that in the firs section I prepare a brand new MQMD header with two properties – Format and CorrelId. They are a minimum required by clients to understand the message. First one informs that this is a MQRFH2 message with additional information buried in the body and the other is the correlation identifier which is used to mach incoming responses with requests.

The second part of the transformation generates the MQRFH2 header with its attributes. Not all of them are required but I left them to give you a clue on how the MQRFH2 header might look like. We will inspect it in the RFHUtil tool as well.

Now, if everything went OK we have prepared environment to start unit testing.

Testing the end to end scenario

In order to test the scenario you will need a valid XML message with a RFH2 header. You can use my Initial_rfh2_request.zip file and load it into RFHUtil tool or generate your own (to do this you can simply put a text message in MDB.IN queue and get the MDB.OUT queue – it will contain a proper message). And of course you have to install two applications – your own or you can use mine bundled with all required resources for this article.

1. Check if both applications (MDB and web) are running and if the EmdebListener is up and running
2. Log on to DataPower console and turn on the Probe tool to investigate its internal traffic
3. Load the initialization message to the RFHUtil tool and check its properties
before sending

This is my sample message shown in XML format:



Message contains MQRFH2 header:



Message also contains a proper MQMD header - note that there is a proper (for MQRFH2) Message Format - MQHRF2 - and yes, it is typed correctly ;-):



4. Send it to DP.INIT.IN queue using send it button
5. Refresh the Probe in the DataPower console to see the results

There should be a successfully processed request and response in the Probe window:



Click the request to see its details:



As we can see, DataPower received our message. Click on the magnifying glass after the transform step. In order to see if the MessageId was properly saved in context variable click on ContextVariables tab:



That was exactly what we needed; the long alpha-numeric value is the message Id that we will use later on. Now close this window and return to the probe and click on the response:



As we can see the text is changed by the web application. Note also that the MQMD and MQRFH2 disappeared. It is because we received a HTTP request which doesn’t contain such information. Because we ware prepared for this case in the next, transform step click the magnifying glass icon next to it:




6. Open MQ Explorer or RFHUtil to check if the result message is placed inside MDB.OUT queue and if it contains proper headers
7. Optionally you can investigate the WebSphere Application Server and the J2EE application logs on both servers

Conclusion

This article demonstrates a valuable ability of DataPower to connect separate systems using different protocols (in this case HTTP and MQ), which use different types of headers and are technologically different.

In the article I showed how to build a valid RFH2 header which can be then processed by a JMS ready application (a common real life example) and also how to use the correlation id to inform the backend system about its reply (another common problem).

This is only a small part of the DataPower capabilities but shows its potential and power of customization and usability and also a clear pattern of how to use it.