Search This Blog

Loading...

Tuesday, June 23, 2009

Scaling in the JMS World...in particular Topics

Scalability and Availability in JMS. For the former, as load on the messaging system increases, one would want to be able to service the increased messages without performance degradation. For the latter, one should ensure the reduction if not elimination of single point of failures, i.e., ensuring system is available for use.

Most JMS Providers have some sort of mechanism for addressing the above. This BLOG is however only going to concentrate on Oracle WebLogic.

WebLogic has an interesting way in which JMS Destinations (Queues and Topics) are scaled via Distributed or Virtual Destinations. A Virtual Destination can be considered a sort of router/load balancer that distributes messages it receives over to actual or physical destinations. Each physical destination would reside in separate WebLogic instances on potentially separate hardware. See figure below where a virtual destination "test_queue" has physical members test_queue_1, test_queue_2 and test_queue_3 on separate WebLogic instances:



As an example of Virtual Queues in action, in the conceptual figure shown below, Producers send messages to the Virtual Queue which then directs the message to one of the physical destinations



P : Producers
VQ: Virtual Queue
PQ-X: Physical Queue, where X is the number of the Queue
C: Consumer
M: Message

In the case of a Virtual Topic, messages sent to the Virtual Topic are sprayed on to each and every physical member as shown in the figure below where VT and PT-X represent Virutal and Physical topics respectively:


Scaling Queues:
From the figure shown regarding Queues, it is pretty simple to follow how the system scales and that it will continue to service new messages and consume them should one of the servers in the messaging cluster fails. A message will be consumed at most by one of many consumers successfully. Adding Consumers to the end of the physical members allow the architecture to process messages rapidly, i.e., Competing Consumer Design Pattern.

Now, what if one of the servers having physical members went down, for example VQ-1 went down? From the perspective of availability, messages are still flowing and getting consumed from the other available member, i.e., VQ-2. What about the messages that were in the physical member whose server went down? One has multiple options. The first and most straight forward is to restart the server and re-connect the consumers to drain the queue. WebLogic allows for auto-service migration in the event of failure. This is another feature that can assist in recovering from failure. Queues readily tend to present themselves for scaling. One note on the same, if message ordering is put into play, all bets are off :-)..more on the same on a subsequent blog.

Scaling Topics:
Topics unlike Queues present an interesting challenge. In the case of a topic, a message is delivered to all listeners of the topic and each listener is typically different than its peer in how it handles the message. For example a message posted to an order topic, might have a consumer that processes the order while another one looks at inventory calculations:


Clearly we cannot have two consumers that process the same order and it is redundant to have duplicate consumers perform the same inventory calculations.

Messaging systems have the concept of a Durable Subscriber, i.e., a Message listener who registers with the topic such that they are delivered messages sent to the topic even when the listener is not connected. Message providers store the message on behalf of the durable subscriber and forward the same when the subscriber comes back on line.

In WebLogic one cannot connect to a durable subscriber using a distributed (virtual) destination JNDI. One has to explicitly register with a physical member. This is one gripe that I have with the WebLogic solution. Adding to the problem, should one connect to one physical member and if that member goes down, attempting to establish the durable subscription on other available members are treated like totally new subscriptions. In consolation, if the server goes down that contains durable subscriptions, then messages will be stored on other physical members of the virtual topic on behalf of the durable subscribers, and when the server is restored, messages get forwarded to the durable subscribers when they comes back on line as shown below:


Now, as each subscriber of the topic has a unique agenda from the other subscribers, the fact that it is the sole entity that services the message, the same represents a single point of failure and a proves a scalability inhibitor as it cannot concurrently process multiple messages.

So how can one scale a topic so that a message on a given type of subscriber can be rapidly processed? One direction is have the consumer of a Topic post the message onto a Queue which can then be processed by competing consumers. One way this can be achieved is to have a Message Driven Bean withing the container whose sole purpose is to transfer the message from the topic to a queue for those consumers that need to scale. An example of the same is shown below:


In the above shown example, as one consumer of the topic needs processing to rapidly occur of messages received, an MDB (registered as a durable subscriber of the topic) is used to transfer every message onto a Queue which is then consumed by competing consumers. As other consumers, DC-1 and DC-2 are not in need of scaling, they remain durable single subscribers.

The above solution works to scale the durable subscriber of a topic. However, in WebLogic when using distributed topics the durable MDB still represents a single point of failure.

A question to ask at this point is, "Do you really need a topic for the use case at hand?" Topics are great IMO when the subscribers tend to be dynamic in nature or do not need to be durable, an example of the former is a stock quote topic and an example of the latter is a event listener that requires notification of an event.

When the number of subscribers are a known or finite in amount, the use of a queue coupled with the MDB can easily achieve a scalable solution as shown below where the MDB transfers messages on the in-queue to subsequent out-queues where competing consumers can scale and consume the messages:



Transfer MDB:
It is pretty trivial to create the Transfer MDB. One would typically like to re-use the Transfer MDB Java Code with only configuration changes for different applications. The same can easily achieved via separate projects where target destination can be provided via @Resource. A simple transfer MDB is shown below:



@MessageDriven
@TransactionAttribute(TransactionAttributeType.REQUIRED)

public class MessageRouterMdb implements MessageListener {

/**
* Map this jms connection factory to the actual one in the weblogic-ejb-jar.xml deployment
* descriptor of the ejb project. The Connection factory to be used will be the one that is
* specific to this mdb.
*/

@Resource(name = "jms/connectionFactory")

private ConnectionFactory connectionFactory;

/**
* Injected in Message Driven Context
*/

@Resource
private MessageDrivenContext mdc;

/**
* Define a comma separated list of destinations JNDI names in the ejb-jar.xml via an environment
* entry.
*/

@Resource
private String targetDestinations;

// Initialized
private List<Destination> targetJmsDestinations;

private MessageProducer messageProducer;

private Connection connection;

private Session session;

@PostConstruct
public void init() {
try {

InitialContext ctx = new InitialContext();
connection = connectionFactory.createConnection();

session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

messageProducer = session.createProducer(null);
String[] targetDestArray = StringUtils.split(targetDestinations, ",");

targetJmsDestinations = new ArrayList<Destination>();

for (String targetDest : targetDestArray) {

targetJmsDestinations.add((Destination) ctx.lookup(targetDest));

}

connection.start();
}
catch (Exception e) {
throw new RuntimeException("Error Initializing Message Router Mdb", e);

}
}

public void onMessage(Message message) {

try {
// Loop through target destinations and send message to each destination
for (Destination dest : targetJmsDestinations) {

messageProducer.send(dest, message);
}
}

catch (Exception e) {
mdc.setRollbackOnly();

}
}

@PreDestroy
public void cleanup() {

// Close open jms resources here...
}
}




The CODE for the above MDB and an example Maven Project that uses WebLogic is available for download HERE. Note that the code is not specific to WebLogic and can really be used in any container, for example JBoss.

Conclusion:

Scaling topics via an MDB and target queues just felt like an obvious pattern to me. WebLogic, like many JMS Providers has the concept of a Message Bridge. Initial investigation led me to believe that a message bridge more serves the purpose of transferring a message from one provider to to another rather than serving to scale a Topic and distributed messages to multiple destinations.

