General

Hello 2010 And My Rant For 2009

January 7th, 2010  |  Published in General  | Add to del.icio.us

It’s never to late to say “Happy New Year” !!!
I would like to take this opportunity to wish everybody the very best for 2010.

2009 have been a very busy and an eventful year. My wife graduated and thus ended our 2 year stay at the university residences at UTM. All though a small townhouse (albeit with 4 bedrooms - no idea how they fit them all in that tiny space) it was nestled in a lovely location. There was greenery all around and our townhouse backed into a wooded lot where there was deer with plenty of raccoons and the occasional rabbit. The campus had clearly paid a lot of attention to maintaining a healthy balance with nature, so there was plenty of tress around the area. I am not really a shutter bug, but we did take a few pictures here and there. Sadly I can’t seem to find them, so I’m linking with a few photos (pic1, pic2, pic3) I found on the net taken by one QueenCindy. My kid loved this place as there was plenty of room to run around and play.

After my wife graduated we had to moved into another place and after a very exhaustive search we found our selves back in the northern edge of Brampton,ON. House hunting was no fun and we spent countless hours running around looking for a place that fits our whims and fancies and also within our budget. Once we found the house it was a mad rush to find a mortgage at a suitable rate as we had only a few days. At the time the rates were very attractive, but the lending institutions were very thorough with so many requirements for various kinds of documents. I just about managed to get all the paper work done in time, but not without a last minute scare where for reason only known to them the bank refused to work with my lawyer. So I found another one at the eleventh hour that had a good working relationship with the bank which ensured we closed on time. All this happened while my wife was doing her final exams and I had to work on site with a customer that had a fairly aggressive schedule. My interactions with customers were mostly via email or phone calls, so being onsite was a new experience, all though I have to admit it was fairly stressful as well. I have blogged on my experience about it here. By the time the gig came to an end, I had lost quite a few hair.

The university gave us a one month grace period as there was nobody waiting to lease our townhouse. It allowed us some flexibility in the closing schedule. We have moved 5 times during the last 6 years, where one move was from Ottawa to Brampton (in Greater Toronto Area) !!!. So the very thought of moving again itself was a dreadful experience. I managed the last 5 moves on my own by renting a UHaul trunk. It wasn’t fun and I had enough, so this time I hired a mover. It took us quite a bit of time to get everything unpacked and settled in.

I started playing cricket in earnest during the last season (2009) for the Toronto and District Cricket League. It was an up and down season ending with me breaking my finger pretty badly during the last match of the regular season. The finger was dislocated and had a volar plate chip fracture. My finger is still in a pretty bad shape with a real possibility of it not attaining at least a 70% of what it used to be. One highlight of the season was facing Navin Stewart from Trinidad (who came to Canada to play club cricket during his off season). He plays for Trinidad and Tobago and featured in the Stanford Super Series and the esteemed Champions League in India. The bastard bowled two bouncers the second of which hit my glove, ricocheted off my helmet before being caught at the slips. He had decent pace and it was difficult to pick the red ball against the fading light. I hope I had better luck this coming season, but not sure if I am able to play at all due to the finger injury.

With all the madness happening around I had managed to post a grand total of 3 blog entries for 2009. I am certainly hoping to improve on that in the coming year. Again I wish everybody the very best for 2010 !!!

Survival tips for software engineers in a customer facing role

September 9th, 2009  |  Published in General  | Add to del.icio.us

It is not often a software engineer has to engage in a customer facing role. In most organizations there is a tiered support structure between a customer and the software engineer. However in certain circumstances a software engineer may end up in a customer facing role. For example if you work for a startup you may have to juggle multiple roles, including a customer facing role until a proper support structure is put in place. Even in an established organization, when a new product is introduced the engineering team may need to handle support issues initially until the support organization gets up to speed with it.

