Tuesday, August 14, 2007

New Enhancements for the XMPP Binding Component

We have some new enhancements for the XMPP Binding Component coming down the pipe this month. Already in place is the ability to join, leave, and send messages to group chats. You can join a group chat upon deployment or you can dynamically join/leave groups at runtime. Also in the works for this month are enhancing the XMPP BC to handle complex types. You can view the documentation for the WSDL Extensions here.

Wednesday, August 1, 2007

My Sports Rant

So, my favorite time of year is quickly approaching......Football Season. Lately I have been catching up on where my teams stand, and as usual someone is holding out for more money. This is my biggest problem with Pro Sports in general, causing me to be a bigger College sports fan. I get sick and tired of seeing athletes hold out for more money cause they have had a couple of good seasons. What happens if you have a bad couple of years, should the team be allowed to negotiate your contract down to what you deserve, oh no that is not how it works. I am a Chiefs fan, and as most sports fans know, Larry Johnson is holding out for more money. I can see where he is coming from in a way. He has been one of the best backs, if not the best, the last couple of years, and he does not make nearly as much as some of the other backs in the league, e.g. LT, Shaun Alexander, Edge, etc. My beef with all of this is what ever happend to honoring your contract. You are still making a lot of money, more than 90% of the people out there will make in a lifetime. Teams have to honor the contract no matter what, unless they want to cut you. At the end of the day I do not really blame the athletes, I blame the agents. Most of the time I think they ruin what is good about sports, they are not in this for the athletes, they are in it for themselves. Just this morning they were talking about Brady Quinn holding out for more money because he thought he should have been drafted higher, sorry buddy you did not so you get pick 22 money. Now go prove yourself on the field and get that money the next contract, what a novel thought .... proving yourself and earning that money.

I will get off my soap box now.......

Monday, July 30, 2007

Utilizing Installation Descriptor Extensions in JBI

JBI provides a means to add extensions to your Installation Descriptor (jbi.xml). These extensions can be used for a variety of different things, like configuration for your component. Working examples of components utilizing this feature check out the OpenESB HTTP Binding Component or ServiceMix HTTP Binding Component . Recently I needed to use this feature to add some configuration type attributes to the component we were developing. The first thing you will need to do is add the extensions to your installation descriptor. As noted in the API, the Installation Descriptor Extensions are located at the end of the <component> element of the installation descriptor, something like the following:


<component>
....
The rest of the jbi.xml
....
<config:Configuration>
<config:Port>8888</config:Port>
<config:Location>localhost</config:Location>
</config:Configuration>
</component>


During bootstrap init() the InstallationContext is passed in, this object gives you access to the Installation Descriptor Extensions, via installationContext.getInstallationDescriptorExtensions (Which returns a DocumentFramgment containing all Extensions). At this time you need to store the values in an object so that you can access them during the Components init(). The best way to achieve this is to use JMX. So the first thing you will need to do is Create an Interface that defines your MBean, and then create your class that will implement that interface. Something like the following:

public interface ConfigExtensionsMBean {
public void parseConfigExtensions(DocumentFragment documentFragment);
public String getLocation();
public int getPort();
}
Now we need to write our concrete class that implements this interface, something like the following:

public class ConfigExtensions implements ConfigExtensionsMBean {

private int port;
private String location;

public enum Attributes {Location, Port};

public String getLocation() {
return location;
}

private void setLocation(String location) {
this.location = location;
}

public int getPort() {
return port;
}

private void setPort(String port) {
this.port = new Integer(port);
}

public void parseConfigExtensions(DocumentFragment frag) {
//Parse the DocFrag here and call the setters for the port and location.
}
}
So now we have the Interface and the Concrete class, we just have to use it now. So the first thing we need to do is in your Bootstrap classes init() method we need to get the Installations Service Description Extensions and create our MBean and register that MBean in our MBean server, this should look something like the following:

public void init(InstallationContext context) {
ConfigExtensionsMBean mBean = new ConfigExtensions();
DocumentFragment doc = context.getInstallationDescriptorExtension();
mBean.parseConfigExtensions(doc);

MBeanServer mBeanServer = context.getContext().getMBeanServer();
ObjectName mBeanName = context.getContext().getMBeanNames().createCustomComponentMBeanName("MyMBean");
try {
if (!mBeanServer.isRegistered(mBeanName) {
ObjectInstance oi = mBeanServer.registerMBean(mBean, mBeanName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
So what we just did was read the extensions, parse them and call the setters, and registered the mBean for future use. So now our new component is ready to be initialized and needs access to that mBean. The following is how you can access them during ComponentLifeCycle.init(ComponentContext context):

public void init(ComponentContext context) {
MBeanServer mBeanServer = context.getMBeanServer();
ObjectName mBeanName = context.getMBeanNames()
.createCustomComponentMBeanName("MyMBean");

try {
host = (String) mBeanServer.getAttribute(mBeanName,
ConfigExtensions.Attributes.Location.toString());
port = (Integer) mBeanServer.getAttribute(mBeanName,
ConfigExtensions.Attributes.Port.toString());
} catch (Exception e) {
log.warning("Exception getting mBean Attributes: " + e);
e.printStackTrace();
}
}
So, there you have it, an example of how to utilize the Installation Descriptor Extensions from your jbi.xml.

Tuesday, July 24, 2007

Patterns and Matchers - java.util.regex Package

Recently I got the oppurtunity to utilize the java.util.regex package, which I had never used before, and found it very simple and handy to work with. As I look to do on my blog, I will share a simple example of how to match character sequences against patterns specified by regular expressions utilizing the Java API. So, as TDD goes we will write the test first and then develop our code against our unit test. If your not familiar with unit testing, you will need to download JUnit. Ok, we will start by creating our new test class.


import junit.framework.TestCase;
import java.util.List;

public class ProcessorTest extends TestCase {
String testData =
<test><name>Chad</name>Bob<name></name></test>;

public void testProcessor() {
Processor processor = new Processor();
List list = processor.processMessage(testData);
assertEquals("List was not correct size", 2, list.size());
assertEquals("Name did not match", "Chad", list.get(0));
assertEquals("Name did not match", "Bob", list.get(1));
}
}


This will obviously fail since we haven't created our Processor class yet, so lets go ahead and create our new Class, and then we can run our unit test to verify that our code is doing what we want it to do.

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.List;
import java.util.ArrayList;

public class Processor {

public List processMessage(String text) {
String pattern1 = <\\w*?name>>;
String pattern2 = </\\w*?name>;
List result = new ArrayList();
Pattern p1 = Pattern.compile(pattern1);
Pattern p2 = Pattern.compile(pattern2);
Matcher m1 = p1.matcher(text);
Matcher m2 = p2.matcher(text);
while ((m1.find()) && (m2.find())) {
result.add(text.substring(m1.end(), m2.start()));
}
return result;
}
}


Now we can run our unit test again and our test will pass. So this is just a simple example of how to use the Matcher and Pattern class provided as part of the JDK, and how to utilize Unit Testing to test your code.

Monday, July 23, 2007

Using Grizzly to read TCP Packets

Recently I had the need to be able to listen on a port and read TCP packets that were sent from a logger (java.util.SocketHandler), and I wanted to utilize the Grizzly framework to do this. With some help from the Grizzly team I was able to accomplish this and thought I would share what I did. The first thing I had to do was write a main that could connect to a port and receive TCP packets, it looked something like the following:

public class TCPProcessor {
public static void main(String[] args) throws Exception {
int port = Integer.getInteger(args[0]);

Controller controller = new Controller();
TCPSelectorHandler tcpHandler = new TCPSelectorHandler();
final MyProtocolFilter filter = new MyProtocolFilter();

tcpHandler.setPort(port);
controller.setProtocolChainInstanceHandler(new DefaultProtocolChainInstanceHandler() {
public ProtocolChain poll() {
ProtocolChain protocolChain = protocolChains.poll();

if (protocolChain == null) {
protocolChain = new DefaultProtocolChain();
protocolChain.addFilter(new ReadFilter());
protocolChain.addFilter(filter);
}

return protocolChain;
}
});
controller.addSelectorHandler(tcpHandler);
controller.start();
}
}
Now that I have my main listening, I need to write the Filter that will handle the processing of the data packet. With the ProtocolChain, the ReadFilter will read the TCP packets and pass it to the next filter in the chain, which is were I need to process my data. My filter will look something like the following:
public class MyProtocolFilter implements ProtocolFilter {
public boolean execute(Context context) {
final WorkerThread workerThread = ((WorkerThread)Thread.currentThread());
String message = "";
ByteBuffer buffer = workerThread.getByteBuffer();
buffer.flip();

if(buffer.hasRemaining()) {
byte[] data = new byte[buffer.remaining()];
int position = buffer.position();
buffer.get(data);
buffer.position(position);
message = new String(data);
}
System.out.println("New message being read, message is: " + message);
buffer.clear();
return false;
}

public boolean postExecute(Context context) throws IOException {
return true;
}
}

So now you could whip up a test to send some data over TCP and the Processor will read the packets and print the message out.