There may be cases as mentioned where the number of subscribers are not known. In such a case, a topic might work and it becomes the responsibility of the subscribers to scale on their end, for example multi-threading upon receiving the message.

What really would be nice if the JMS specification had the concept of "Durable Competing Consumers" where a Durable subscriber could register multiple instances of itself such that a message to a topic would be delivered to at most it or one of its clones :-). I believe there are some Messaging providers who permit such a pattern via customization that extend the JMS specifications.

Before bidding adieu, this has been one of my most figurative blogs, all Ye artists, look at the diagrams with a forgiving eye, "I am a programmer not an artist!" :-)

Wednesday, June 3, 2009

Enjoying parents visit

Dad and Mom are visiting us from India. The home is so lively. Kids have taken to their grand parents. My daughter is literally an appendage of her Grandma at the moment. Dad although has been fighting time, is as vibrant as ever with his humor and condemnation of everything I do and anything I own :-)...Thats expected and welcomed, he wouldn't be the same without it...

I had an option of going to Java One, however had to pass as dad and mom were visiting. In hindsight, it was clearly the right choice as I really enjoy their company..:-)

Dad will be able to celebrate his birthday soon, I am hoping for a trip to a place where the entire family can celebrate, i.e., bro and gang + us. Don't know how many of these chances we will have where the entire family can be at the same place at the same time on an occasion. Got to make the most of the oppurtunity.

Also badly in need of a break from work at his point...feeling burnt but hanging in there..proud of my resiliency.

Going back in time seeing dad and mom, mom of course is pampering me considerably, and I am taking it all in...she wants to make me fat..and I am all for it ;-))

Thinking of the movie Kabhi Kushi Kabhi Gham...its all about loving your parents...;-) Hope my kids turn out similar...taking tips from dad and mom...

Is Facebook killing my blog? Something I am pondering about...

Friday, May 22, 2009

Ending the drought...

Its been a month since I posted anything on my BLOG, cannot let May end with a drought. It has been rather a trying month for me, the reasons I am saving for a later melodramatic post ;-)...

Right now I am very happy. At the company I currently work at, we released out a JMS architecture with minimal hiccups. It was very gratifying to witness the entire team involved work and mesh so well in order to make the architecture work. Everyone from Architects, Developers, System Administrators, Testers worked so well together. I must state that my level of confidence in the team and players involved was so much that I did not even have to be there during the go live in person. Put it in a word, my current organization is so much about "WE" and not "ME". That is a motto that works IMHO. Guess my current organization is very talented in its selection process of the people they want on board.

I truly enjoyed working with all the folks on the various facets involving the deployment of the architecture, frameworks, deployment, projects etc. We suffered a few hiccups after the deploy as well but the messaging solution itself was 100% solid. In fact in my own retarded way, I appreciated the fact that the failures occurred as they served to demonstrate that the failure path in fact worked ;-)

Personally, I have experienced considerable growth in the areas of JMS Messaging. However, every once so often I again am humbled by what I don't know or did not anticipate.

The project as a whole was like our baby that finally saw the light..and danced on...I hope it keeps dancing :-))))))))))) Even if does not, I believe we have a team strong enough to put it on crutches to make it so...

I can't wait for further adoption of the architecture...so thrilled, had a blast...

More BLOG's coming up soon, the little GREY cells were on vacation (not dead, just vacationing), you should see something from them soon....

Friday, April 24, 2009

Browsing Weblogic JMS Distrubuted Queues

On of the interesting features of Weblogic is that when javax.jms.QueueBrowsers are created, they are pinned to a particular physical member of a distributed destination. What that means is that a QueueBrowser created for a distributed destination will only be able to browse messages on the member it gets pinned to and not the whole queue.

One can try to create X number of queue browsers based of the number of servers in the provider URL, for example, "t3://localhost:8002, localhost:8003", and hope that no two queue browsers will pin to the same destination, i.e., at the mercy of Weblogic round robin if possible. Even if we do manage to do that, one still needs to iterate over X separate enumerations in order to manage the message. Consider an integration test where one sends a message to a distributed destination and would have to create X queue browsers to determine whether or not the message is present.

What would be really nice is if the Weblogic runtime gave us a QueueBrowser that provided an enumeration of enumerations of the physical members of a distributed queue. That however is not present. So, I decided to create a simple example that would help me with the same. At the same time, I am interested in understanding the JMX capabilities of Weblogic.

The example will create a QueueBrowser and obtain an enumeration from each of the physical members of the distributed destination and provide back an enumeration of the respective enumerations. In the case of uniformly created distributed destinations, the JNDI name of the physical members will be of the format JMSServerName@JNDIName. If one knows the JMSServerName thats great. However, one should not have to rely on the same as JMSServers might be added/removed. It would be nice if the distributed member JNDI names could be located on the fly by using Weblogic's JMX capabilities and thats what I intend to do. Note that the enumerations obtained in Weblogic are snapshots of the current state of the queue and are not dynamic, i.e., new messages added being dynamically reflected in the enumeration. Finally, I am providing a java.util.Enumeration for the JMS messages instead of an java.util.Iterator as Enumeration does not have a "remove" method and I hate putting an "UnsupportedOperationException" in the Iterator and also I would like to be true to the JMS API.

So first obtaining the JNDI name of physical members of a distributed queue. Weblogic JMX is a tree for objects. Once we obtain the ServerRuntimeMBean information, we can obtain information about the JMSRuntimeMBeans and then the different JMSServers and finally the JNDI names of the JMS Servers as shown below:



public class WeblogicMBeanHelper {
private final MBeanServerConnection connection;

private final JMXConnector connector;

private final ObjectName service;

public WeblogicMBeanHelper(String url, String userName, String password) {

try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");

}
catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());

}
......
......
JMXServiceURL serviceURL;

try {
serviceURL = new JMXServiceURL("t3", hostName, Integer.valueOf(port), jndiroot + mserver);

Hashtable<String, String> h = new Hashtable<String, String>();

h.put(Context.SECURITY_PRINCIPAL, userName);
h.put(Context.SECURITY_CREDENTIALS, password);

h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);

connection = connector.getMBeanServerConnection();
}
catch (Exception e) {

throw new RuntimeException(e);
}
}

public Iterable<String> getDistributedMemberJndiNames(String distributedDestJndiName) {
Iterable<String> serverNames = getJmsServerNames();

Set<String> distributedDestNames = new TreeSet<String>();

for (String serverName : serverNames) {
distributedDestNames.add(serverName + "@" + distributedDestJndiName);

}

return distributedDestNames;
}

public Iterable<String> getJmsServerNames() {

.....
}

public Iterable<ObjectName> getJMSServers() {

....
}

public Iterable<ObjectName> getJMSRuntimes() {

....
}

public List<ObjectName> getServerRuntimeMBeans() {

try {
return Arrays.asList((ObjectName[]) connection.getAttribute(service, "ServerRuntimes"));

}
catch (Exception e) {
throw new RuntimeException("Error obtaining Server Runtime Information", e);

}
}

public void close() {

// Close the connector
....
}
}





public class WeblogicMBeanHelper {
private final MBeanServerConnection connection;

private final JMXConnector connector;

private final ObjectName service;

public WeblogicMBeanHelper(String url, String userName, String password) {

try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");

}
catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());

}
......
......
JMXServiceURL serviceURL;