In any case it is important that software engineers develop necessary skills to handle such situations effectively. Some of these skills will help when communicating within your organization and some for life in general.
Following are some tips that may help you to make your engagement a productive and a pleasant one.

  1. . Pay attention to the subtleties when communicating over email.
    It is often easy for people to misunderstand you when communicating over email as opposed to phone or in person. The tone could be easily misunderstood as being aggressive or rude as the person reading is unable to gauge your emotions or see your body language. This is especially important if you haven’t met them in person or spoken to them over the phone. Generally once a person can put a face to a name it becomes a bit more easy.

    I have had several instances where this has happened and I now pay close attention to any email I send out to ensure that I communicate exactly what I intended.

    Also it is important to state the obvious at least for completeness sake. What is obvious to you may not be to others. This especially important when using emails as there is no opportunity for instant feedback/questions. Otherwise it will result in lengthy email threads.


  2. Respect the people you are dealing with and try to build good working relationships
    Telling a customer to RTFM is probably not a good idea. Even if you are frustrated due to repeated questions that you have answered a 100 times to several people during the last few days, it is best to answer it one more time. Even when you have no choice but to tell them to RTFM, do so in a respectful manner which doesn’t make people feel bad. Nobody in this world wants to be belittled or disrespected. When egos are hurt it creates a very unpleasant work environment.

    In fact good healthy relationship can go a long way in making sure the project runs smoothly and successfully.


  3. Your code vs my code - avoid the customary finger pointing
    Most people are very passionate about the code they write. And often when there is a problem we tend to take a defensive stand. Anybody who has seen a conversation between a programmer and QA engineer would know what I am talking about.
    But when you are dealing with a customer, you need to be extra careful about how you look at a problem. Even if the issue is not in your product you need to control your urge to point it in the same emphatic way you do so with your QA folks. You need to be more diplomatic in how you point out the bug on their side and try to avoid using words like “your code” or “our code”.

  4. We can’t reproduce in our lab environment is not a good answer.
    Certain problems may not be possible to reproduce (in the exact form), outside the customers environment as it is difficult to replicate the exact environment due to differences in hardware and not having access to their application binaries due to security, legal and other issues. . But it is important to identify the issues at a more deeper level. Perhaps if you understand the root cause, you maybe able to simulate the issue in a different way.
    Take the time to understand the issue and try to talk to all people involved to get a complete and accurate picture. From experience I have seen that sometimes you want get all relevant information the first time you talk to people. People often forget unless you ask probing questions. Most times the first reactions from people capture the symptoms rather than the root cause. So a careful analysis maybe need to nail the real issue.

  5. Encourage the use of proper support procedures right from the beginning. Never take short cuts.
    I have been burned several times by not following this. When an issue happens it is important that you encourage your customers to follow the correct procedure. For example the use of a bug tracking tool instead of a series of adhoc emails. It is often tempting to ask customers to email log files, or if you are on site to walk over to their desk and try to investigate.
    But if you encourage the use of a bug reporting tool it will have several benefits. It will force the person reporting the issue to think through in a methodical way and capture all the right information while it is still fresh in their mind. For example most bug reporting tools have fields to capture version information, a problem description, a component, steps to reproduce (if any), expected and observed result and provisions to attach log files ..etc. Once information is captured in a central location it is easy to share that information with your engineering team rather than digging through a series of adhoc emails.

  6. Proactively educate the people you work with
    By experience I have found it is helpful to have a meeting as soon as possible with all involved parties and educate them on the following. Some of these may have already being communicated to them. But most may have forgotten or in some cases not being given to them at all.

    • Provide links to documentation, training slides ..etc
    • Educate them on the proper procedure to follow when reporting issues (can’t stress this enough)
    • Based on the most frequent questions, try to provide an faq that is tailored to their environment
    • Once you identify the full system setup provide a basic trouble shooting guide for them to isolate if the issue is related to your organizations product or not. This I found reduced a lot of pain and non issues being reported.
    • Provide useful links to other skills involved in the project. For example I sometimes encountered folks who work mostly in a windows environment, but now dragged into a product being deployed in a unix environment. So links on basic unix skills would make it easy on everybody in such a situation.

  7. Don’t babysit the people you work with
    Initially you may get into the habit of spoon feeding information and babysitting them. This may seem like an easy option rather than trying to get them involved in the process. But it is in everybody’s best interest to get the customer to gain as much confidence in getting to know how to install, debug and use your product. This will reduce a load of pain later on in the process. Also try to,

    • Avoid getting sucked into debugging the customers code.
    • Avoid the temptation to debug or fix an issue on your own. Try as much as possible to get them involved in the process.
    • Document trouble shooting attempts and consolidate them into a trouble shooting guide. Most products have official trouble shooting guides, but a supplementary trouble shooting guide tailored to their environment and using terminology familiar to them will make them more comfortable.

  8. It is helpful if you have multiple programming language skills
    Since you write code, the customer will expect you to answer questions at the code level. Sometimes you may have to review code segments and provide an opinion. However if your product is providing clients in different languages, these questions may be in a language that is outside of your core competencies. Therefore it is important that you have a at least some knowledge using those languages.
    In general the ability to write code in several languages is always an added bonus as you will be a valuable asset to the company.

  9. Know thy unix tools
    Also if you are in the unix world it is nice to have some skills in basic unix tools like top, vmstat, pmap, netstat, sar, lsof ..etc and text processing languages like perl, awk, sed etc. These tools can help you diagnose issues and obtain important information about the env. The text processing tools will be invaluable when you need to make sense out of massive log files or other text processing tasks. These skills will make you more productive by allowing you to extract information quickly and efficiently than just using grep or crunching numbers using a spreadsheet.

  10. Keep your conversations professional and never take things personal
    You always need to remember that you are representing your company/product and the team you work with. Therefore the people you work with at a customer’s site may directly vent their frustration at you. This may manifest in the form of rude comments, lack of cooperation and in rare situations a bit of yelling (Fortunately I’ve only seen only one such incident that happened a few years back) . Never take them personally or get into any sort of argument. It is best not to take anything personal or get emotionally involved. When the stakes are high and push comes to shove, humans will react and we need to understand that and continue to behave professionally. Sometimes all they expect is for you to keep quiet, listen to them and empathize with their situation. And something simple as “I hear your point/understand your frustration. We are doing all we can to help” is all it takes.

    However if you are finding it difficult to cope, it is best to bring it to your managers attention and discuss possible measures to address the situation. It’s a bad idea to just keep quiet and bottle them inside, as you run the risk of an emotional outburst. Let your manager help you by dealing with the management on the customers side. All though the customer is the king, it is not acceptable for anybody to be treated badly.