try {
serviceURL = new JMXServiceURL("t3", hostName, Integer.valueOf(port), jndiroot + mserver);

Hashtable<String, String> h = new Hashtable<String, String>();

h.put(Context.SECURITY_PRINCIPAL, userName);
h.put(Context.SECURITY_CREDENTIALS, password);

h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);

connection = connector.getMBeanServerConnection();
}
catch (Exception e) {

throw new RuntimeException(e);
}
}

public Iterable<String> getDistributedMemberJndiNames(String distributedDestJndiName) {
Iterable<String> serverNames = getJmsServerNames();

Set<String> distributedDestNames = new TreeSet<String>();

for (String serverName : serverNames) {
distributedDestNames.add(serverName + "@" + distributedDestJndiName);

}

return distributedDestNames;
}

public Iterable<String> getJmsServerNames() {

.....
}

public Iterable<ObjectName> getJMSServers() {

....
}

public Iterable<ObjectName> getJMSRuntimes() {

....
}

public List<ObjectName> getServerRuntimeMBeans() {

try {
return Arrays.asList((ObjectName[]) connection.getAttribute(service, "ServerRuntimes"));

}
catch (Exception e) {
throw new RuntimeException("Error obtaining Server Runtime Information", e);

}
}

public void close() {

// Close the connector
....
}
}




Now that we have a way of obtaining the distributed members, the following represents the QueueBrowser that enumerates over the different members and consolidating the same into a single enumeration. I have a second enumeration that provides information regarding the JMServer that hosts the given message:



public class DistribuedQueueBrowser {
...
private final Iterable<String> queueNames;

public DistribuedQueueBrowser(String adminUrl, String providerUrl,
String distributedDestinationName, String userName, String password) throws Exception {

ctx = getInitialContext(providerUrl, userName, password);
WeblogicMBeanHelper helper = null;

try {
helper = new WeblogicMBeanHelper(adminUrl, userName, password);

queueNames = helper.getDistributedMemberJndiNames(distributedDestinationName);
}
finally {

if (helper != null) {
helper.close();

}
}

// Set up connection/session..
....
}

private InitialContext getInitialContext(String providerUrl, String userName, String password) throws Exception {

....
}

// Retrun an Enumeration of Messages only
public Enumeration<Message> getEnumeration() throws JMSException, NamingException {

return new JmsMessageEnumeration(getMessageEnumeratorMap());
}

@SuppressWarnings("unchecked") private Map<String, Enumeration<Message>> getMessageEnumeratorMap() throws JMSException,
NamingException {

Map<String, Enumeration<Message>> serverMessageMap = new HashMap<String, Enumeration<Message>>();

for (String queueName : queueNames) {
String serverDq[] = StringUtils.split(queueName, "@");

Queue queue = (Queue) ctx.lookup(queueName);

javax.jms.QueueBrowser qb = session.createBrowser(queue);

serverMessageMap.put(serverDq[0], qb.getEnumeration());

}

return serverMessageMap;
}

// Return an enumeration of ServerLocatedMessage that contains the
// the jms server that houses the message

public Enumeration<ServerLocatedMessage> getServerLocatedEnumeration() throws JMSException,
NamingException {

return new ServerLocatedMessageEnumeration(getMessageEnumeratorMap());
}

public static class ServerLocatedMessage {
private final Message message;

private final String jmsServerName;

public ServerLocatedMessage(String jmsServerName, Message message) {

this.message = message;
this.jmsServerName = jmsServerName;

}
...
}

private static abstract class AbstractMessageEnumeration<T> implements Enumeration<T> {

Map.Entry<String, Enumeration<Message>> current;
private Enumeration<Message> currMessageEnumer;

private final Iterator<Map.Entry<String, Enumeration<Message>>> iterator;

public AbstractMessageEnumeration(Map<String, Enumeration<Message>> map) {

iterator = map.entrySet().iterator();
current = iterator.hasNext()

? iterator.next()
: null;
currMessageEnumer = current != null

? current.getValue()
: new Enumeration<Message>() {

public boolean hasMoreElements() {
return false;

}

public Message nextElement() {
throw new NoSuchElementException();

}
};
}

Enumeration<Message> getEnumeration() {

if (current == null || currMessageEnumer.hasMoreElements()) {

return currMessageEnumer;
}

while (iterator.hasNext()) {

current = iterator.next();
currMessageEnumer = current.getValue();

if (currMessageEnumer.hasMoreElements()) {
return currMessageEnumer;

}
}

return currMessageEnumer;
}

public boolean hasMoreElements() {
return getEnumeration().hasMoreElements();

}
}

// Wraps the JMS Message within a ServerLocatedMessage object
// which contains the server name along with the message
private static class ServerLocatedMessageEnumeration extends

AbstractMessageEnumeration<ServerLocatedMessage> {

public ServerLocatedMessageEnumeration(Map<String, Enumeration<Message>> map) {

super(map);
}

public ServerLocatedMessage nextElement() {

Message message = getEnumeration().nextElement();
return new ServerLocatedMessage(current.getKey(), message);

}
}

private static class JmsMessageEnumeration extends AbstractMessageEnumeration<Message> {

public JmsMessageEnumeration(Map<String, Enumeration<Message>> map) {
super(map);

}

public Message nextElement() {
return getEnumeration().nextElement();

}
}

public void close() {

......
}
}



Using this QueueBrowser is rather straight forward and can be done via:



// Note that the first argument is the admin url and the second is the
// managed server url.
DistribuedQueueBrowser qb = new DistribuedQueueBrowser("t3://localhost:7001",
"t3://localhost:8001",
"test_queue", "weblogic", "weblogic");

Enumeration<Message> i = qb.getEnumeration();
while (i.hasMoreElements()) {

Message m = i.nextElement();
System.out.println("Message:" + m);

}

Enumeration<ServerLocatedMessage> sli = qb.getServerLocatedEnumeration();

while (sli.hasMoreElements()) {
ServerLocatedMessage m = sli.nextElement();

System.out.println(m);
}
}



The code for the same is available HERE. The zip file contains only the JAVA files. One would need to compile the same with weblogic's client jar's and then use them. Let me know if you have problems running the code or if you have any tips regarding the code.
Later...

Saturday, April 18, 2009

Aspect J Maven and Logging

At my earlier job, I had looked at Aspect Oriented programming with Spring. I used the same for transactions. I wanted to use it for Logging method enter/exits as well but abandoned the same as one would need to use Spring's native AspectJ weaving. I was not ready to take that on at the time. Another option was to use AspectJ compile-time weaving, again, not something I had the time for and simply settled on Transactional support with Spring Aspects.

So what am I upto? I wanted to play with AspectJ and how compile time weaving on maven project would help me eliminate the logging.

Enter and exit of methods are quite useful, especially when debugging. Another use case of debugging would be to trace the method arguments passed to a method. In addition, performance of profiling method executions has its benefits. In an earlier blog post I had investigated the use of Java Instrumentation to assist with profiling.

So I start by creating a logging Aspect. If the logging level is set as DEBUG, it will LOG entry and exit of a method. If the level is set as TRACE, then the time for method execution is also logged along with the method arguments to the method. The following represents the Aspect:



import org.aspectj.lang.*;
import org.apache.log4j.*;

public aspect LoggingAspect {

Logger LOG = Logger.getLogger("trace");

// Execute on all methods except this Logging Aspect

pointcut traceMethods()
: execution(* *.*(..)) && !within(LoggingAspect);

// Around each method do the following
Object around() : traceMethods() {

Signature sig = thisJoinPointStaticPart.getSignature();

String baseEnterMessage = "Enter [" + sig.getDeclaringType().getName() + "." + sig.getName() + "] ";


if (LOG.isTraceEnabled()) {
Object[] args = thisJoinPoint.getArgs();


if (args.length > 0) {
StringBuilder argsBuilder = new StringBuilder(20);

argsBuilder.append(baseEnterMessage).append(" Args :");

for (int i = 0; i < args.length; i++) {

argsBuilder.append("{Index [" + i + "], Value [" + args[i] + "]}");

if (i != args.length - 1) {

argsBuilder.append(",");
}
}
argsBuilder.append("}");


LOG.trace(argsBuilder.toString());
}
else {

LOG.trace(baseEnterMessage);
}
}
else if (LOG.isDebugEnabled()) {

// Print base debug without arguments
LOG.debug(baseEnterMessage);
}

long start = System.currentTimeMillis();


try {
Object result = proceed();
return result;

} finally {
String baseMessage = "Exiting [" + sig.getDeclaringType().getName() + "." + sig.getName() + "].";


if (LOG.isTraceEnabled()) {
// If trace is enabled, print the time for execution.
long end = System.currentTimeMillis();

LOG.trace(baseMessage + "Completed in:" + (end - start) + " millis");

} else if (LOG.isDebugEnabled()) {
LOG.debug(baseMessage);

}
}
}



Another nice use of Aspects is to be able to enforce compile time standard checks. Maybe Find Bugs has a way to already do this. Not sure. Anyway, say for example, we want to detect when there are System.out.println() calls in the code or maybe the code in question is using some Class/Framework that we do not approve of, with Aspects and compile time checking there is a nice way out. I quite liked reading the blog by Jacob Matute on the compile time enforcement of standards. What I envision is the inclusion of a simple jar in project that can/will enforce the standards one desires. I think this might be preferable over depending on IDE based configuration of plugins.

What about method invocations where checks are performed? For example in many methods we repeat code that checks if an argument is null and throws some exception? What if one could declare an annotation on the method and an aspect check for the annotation to handle the same for you? The code becomes cleaner IMO. I think Java 7 will have this feature. Till then one can create an @NotNull annotation on a parameter and have aspects handle the exception throwing part for you across your entire code base. Andy Clement's blog discusses the same very nicely.

As I used maven for all my projects, there is a plugin from codehaus, for integrating AspectJ into maven.

For the sake of demonstration, I have a simple, fictional and potentially farcical objects that would undergo the tests of the Aspects:



public class Order {
private final Long id;

private final String userName;
private final Random random = new Random();


public Order(Long id, String userName) {
this.id = id;

this.userName = userName;
}

public String getUserName() { return userName; }


public int getTotalCost(int range) {
System.out.println("Calculating Cost...");

try {
Thread.sleep(2000L);
} catch (InterruptedException e) {}

return getRandom(range);
}

private int getRandom(int range) { return random.nextInt(range);}

}



An even trivial use of the Order object which is not even a unit test is shown below:



@Test
public void testOrderModel() {

Order order = new Order(23L, "Foo");

System.out.println("Order UserName:" + order.getUserName());

System.out.println("Order Total cost:" + order.getTotalCost(113));

System.out.println(Util.concatName("Sanjay", "Acharya"));

}



When I run "mvn install", I notice the following depending on the logging level I have setup in my log4j.properties, i.e., DEBUG or TRACE:



-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.welflex.model.ModelTest
Enter [com.welflex.model.Order.getUserName]
Exiting [com.welflex.model.Order.getUserName].Completed in:0 millis
Order UserName:Foo
Enter [com.welflex.model.Order.getTotalCost] Args :{Index [0], Value [113]}}
Calculating Cost...
Enter [com.welflex.model.Order.getRandom] Args :{Index [0], Value [113]}}
Exiting [com.welflex.model.Order.getRandom].Completed in:0 millis
Exiting [com.welflex.model.Order.getTotalCost].Completed in:2000 millis
Order Total cost:40
Enter [com.welflex.model.Util.concatName] Args :{Index [0], Value [Sanjay]},{Index [1], Value [Acharya]}}
Exiting [com.welflex.model.Util.concatName].Completed in:1000 millis
SanjayAcharya
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.12 sec



Parting Thoughts:
I think Aspects are rather powerful. There is plugin support for Aspects as well. For cross cutting concerns, use of Aspects is the way to go IMHO. Finally, although this is a maven project using JDK 1.5, there is no reason why this applies to maven only or cannot be used on previous versions of the JDK.

A maven project that demonstrates the above is available for download HERE
. One problem that I faced was getting the maven-aspectj plugin to install correctly. If you do install the same, you might want to add the codehaus repository to the pom.xml to ensure that the plugin is downloaded. To execute the project, from your command line, issue a "mvn install". There is a log4j.properties file in the project whose logging level you can tweak to see differences.

Enjoy :-)!

Saturday, April 11, 2009

Weblogic JMS Standalone Multi-threaded Client Security

I have been building a helper library that provides some convenience functionalities and all of a sudden it started failing with authentication exceptions. Not on obtaining Jms artifacts but during the send of a message. Jeez! One part of me says let go, deal with it on Monday, the other part is hungry to find out why. No prizes for guessing which part of me won :-)

The story so far:

Weblogic client runtime stores credentials in a ThreadLocal of the Thread that creates an InitialContext to obtain a jms resource, i.e., equivalent of saying the thread that has the credentials can execute privileged operations on certain JMS resource but as other threads do not have the credentials and thus, they cannot. Weblogic's security will obtain the information from the ThreadLocal and use the credentials therein for send/receive operations.

Now, in a Jms environment, one would like to create multiple javax.jms.Session, javax.jms.MessageProducer and use multi-threading where appropriate, sharing the same JMS connection. Think of a Servlet container that has multiple threads. If Jms artifacts (Connection factories, Destinations) are obtained only once using a Singleton by one of the Container's thread's, then it is only this thread that can send/receive messages from a JMS destination if the destination has security enabled on the same. The operation of creating a Context places a javax.security.auth.Subject in the ThreadLocal of the thread creating the Context. If the context is closed, the Subject is removed.

Consider the following example where the jms artifacts are obtained in a single thread of execution and a message is sent in the same thread:



public void sameThreadCreateSend() throws Exception {

InitialContext ctx = getInitialContext();

ConnectionFactory connectionFactory = (ConnectionFactory) ctx

.lookup("Connectionfactory");
Destination destination = (Destination) ctx.lookup("test_queue");

// Closing the context causes the send authentication exception
// ctx.close();

Connection connection = connectionFactory.createConnection();

connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(destination);

// Fails to send message as closing of the context removes the security information

// from the Thread local. If the context is kept open, then it works great.
producer.send(session.createTextMessage());
System.out.println("Sent message when send was called on thread that created context...");

}





In the above example, the message gets sent successfully, What about a case where the Jms artifacts are created on one thread and a thread created from the creator thread tries to send a message? Will the permissions get propagated to the child thread? Look at the code below:



public void testInheritableThreadSend() throws Exception {

InitialContext ctx = getInitialContext();

// Current Thread has the security information
final ConnectionFactory connectionFactory = (ConnectionFactory) ctx

.lookup("connectionfactory");
final Destination destination = (Destination) ctx.lookup("test_queue");

// This thread will have the security as well due to Inheritable thread local
Thread t = new Thread() {

@Override public void run() {
try {

final Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(destination);
producer.send(session.createTextMessage());

System.out.println("Sent message using inheritable thread local...");
}
catch (Exception e) {

e.printStackTrace();
}
}
};

t.start();
t.join();
}




Yes the above code sent a message successfully as the credentials in the parent are propagated to the child thread via Inheritable thread local.

Now what about a case where the creation of the Jms artifacts are created on a thread that is not the parent of the thread that sends the message using those artifacts? Look at the sample below:



public void createOnSeparateThread() throws Exception {

// First thread opens a context and had the credentials
ResourceCreator c = new ResourceCreator();

c.start();
c.join();

// Second thread is not a child of the first, thus does not have the security
NonCreatorThreadRunner n = new NonCreatorThreadRunner(c);

n.start();
n.join();
}

private class ResourceCreator extends Thread {
InitialContext ctx;

Destination destination;

Connection connection;

@Override public void run() {

try {
ctx = Example.this.getInitialContext();

connection = ((ConnectionFactory) ctx.lookup("connectionfactory"))

.createConnection();
destination = (Destination) ctx.lookup("test_queue");

}
catch (Exception e) {
e.printStackTrace();

}
}
}

private class NonCreatorThreadRunner extends Thread {

private final ResourceCreator resourceCreator;

public NonCreatorThreadRunner(ResourceCreator resourceCreator) {

this.resourceCreator = resourceCreator;
}

@Override public void run() {

try {
resourceCreator.connection.start();
Session session = resourceCreator.connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(resourceCreator.destination);

producer.send(session.createTextMessage());
System.out.println("Sent message when context was created on a separate thread...huh ???");

}
catch (Exception e) {
e.printStackTrace();

}
}
}




So the above send operation failed. Why? Because the second thread does not have the security credentials in its ThreadLocal. Now what if we could use the security information from the first thread on the second thread? We can, using weblogic security classes and using the javax.security.auth.Subject to execute a javax.security.PrivilidgedAction.




private class SubjectHoldingResourceCreator extends ResourceCreator {

Subject subject;

// Obtain the Subject from the thread
@Override public void run() {

super.run();
subject = weblogic.security.Security.getCurrentSubject();

}
}

private class SubjectUsingNonCreatorThreadRunner extends Thread {

private final SubjectHoldingResourceCreator creator;
public SubjectUsingNonCreatorThreadRunner(SubjectHoldingResourceCreator creator) {

this.creator = creator;
}

@Override public void run() {

try {
final Session session = creator.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

final MessageProducer producer = session.createProducer(creator.destination);

// Execute a secure action using the Subject from the previous thread.
weblogic.security.Security.runAs(creator.subject, new PrivilegedAction<Void>() {

public Void run() {
try {
producer.send(session.createTextMessage());

System.out.println("Sent using Subject created on separate thread....");
}
catch (JMSException e) {

e.printStackTrace();
}
return null;

}
});
} catch (Exception e) {

e.printStackTrace();
}
}
}

public void testCreationOnSeparateUsingSubject() throws Exception {
SubjectHoldingResourceCreator c = new SubjectHoldingResourceCreator();

c.start();
c.join();
SubjectUsingNonCreatorThreadRunner r = new SubjectUsingNonCreatorThreadRunner(c);

r.start();
r.join();
}




The above example worked and sent the message. I have seen others facing a similar issue when using Spring classes such as JmsTemplate and DefaultMessageListenerContainer with Weblogic where this security issue bites them. Some folks have taken the route of initializing the Context before every send/receive of a message. This is clearly not optimal as the creation of an InitialContext is not cheap and can lead to degradation of performance.

My recommendation is to use the Proxy Pattern and have proxied versions of javax.jms.MessageProducer(s) and javax.jms.MessageConsumer(s) which ensure that calls to send/receive are executed within a PrivilidgedAction.
Look at my posting on Weblogic Jms Template to see how Proxies can be used.

The javax.security.auth.Subject can be obtained once in a multi-threaded environment for a particular user authenticator (userName/pass) and then be held for use by all the threads in the environment.

public Subject createSingleSubject(String providerUrl, String userName, String passsword) {

Subject subject = new Subject();
// Weblogic env class

Environment env = new Environment();
env.setProviderUrl(providerUrl);

env.setSecurityPrincipal(userName);
env.setSecurityCredentials(password);

try {
// Weblogic Authenticate class will populate and Seal the subject
Authenticate.authenticate(env, subject);

return subject;
}
catch (LoginException e) {

throw new RuntimeException("Unable to Authenticate User", e);
}
catch (Exception e) {

throw new RuntimeException("Error authenticating user", e);
}
}



If the above method is invoked once to set up a Subject, then the same Subject can be used by Proxies to invoke PrivilidgedActions.

One thing I don't like is that on closing of the obtained Context, the ThreadLocal object is not cleared of all allocated permission related objects. It is only the Subject that is detached. I am looking for a way prevent the caching of security information in the ThreadLocal by WebLogic.

Some Links:
1. Spring JIRA
2. Weblogic Security Documentation

Wednesday, April 8, 2009

Vote for Adam Lambert..a vote more importantant than your vote for Obama

I am not an Idol fanatic by any means, very far from it. I am however following this season. American Idol IMHO is a package, a singer with a great voice, who is sellable, has a dynamic persona, can get the chicks! Once in a while comes a singer who just does it freakin right. Adam Lambert from this seasons American Idol is the man. His rendition of "Mad World" is just super.

This guy has it all. The persona, the package, the voice for the next idol. I have found my American Idol, its Adam...Vote on! We need this guy at No.1. My theory is this person is Elvis reborn. Elvis lives!

Wednesday, April 1, 2009

Liking Emma and FindBugs Eclipse Plugins

I have found myself liking two helpers as I continue to develop, Code Coverage and Finding Bugs. I usually use plugins in maven reporting to help me find issues and coverage information after issuing a "mvn site".

I however prefer to catch the same without having to generate the maven site though and in my IDE. I see two nice eclipse plugins for the same. For the Code Coverage part, I quite like the Emma Eclipse plugin which allows me to run my unit tests in "Coverage" mode and helps me determine the amount of code coverage my unit tests are providing. The coloring is pretty good, green for fully covered code, red for missed code and yellow for partially covered code. Trying to be green...

I have also started to use the Find Bugs eclipse plugin. Professional "Hara Kiri" here but I often get pleasantly surprised by what the utility finds for me :-). It would have been nice if the "Problems" tab in Eclipse showed the issues found by "Find Bugs" via a different icon. Also I am refraining from showing results of either plugin here for obvious reasons :-))))

Monday, March 30, 2009