Synapse vs Camel

February 11th, 2008  |  Published in General, Open Source  | Add to del.icio.us

I had the opportunity of listening to my friend Bruce Snyder talk about Apache Camel during his talks on ActiveMQ/ServiceMix at the Colorado Software Summit 07. There was also some discussion on Camel on the Apache Synapse mailing list recently. I thought of replying to the thread comparing the two based on it’s routing and mediation aspects. In the process I decided to write a blog post instead. If I have misunderstood any Camel feature/architectural detail, please let me know and I will post a correction. Note this is not an in depth analysis, neither a verdict on either project. Readers should do their own research and come to conclusions.

Intent/Problem Space

  • Both Synapse and Camel have similar intents as Integration, Mediation and Routing Engines.
  • Synapse also positions itself as an ESB, treating your entire network as the bus.
  • Camel/ServiceMix is advertised as an ESB.
  • Both have routing,transformation,mediation,enrichment,validation, logging ..etc.
  • Initially Synapse was more focused on Web Services mediation. Since then, it has moved out of the Web Services umbrella and is trying to position itself as a general purpose integration/mediation/routing engine.
  • Synapse by design have a proper abstraction layer where you can adapt (implement) Synapse on top of any Environment. It is one of the least known aspects about Synapse. Most folks assume Synapse can only work on top of Axis2. I have implemented the Synapse environment interface inside the Apache Qpid broker to leverage its mediation/routing capabilities.
  • Camel on the other hand was designed to work on different environments from the begining. Camel can be used inside ServiceMix, ActiveMQ etc.

I haven’t experimented enough with Camel to compare performance, flexibility,extensibility or robustness with Synapse. Perhaps that would be an interesting topic to touch sometime later

Messaging Model

  • The Synapse messaging model is based on SOAP. The current implementation of Synapse is powered by Axis2 and takes any type of non SOAP message and creates a fictitious SOAP message and pumps it through the Synapse engine.
  • Camel has a neutral messaging model which I think is nice.
  • However you can implement your own Synapse MessageContext as well. I have created an AMQP based messaging model for Synapse for my work on embedding Synapse as an AMQP Exchange.
  • Synapse could also use generics to make it’s messaging model neutral. (I hope to make a proposal to this effect after my AMQP work).

Synapse Configuration vs Camel Context

  • Both use very similar models for representing a runtime instance of the rules/endpoints/registry ..etc.
  • Synapse has a XML based DSL for configuration.
  • Camel has a java and XML based DSL for configuration. You can use Spring to configure the Camel Context as well.
  • You can also use Synapse programatically all though we haven’t provided a clear API as such to the user community. I think such an API would be a valuable addition to Synapse.
  • There is support for configuring Axis2 with Spring, so I assume you can do the same for Synapse very soon (if not already).
  • Both supports the concept of a Registry. The registry mechanism is pluggable in both projects.

Synapse Mediators vs Camel Processors

  • A Synapse mediator, mediates a message as it passes through. It could be a transformation,validation, logging, audit ..etc.
  • You can chain mediators into sequences and combine different sequences to create a processing engine.
  • Camel processors does more or less the same.
  • In both Synapse and Camel you can write you own mediator by implementing the Mediator or Processor interfaces respectively.

Synapse Script Mediator vs Camel Predicates/Expressions
Again they both provide pluggable scripting support. Not much to be said there.

Endpoints/Transports

  • Both represents endpoints via URIs.
  • Camel and Synapse supports more or less the same set of transports with the following exceptions.
    • Camel has additional support for JBI,MINA, XMPP.
    • Synapse supports Non blocking HTTP, AMQP (native not via JMS).
      James Strachenanswered : “Camel supports non blocking HTTP too”
    • In Synapse you could switch transport. Ex incoming is JMS and outgoing is HTTP (does Camel have similar support?).
      James Strachen answered : “you can use Camel to do protocol switching from any protocol to any protocol with whatever EIP patterns in between (e.g. Message Translator etc).”
    • Axis2 has support for XMPP, so if you really want to you could leverage that in Synapse.

Enterprise Integration Patterns

  • Camel has support/good documentation for Enterprise Integration Patterns (based on Gregor Hopes book).
  • All though Synapse doesn’t directly say so, you can easily do the same. In fact it does have some built in support similar to Camel for some patterns while other patterns can be done with a little bit of work. I may in the future compile an article on how to do so with Synapse.

Embedability

  • Camel has a programmable API as described above and I quite like it. It would be nice if Synapse can do something similar.
  • Camel can be used inside ServiceMix, ActiveMQ ..etc. I have managed to embed Synapse inside an AMQP broker albeit with some code changes.
  • It would be nice if you could embed the mediation engine in Synapse in other projects in a trivial way and also provide some documentation on it.
  • One nice thing about Synapse is that it can be deployed as a module inside Axis2 or as war file inside Tomcat. Couldn’t find any documentation on easy Camel integration with Apache CFX
    James Strachen answered : “its trivial to deploy Camel inside any Spring or WAR application or as an OSGi bundle, working great with Spring Dynamic Modules”

WS-* QoS Support

  • Synapse has Built in support for WS-* QoS features (adding/removing security, reliability ..etc) when running on top of Axis2.
  • Does Camel have a similar strategy with it’s Apache CXF support? ( I couldn’t find any information in the Camel site about this)
    James Strachen answered : yes Camel has a similar WS-* strategy; using CXF to support the SOAP/WS-* protocols on any endpoint

Throttling/Load balancing/Policy based access and failover support for endpoints

  • Synapse has good support for applying throttling , failover support and load balancing to endpoints.
  • Synapse also can apply policies to enforce restrictions for better manage your endpoints.
  • Not sure if Camel has any support for this area.
    James Strachen answered : “yes Camel has support for load balancing, throttling, resequencing etc. See http://activemq.apache.org/camel/enterprise-integration-patterns.html”

Clustering support

  • Synapse allows mediator state to be replicated across the cluster.This is based on the Axis2 clustering support.
  • This is nice when you want to implement stateful mediators, like a session mediator.
  • Again haven’t come across any documentation in Camel on this area.
    James Strachen answered : “for stateful replication, we rely on ActiveMQ’s Message Groups feature or using EJB3″

Payload Conversion

  • Synapse can covert from one message format to another via built in support for POX, SOAP and JMS.
  • Camel provides a Type Converter interface (and some default implementations) to convert message payloads from one type to another when routing.
  • Similarly in Synapse, for other payload types you could write a custom mediator to do the job.
  • Also using the transport switching mechanism you can do some trivial things like converting a Qpid/AMQP message to an ActiveMQ message using the JMS transport. Sort of like a message bridge.