Java Closure(s) but no cigar?

It has now been a year since I have been working with Java 5+ features. During development, I have welcomed auto-boxing, the concise for loop, vargs, enums and Generics. In particular the last feature has been rather appreciated as type safe programming makes life for a developer so much easier. That said, I will also state that there have been many times that I have been troubled by the wild cards in generics and erasure. However, I find the take aways I get from generics far out weigh the few times I need to stress my brain with wild cards and erasure.

Like Generics, one equally important feature that the Java language has been wanting is Closures. A JSR for closures resulted in multiple proposals. Notably,
  1. Full Closures by the BGGA proposal
  2. CICE Simplified inner classes and
  3. FCM First Class methods.
As a note a poll taken to determine which proposal Java developers would welcome led to, BGGA taking the lead. Interestingly enough, a large percentage of Java developers felt that they do not want Closures in Java. My intuition tells me that a large percentage of the latter voters are saying "I do not want BGGA closures in Java" rather than "I do not want Closures at all".

A famous debate between Neal Gafter who has come forth as the major spokesperson for the BGGA closures proposal and Josh Bloch, a supporter of the CICE proposal has ensued via presentations and blogs. The same can be googled for.

A bit about my stance, I definitely see the power of Closures. However as the saying from Spiderman, the movie goes, "With great power comes great responsibility." I want the power that Closures offer in Java, and I want an implementation that I can understand and be productive with. I want intuitive compilation errors that will immediately alert me to the problem without straining the few @deprecated Grey cells that are still struggling to function in my brain.

I want conciseness, but not at the cost of readability and maintainability. In short, I want power with clarity and brevity. One cannot always get everything they want, sad but true, however, my stance is that if I can benefit considerably most of the time, I do not mind the pain for a little of the time. Think of it like a marriage ;-)))..luckily, the wife does not read my technical blogs lol! A better parallel; (Gain Factor >>>> Pain Factor == Adoption)