Summary
Both projects seems interesting and has some overlapping features, but different direction/focus and thought process behind them. IMHO it is nice to have choices in open source. Each community can learn from each other and strive to provide a better experience to the end user.

I REST my case

January 21st, 2008  |  Published in Architecture, General, REST, SOA  | Add to del.icio.us

Mark Baker has hung up his boots on the REST vs SOAP debate. I appreciate his effort in building awareness about the value of REST and convincing people that it provides a solid basis for designing distributed systems. In the same post, Mark also says that, “The war really has been won”. Other REST folks including Stefan Tilkov says more or less the same thing too. I don’t know. In my humble opinion, a few years from now when the systems we design/build today using a RESTful, WS-* (or whatever) approach will show us which approach yields the better result in terms of scalability, extensibility, reliability, interoperability, flexibility, versioning, reusability ..etc. Sure the REST folks would say the web has being there for a while now and it works. But usually there is a human on the other side that drives the interaction. So it remains to be seen whether it will be the same with application-to-application interactions as well.
After all the hype surrounding REST,WS-* etc.. dies out and when people have enough experience building real world applications using both approaches and realizes the advantages and disadvantages of each approach there will be less debate as to which is better, or whether we need both approaches ..etc. The answers to these questions will become more clear to the ordinary folks in time. I for one will have an open mind and is very interested to see the outcome of all of this.

The REST vs SOAP debate has been more emotional/religious and less technical as of late. Several folks burned bridges due to insidious remarks, inflammatory comments and even personal attacks. Irrespective of the technical merits one should be able to tolerate/appreciate differences of opinions and debate in a more disciplined manner than resorting to personal attacks or inflammatory comments. Even if you are the most intelligent person in the world it doesn’t matter if you can’t put forward your technical arguments without degrading your own self by making inflammatory comments or personal attacks.

Global Warming …is it really?

November 1st, 2007  |  Published in General  | Add to del.icio.us

Dwight Hornbecker, the only geologist I’ve even known, had some very interesting facts about global warming. They sound kinda crazy, but I wonder if they are true. Here is what he told.

  • One volcanic eruption can contribute to global warming more than what humans can do in an year
  • The earth was actually warmer than what it is now.

Dwight went onto explain that there is evidence to support that, a few million years ago the earth was a lot more warmer than what it is today. Then came the ice age. And he maintains that we are still recovering from the ice age and earth is slowly returning back to it what it was. Not sure whom to believe. Is it Al Gore and his crew or Dwight?

All I know is that humans haven’t really figured it out yet. We think we do and try to mess around with nature, but I don’t think we are even close at guessing/figuring out the real situation.

Being a single parent (for 2 weeks)

July 3rd, 2007  |  Published in General  | Add to del.icio.us

I had to go to Sri Lanka for my brothers wedding for 2 weeks. My wife was unable to make it due to exams as she is taking summer school. So I decided to go alone with my 3 yr old daughter. I survived the long journey to Sri Lanka thanks to my daughter putting up her best behaviour. The next day we had the wedding and again the little angle held her composure while wearing her dress in extremely hot weather during the photo shoot and church ceremony. We spent the next couple of days going shopping, a trip to the zoo and the beach. I had an extremely good time with my daughter and stayed away from my laptop (except during the Axis2 clustering hackathon at the WSO2 office in Colombo) for two weeks. I rarely checked email :) , instead I played with my kid and made the most of the time. She loved to go in three wheelers (tuk tuk) and insisted they were much more exciting than the kiddies roller coaster at Wonderland :). The return journey was a bit tough due to flight cancellations. We got stranded in Paris for a day, but used that time to relax and rest a bit before making it home.
I am well versed with diaper changing, feeding and putting her to sleep, as I take care of her when ever I work from home. But washing her at least 3 times a day and feeding 3 meals and putting her to sleep was extremely tiring. I wonder how my wife does it everyday while being a full time student. My daughter thinks Sri Lanka is much more exciting and charming with ants, flies and butterflies to chase around, cows and stray dogs all over the place, bumpy rides in three wheelers and grand parents who are ready to care for all her whim’s and fancies. Sri Lanka is indeed a charming place.

He was a visionary…..

June 7th, 2007  |  Published in General  | Add to del.icio.us