One can read about what a Closure is, what a Lambda expression is and I will not spend time on the same. Primary reason being, I cannot understand the same myself :-(

What I want to do in this Blog is to understand Closures by BGGA and try for myself how hard or how easy is it to work with them. I do not use an IDE but revert to using emacs and the command line for this exercise.

I downloaded the BGGA propopal and ran some of the examples from the Java Closures Tutorial so very well explained by Zdeněk Troníček. Then I tried to apply the same to cases I have encountered before or am working with now to see for myself how easy/difficult the proposal is and problems I faced, if any.

Function Types:
I think function types would be a great addition to the language. I understand Mr.Bloch's concern that they might tend to lead to an exotic style of programming, however, I feel exotic styles of programming can even be developed with the simplest of constructs should developers choose to. It is possible for a psychotic developer as myself to take the simplest of problems and provide the most convoluted but workable solutions for the same. If I were introduced to the book Java Puzzlers prior to learning Java, I might have fled the scene. Sure, there will be puzzling cases but thats what code reviews, documentation, etc are all for after all. I am not sure I buy the argument, that "BGGA closures lend themselves to an exotic programming style". One can easily be exotic with the simplest of language constructs IMHO.

Lets look at a couple of examples, I have an eachEntry() method that runs through an java.lang.Iterable and executes the block provided. I also a have a simple filter() that can be used to filter an Iterable which delegates to the eachEntry().



public static <T> Collection<T> filter(Iterable<T> input,
{T=>boolean} filterBlock) {
Collection<T> filteredItems = new ArrayList<T>();

eachEntry(input, {T item =>
if (filterBlock.invoke(item)) filteredItems.add(item);});


return matched;
}

public static for <T, throws E extends Exception>
void eachEntry(Iterable<T> items, {T => void throws E} block) throws E {

for (T item : items) {
block.invoke(item);

}
}



An example usage of the above where Employee objects are filtered:



// Static import the utility functions, filter and eachEntry
import static com.welflex.util.Utils.*;

List<Employee> emps = ...// Get employees

// A closure that uses the Function type of eachEntry to dump out the
// information about each employee
eachEntry(emps, {Employee e =>
System.out.println("Id:" + e.getId()

+ ", Manager:"
+ e.isManager()
+ ", Salary:" + e.getSalary());});

// Filter out only employees who are managers
Collection<Employee> managers = filter(emps, {Employee e => e.isManager()});

// Filter out only managers who earn gt 60000 using a filter of filters
Collection<Employee> mgrsGt = filter(filter(emps, {Employee e => e.isManager()}), {Employee e => e.getSalary() > 60000);

// The above one re-written
mgrsGt = filter(emps, {Employee e = > e.isManager() && e.getSalary() > 60000});



I find the above pretty concise and powerful. I also find the same rather easy to read as well. So no complaints from me there. For those reading, hey I never claimed I was invincible as far as programming goes, close to invincible, yes ;-)

Now the negative, some things I could however not understand,

a. for construct did not work for me:
"for" construct did not work for me. I might not have done it correctly, but the eachEntry() that uses the "for" construct compiled just fine. Compiling the following should have worked, I am not sure what I am missing:



for eachEntry(Employee e : emps) {

System.out.println("Id:" + e.getId());

}



A compilation error leading to:
"Filter.java:20: method forEach in class Filter cannot be applied to given types
required: java.lang.Iterable
,javax.lang.function.OO,java.lang.Class
found: java.util.Collection,{T => void},java.lang.Class
forEach(orig, {T item => if (block.invoke(item)) matched.add(item);},"

The above was not very instructive for me in addressing the issue :-(

b. Static Inner Class when used in the example caused compiler error:

When my Employee class was a static inner class, I ended up with the following exception when I tried to compile the examples class, leading me take it the Employee class to its own separate compilation unit:

exception has occurred in the compiler (1.6.0_11). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. java.lang.NullPointerException at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:140)

I would like to also provide another example where I am using an ARM block to obtain a JMS Object from JNDI and subsequently closing the context. Note that I am not using actual javax.naming.Context classes but have instead modeled my own for the sake of demonstration. Without closures and using anonymous classes, I have the following:



private <T> T executeContextTask(ContextTask<T> task) throws LookupException {

Context ctx = null;
try {
ctx = new ContextImpl();
return task.executeWithContext(ctx);

} finally {
if (ctx != null) {

try {
ctx.close();
} catch (Exception e) {

//log this
}
}
}
}

private static interface ContextTask<T> {

public T executeWithContext(Context ctx) throws LookupException;

}

public ConnectionFactory getConnectionFactory(final String name)
throws LookupException {

return executeContextTask(new ContextTask<ConnectionFactory>() {
public ConnectionFactory executeWithContext(Context ctx)
throws LookupException {

ConnectionFactory c = (ConnectionFactory) ctx.lookup(name);

// Do something with Connection Factory before returning
return c;
}
});

}
....
public Destination getDestination(final String name)
throws LookupException {

... // Similar to above..except returns a Destination..//
}




The same above example when done using BGGA closures is simplified to:



private static <T, throws E extends LookupException>
T withContext({Context=>T throws E} contextTaskBlock) throws E {

Context ctx = null;
try {
ctx = new ContextImpl();

return contextTaskBlock.invoke(ctx);
} finally {

if (ctx != null) {
try {

ctx.close();
} catch (Exception e) {

// Log error
}
}
}

// Note name is no longer final, neither is there a class called
// Context Task and the anonymous class has been replaced by the
// closure.

public ConnectionFactory getConnectionFactory(String name)
throws LookupException {

return withContext({Context ctx =>
ConnectionFactory c = (ConnectionFactory) ctx.lookup(name); c});

}

.. Similar code for Destination...



Closure Conversion:
I quite like Closure Conversion. For example, I have an interface called Read that reads in an Employee Record. Assigning a closure to the interface type we have the below:

I am liking the conciseness presented by the above over writing an anonymous inner class + method definition + body (although the conversion is translated to the same).



interface Read {
public Employee read(String criteria);

}

Read readRecord = {String criteria =>
System.out.println("Criteria:" + criteria);

Random r = new Random();
new Employee(r.nextInt(5),
r.nextBoolean(),
r.nextInt(10000))};


public void closureConversion() {
Employee e = readRecord.read("select * from Emp where id=\"20\"");

System.out.println("Employee Read:" + e);
}




Arrays:
Arrays have boggle my mind in Generics, Arrays continue to boggle my mind with BGGA closures.



// Will not compile
{ => int} closures[] = new { => int}[10];

// Will not compile
{=>int} closures[] = {{=>5}, {=>6}};

// Compiles
List<{=> int}> list = new ArrayList<{=>int}>();

// But no way of
{=>int} closures[] = list.toArray({=>int} closures[0]);




Non local returns:
When returning from a Closure, should the "return" result in returning from the method itself? That is not very intuitive to me. I am of the opinion that returns from a closure, should only be local and not result in exiting the method. That is room for accidental programing with disastrous results.

Consider the following Code, what do you thing will be the result of the invocation?



static boolean testBooleanLocal(boolean input) {

{boolean =>boolean} closure = {boolean args=>

args
};

boolean result = !closure.invoke(input);

System.out.println("Test Boolean Local Result: " + result);
return result;

}

static boolean testBooleanNonLocal(boolean input) {

{boolean ==> boolean} closure = { boolean arg ==>

return arg;
};

boolean result = !closure.invoke(input);

System.out.println("Test Boolean NonLocal Result:" + result);
return result;

}

public static void main(String args[]) {

System.out.println("Local:" + testBooleanLocal(true));

System.out.println("Non Local:" + testBooleanNonLocal(true));

}



The answer is:



Test Boolean Local Result: false
Local:false
Non Local:true



What just happened to the second println()? All because I had a ==> versus a => along with a return statement?

The Syntax:
Without the assistance of an IDE, I had a few growing pains where I was accidentally doing "= >" instead of "=>", i.e, a space in between. Surely any IDE ready to support BGGA will catch the same. What about "==> "versus "=>"? Will an IDE be able to warn regarding the difference? I sure hope so :-)

Running the Examples:
As always, I am sharing my playground. For the ones interested, I tried the same using:
Download the ...., install the same and then set your PATH to include the existing JDK 1.6. For example,
export PATH=/.../jdk1.6.12/bin:$PATH. Then compile the provided code using the "javac" from the BGGA proposal, for example, "$BGGA_HOME/bin/javac -classpath .:com/welflex/utils:com/welflex/model:com/welflex/example *.java" and run the same using the similar syntax.

Parting Thoughts:
Sadness that Java does not have closures. Visual Basic developers are benefitting and thriving with the same, something I heard. Closures are a construct that has been around since ages, Java compromised at the time of inception via Anonymous classes rather then deal with the complexity of Closures, maybe a good decision for the time. However, time is now neigh for change. If Java has to survive, Closures need to enter the language. One cannot wait between JDK7 to JDK8 without knowing closures will or will not find a place in Java. Java folk are tending to gravitate toward other languages like Scala, Clojure etc. IMHO we need to stop this abandonement. My rationale for the same is (based purely on sentiments), I love Java, its been the reason for my bread and butter over the years, I love developing with it and I want to continue to develop with it. More importantly, its represents Coffee, I cannot wake up without my shot of the same. Scala or Clojure doesn't inspire me as much, maybe an alternate VM language called Nicotine could cut it and spark my interest ;-)

BGGA is not perfect. Sadly, nothing ever is. In my own humble opinion, the warring factions of Gafter/Bloch need to join forces to improve the compiler warnings, syntax and any other ambiguities in the features of BGGA present and look toward introducing it as part of JDK 8.X. Come on guys, you are super smart chaps (Phd's don't come easy) that have collectively led to the creation/enhancement of this great language, make my life easy and do not let me leave my favorite language for some pretenders to the throne :-(. If not, I propose that Gosling take the place of a dictator and get this in..I will welcome the same! Maybe IBM buying Sun will change things... Got to cut em beers when I post, for all you know I might have made a case for "No closures ever in Java via my misadventures :-)", lol!


Sample Code that I have used can be downloaded from here.

Resources:

Tuesday, March 24, 2009

I don't want to RACE on the highway!

Just as a super star has to suffer the paparazzi, so does a person driving a sports car need to suffer contenders and challenges for a race. I drive an ole sweet Boxster but I am not interested in taking on any and every drunk on a highway race.

I recently attended the Salt Lake City Java users groups. On the way back, there is this BMW 3 series who my intuition tells me wants to race. The lights turn green, we are on the ramp, I know I can take him, it would be so freaking close, BMW 3 versus Boxster, but I do not push the throttle, instead I let go and let him drive away thinking he has won.

Call me chicken for not taking the dare, I take it as a compliment in this context. I fear that racing on the highway at high speeds is a recipe for disaster. One advertisement on TV that touched me is a case of a person struggling to call the family of the individual they killed accidentally due to a driving accident. Its one thing to die in an accident because you drove recklessly, its a whole freaking other thing if your actions directly or indirectly lead to the demise of some other innocent bystander.

0-60 I am firing all cylinders though, under the speed limit, no one around, Its my life...


Facebook is so very active

Have not been much of a On line Social Networking enthusiast. Primarily as it goes against my "Anti Social" primal nature :-). Its something I deeply value and something that is woven in my genetic code :-) Anyway, I am amazed by the number of my friends who are rather active there. I decided to login and post a couple of messages and before I could sign off, I had responses back.

People really digg Social networking, a late realization on my behalf. Go figure. I would have never put my money on such a site like Facebook. I must admit I quite like their Web 2.0 design. Very Web 2.0 with a lot of Ajaxian features and especially Ajaxian features that are responsive and done well.

One thing that has discouraged me from these social networking sites is that none of the folks that I knew growing up are on them. I seem to be the only one from my groups that has a presence on any of these places. Were my friends/generation just not technically savvy or am I just hated that people appear as invisible via some rule that says "boolean result = {String user = > user.equals("sanjay") ? false : true}.invoke("sanjay")"

Am seeing myself engage more on Facebook, and yes, this is one of my split personalities that likes socializing which is becoming the dominant personality....Scary times ahead!

Tuesday, March 10, 2009

Gems of Bruce Lee

Growing up, I always wanted to be like Bruce Lee. Fate had other plans, neither did I get my black belt and neither did I acquire his wisdom...still much respect for Mr.Lee and a fan forever...

Found this link rather interesting and felt like sharing... http://www.junauza.com/2009/03/15-inspiring-bruce-lee-quotes-that.html

Wednesday, March 4, 2009

The Case of the Missing Lego - A mystery solved

My earlier blog was regarding my tooth, this one is about a nose. The lead actor of this story is not about me, but is instead my dear son. This incident has to be blogged for posterity.

Well its around 10:30 p.m, I have posted my blog and sitting on the couch watching TV. My dear nutritionist, i.e., my wife is preparing dinner. Sounds like Pleasantville..Well not anymore...

There are cries of my son that I hear, followed by my wife agitatedly bringing him to me. Initial thoughts were, my daughter and my son have had some battle regarding some toy and my daughter has won, leaving the young man disgruntled. Err...not quite!

Flash back to January 1st 2009, my brother had gifted my kids with a Lego Set for ages 4+. Please note that my wife and I were also involved in the selection of the gift. My kids are reaching that 4 year window shortly, so it made for a great toy.

Flash forward to now. The Lego Set had some very small, smooth, disc shaped pieces and my dear son decided to experiment with "What would happen if I blocked one of my nasal passages with this Green foreign thingy?". The experiment worked, he had placed it in one of his nostrils and sucked the same in. Now with blood on his nostrils and realizing that the piece is probably inside him somewhere, he is upset.

Panic time! Where did the piece go? Is he having difficulty breathing? Is he choking? Did he drop the Lego piece on the carpet? I give you ladies and gentlemen, "The Case of the missing Lego" . As Jeremy Brett would have said, "A mystery is afoot".

Well my wife and I definitely did not want any part of this mystery. All we wanted was a solution.

We ask for explanations from my son. In the best way he can, he describes that he placed in his nose, and inhaled it and it vanished. I run my fingers over his nose, testing to see if I can feel the particle anywhere, I cannot feel a thing! We ask him to blow his nose in the hope that the missing Lego is evicted. No luck, nothing is thrown out! As he is able to breathe fine without coughing or choking, one thought is that my son must have inhaled it so forcefully that the piece has gone through his nasal passage and finally into his stomach. Another theory is that he really did not inhale it but instead may have dropped it on the carpet somewhere. Scanning the carpets and trash cans for the piece yielded no results. If we had found it, it would have brought closure to the case right then and there.

So what next? My wife calls "Poison Control". They recommend that since we have determined that my son is able to breathe well, we should take him to the doctor the next day for examination and keep observing him for the night. Well, as worried parents, we call our Pediatrician as well in order to obtain information regarding whether or not to head to the ER. After some discussion, she too states that there is no need for the ER as he is able to drink and eat without a problem. She however recommends that we bring him in for a check up the next day.

An incident less night ensues. The next day we re-think whether or not a Doctors visit is in fact validated. The closure seeker that I am, I request my wife to take him to the Doctors office to ensure the Lego is not present within. Call it peace of mind or closure. I chose not go to the Doctor's office as I was backing the theory that my son must have swallowed the Lego piece and the examination would not turn up any leads in the case.

My wife helps out and takes my son to the Doctor's office. The incidents that follow are total hearsay as I was not at the venue where they occurred.

At the Doctors office, the Doctor (she is a really good Doc) asks my son to explain the incident, he does so in court room level detail. The Doctor then places a magnifying glass instrument under his nose to check for the missing Lego piece. Sure enough, there it is, visible in all its glory !! My wife is stunned. The Doctor wants to remove the particle as leaving it in there could lead to infections etc. The Doctor finds the incident amusing as she has dealt with similar cases multiple times and takes my son to a different room to perform the extraction.

She attempts to remove it via an instrument that looked like sharp tongs but accidentally pokes my son during the process, that clearly is the end of that strategy for extraction. She deliberates on the next strategy, they do have multiple ones apparently. One direction is to use a reverse blower technique where she sets a blower in the child's mouth causing a force that will throw out the particle through the nose, another is to use a glue attached to the end of a fine stick that can be used to attach to the particle and thus removing it. Think of it as using Super-Glue. The Doctor decides to use the latter.

Please note that while all this is ensuing, my son is not exactly Cooperation Exemplified (expected of him as he has suffered pain) by any means :-). He is quite agitated and makes everyone around know his intentions. My daughter on the other hand is seeing her brother in pain and has an extremely sad expression on her face. So, in come a couple of more nurses, joining my wife to hold my son down while the second extraction procedure is attempted.
The doctor sends the instrument in, attaches it to the Lego and manages to pull it down all the way till the nostril. Before she can get it out though, my son breathes in again sucking the Lego all the way back up. Darn! She tries the process again, and this time she manages to get the piece out. However, in the process, she accidentally gets some of the glue under my sons eyes. We have solved the mystery of the missing Lego and put it where it belongs, i.e., in a trash can. My son however will not consider the process complete until the glue is removed from under his eyes, so the cleaning process and finally closure. He still has some of the glue in his nose but that will come off in time. I feel bad thinking of all the pain he suffered...

Back home, my wife debriefs me regarding the incident to my utter disbelief. Boy, am I glad that we went to the Doctor to check on it. I am rather pleased at the way my wife and I handled this minor crisis, i.e., calling poison control, calling the doc, the follow up etc. I am aware this happens to many kids all the time and thankful that my son did not suffer a life threatening emergency. I feel bad for the pain he has suffered though. I wonder how many of my friends have faced something similar where their kids have ingested foreign particles :-)

Take aways from the incident:
- Kids are genetically designed to give their parents heart palpitations once in a while, regardless of age ...:-)
- Be careful regarding small particles, kids tend to experiment regardless of age
- Keep important numbers handy when kids are at home
- Recommend that one never pass up on a full examination from the Doctor when it involves an incident regarding your child
- Even the smallest of things can be deadly
- There is no happiness that compares to knowing your child is healthy

Some links that might be of use:



Found this funny...

What if programming languages ran the airlines, a blog on theserverside.com
http://www.theserverside.com/news/thread.tss?thread_id=53820

Leading to:
http://www.zyra.org.uk/os-air.htm LOL!

Tuesday, March 3, 2009

Drills run by Sergeant's are endurable, Drills by Dentist are not..

Today I had my first root canal treatment at the hands of my dentist. I have been avoiding the procedure for over a year but an infection caused by the dying tooth had me such seething pain that I decided to succumb to the drill. I would have preferred to go last week for the same but the week was busy with a presentation that I was giving at the company I work at and didn't want a swollen mouth and potentially greater post traumatic pain hindering those proceedings.

I have previously had all my wisdom teeth removed as they were causing impaction's, yep, I have no chance of becoming  wise :-). Those surgeries were rather painless as once injected with the anesthetic, I could hardly feel much apart from vibrations of the tongs as the dentist pulled out the tooth. I entered the root canal treatment with the same belief that it cannot be as painful as touted. Boy, was I wrong ! There were times during the drilling where I experienced shooting pain like never felt before and never want to again...Never say, never again says the dentist though as he pointed out that the adjacent tooth might have a problem as well. All these are dying teeth are the result of bad procedures at some other dentist' hand that I suffered long ago.  I can only hope that the other tooth is OK and I would not need to suffer the canal again. 

Right now, recovering a with pain killer that has a narcotic effect, cannot complain about that ;-)