I think Sanjiva already blogged on this, but I feel obliged to do so as well.
If not for his efforts and most importantly his vision, Sri Lanka would not have progressed this far in IT. Especially his efforts in the university circuit opened the doors for many kids who otherwise would have missed the opportunity to study IT. I have met him once or twice at (ICT) Institute for Computing Technology at the Colombo university while I was a student when we were organizing an IT exhibition. If I am not mistaken, the ICT itself was his brain child. He was a pioneer in getting the “.lk” domain name.
Sometimes his work was disrupted by political pressure from various sources which didn’t like the contributions the he was making. However he continued to push towards his vision until his last breath.
Well done sir!!!! You made us all proud.

Mahela, I thought u will pull us through !!!

May 1st, 2007  |  Published in General  | Add to del.icio.us

I know enough has been written about the world cup dissapointment, but sadly I haven’t got over it yet. It was a very bad day for us. It started with rain and a shortened game which suited the aussi style of power hitting. The ICC which is quickly turning out to be a joke, and is run by a bunch of idiots who are pass their sell by date, should have postphoned the game. It’s a shame that the 100 overs was not played in a world cup final !!!!
We were at a huge disadvantage with the light deteriorating by the minute and the batsmen under pressure to stay on top of the duckworth lewis score. But yet we displayed courage and fought till the end. However credit should be given where it is due and I have to say Gillchrist played a one of a kind ininings.
I knew mahela from school days and people thought he would be playing for Sri Lanka when they saw him batting at under 13 level. I was in a match with Nalanda college at under 15 level. And Mahela single handedly took that game away from us. He was always a big game player and thought he would pull us through, just like in the semi finals. But a bad umpiring decesion ended all that.
I am looking forward to 2011!!!!

My take on JSR 311, Java API for RESTful Web Services

February 16th, 2007  |  Published in General  | Add to del.icio.us

I think doing this inside the JAX-WS space seems to give the wrong impression. I heard that they were proposing to tunnel REST services through JAX-WS endpoints. But Dan sent me the following link to a blog post by Marc Hadley which gave me some hope.

Sun always messed it up with Web Services. JAX-RPC and JAX-WS were horribly complicated with no apparent benefit other than to say the implementer is J2EE compliant. What a price to pay to have that check box in your marketing literature. They may very well make the REST API equally useless by tying it to those JAX-WS API’s.

Anyways we already have an API for REST in the form of servlets and JSP, but I agree that they weren’t good enough. IMHO they should have improved these APIs and add REST support over there, not inside JAX-WS which will fuel the myth, that REST is an alternative to SOAP, instead of REST is an alternative to SOA.

All REST API’s I have seen so far, are high level annotation driven API’s on top of a HTTP binding (servlets). For example what Dan has in XFire. I strongly believe that REST support should go into an HTTP API (servlets) instead of a WS API.

I am gratefull to see the new year !!! (Please wear seat belts)

January 1st, 2007  |  Published in General  | Add to del.icio.us

I am extreamly gratefull and feel blessed to see the new year considering the motor vehicle accident, I was involved with on the 30th Dec 06. It a was multi-vehicle accident (1 van and 3 cars) that was nothing short of a miracle considering every person involved made it through with only whiplash and one person with mild shock.
It was a routine grocery trip to costco and we were heading back home. I stopped at the lights with just one vehicle in front of us. I heard a bang behind us and before I could even think about it there was a massive bang and our car was violently thrust forward and rear ended the car in front of us. As it turned out a van had rear ended the car behind us and that in turn rear ended our car.
When I looked around I saw the car that hit us has rolled into the ditch beside the road. The car was squashed so bad I was expecting the worse. The van was thrown on to the lane right of us and has stopped parallel to us with the engine collapsed and fuel leaking towards our car.
I quickly got out and yelled to my wife to take the baby out of the car seat and we all moved on to the ditch as there was a risk of fire. The ememergency vehicles arrived in 5 mins and the firefightes took control of the situation.
All passengers were saved bcos of seat belts and considering the damaged to the rear of my vehicle I am glad that my daughter and wife were ok. Three vehicles including ours were totaled. Property can always be replaced but not human lives. So please wear seat belts and be alert when you are on the road.

Last year was the toughest of my life so far. It was also the year which I learned so much about life and realized how precious your family is. But I am proud of my fighting sprit and the effort to keep the ship steady through all the troubled times. Humans have a remarkable ability to adapt and fightback when the going gets tough.

Wish you all a Happy and a Blessed New Year.