Lessons in software architecture from Bruce Lee

I’m an avid software architect and for even longer have been an avid martial artist (though admittedly I practice the former much more than the latter these days).  As I’ve watched what almost amounts to a holy war between the REST and SOAP crowds (and all the other factions in general software development) I thought back to some of my martial arts training and to my personal hero: Bruce Lee.  He may be seen now as a cult icon, but in his life he was an extraordinary martial artist.  To those not in the know true martial arts is a mix of mind, body, and spirit; of philosophy and physicality.  So why Bruce Lee?  What does he have to do with software development?  I think he has a lot more relevance there than most would guess and I would also venture that martial arts have a lot of parallels to the programming arts. 

I was encouraged to finally start this series after reflecting upon how easy it is for all of us to get caught up in the patterns and practices that we know and forget to look at the current situation at hand.  As I learned in my martial arts training: the black belt is not the end, but merely the beginning.  This series will be a collection of Bruce Lee quotes that I believe apply directly to software architecture and development.  The first quote I have chosen is the following:

“I have not invented a “new style,” composite, modified or otherwise that is set within distinct form as apart from “this” method or “that” method. On the contrary, I hope to free my followers from clinging to styles, patterns, or molds.”

I’m not sure this quote really needs explanation, but it gets to the heart of what much of Bruce Lee’s philosophy was: prepare for everything and be flexible for anything.  Do not let what you know or the latest fad get in the way of doing what is appropriate for the task at hand.  This holds true if the task is a combat situation or mobile service development. 

More messaging like Rabbits

After playing around some with RabbitMQ I decided I’d really let BizTalk message like rabbits.  I modified the file send port so that it sent back to the same queue instead of to the file location.  This creates a feedback loop so a message will keep propagating.  Then to make it more “rabbit like” I added a send port group that had the filter: BTS.ReceivePortName == RMQI_Q_Receive Or BTS.ReceivePortName == RMQI_Receive_Start

This way starting with the first message received from the file drop; every message receive results in two sends to the queue (which just feeds back and results in another doubling of messages). 

Two things became readily apparent.  BizTalk scales well and works fast and RabbitMQ will certainly keep pace.  In moments I had thousands of messages flying through my system. 

Checking the Queues section of the RabbitMQ management portal I was easily able to see the volume flowing through.  I almost think this could be a good benchmarking tool for BizTalk, but the BizTalk Benchmark Wizard is already so good I don’t really think I need a RabbitMQ based one. 

Messaging like Rabbits

I have been all kinds of excited about AMQP lately and yesterday’s news from David Ingham about AMQP on Service Bus got me pretty excited.  Obviously I’m always excited about BizTalk and my work lately has pushed me far heavier into the WCF-Adapters than I had previously gone (including using WCF 4.5 features from within BizTalk 2010). 

Eager to try some AMQP out and not willing to wait I decided I’d give RabbitMQ a try.  I knew they had a WCF binding for their implementation and decided it would probably be a good place to start.  This way I could placate my “open source” critics and also get some good AMQP fun going on Windows… quickly (I’m told AMQP works on Linux too). 

The setup was pretty easy for the server aspect, but the client part was not so much.  Leonid Ganeline’s awesome TechNet article on this helped me very much: http://social.technet.microsoft.com/wiki/contents/articles/7401.biztalk-and-rabbitmq.aspx.

I knew I had to GAC the assemblies and register the binding in machine.config, but I couldn’t find the assemblies anywhere (neither could Leonid), so I ended up building them locally (though you can strong name assemblies after they’re compiled I instead just added a key and strong named them).  I also changed the target to .NET 4.0.  You need to compile RabbitMQ.Client and RabbitMQ.ServiceModel.

I followed a very similar pattern with a file drop that Leonid did and it worked great.  I’m playing around with the graphical tools (management console) for RabbitMQ and I still don’t really know what many of these defaults are, but I do plan to work on it a bit more. 

Windows Azure 1.6/1.5 SDK Service Bus Authentication issue: 40102: Missing Authorization Token

I’ve been playing  a lot with the Azure 1.6 SDK and have been enjoying it quite a bit.  I’m in the process of modifying some of the examples in BizTalk 2010 Patterns to use Azure and ran into an interesting issue that seems to have only affected Service Bus.  I was trying to use queues as a destination and kept receiving this error:

The adapter failed to transmit message going to send port “OP_File_Send_CRM_SalesOrder” with URL “sb://XXXXXX.servicebus.windows.net/salesorders”. It will be retransmitted after the retry interval specified for this Send Port. Details:”System.UnauthorizedAccessException: 40102: Missing Authorization Token.TrackingId:8ac56df4-4094-495b-b302-ddf3c842efe7_6,TimeStamp:3/7/2012 6:38:19 PM —> System.ServiceModel.FaultException: 40102: Missing Authorization Token.TrackingId:8ac56df4-4094-495b-b302-ddf3c842efe7_6,TimeStamp:3/7/2012 6:38:19 PM

I assumed that I must have been using ACS incorrectly and decided to try the owner token.  Still no luck – though I did learn a lot about claims in ACS.  I also tried many permutations switching between transportClientEndpointBehavior settings for ClientCredentials and TokenProvider.

After far too long I remembered something from last week’s MVP Summit.  There had been discussion about versions of the SDK in use and the process of changing to another.  Another MVP said something about having to cut over.  I’m sure this is common knowledge to many (and probably in the SDK readme / docs), but I thought, well maybe I need to uninstall the old SDK.  Before I did this I thought I’d run the RelayConfigurationInstall and uninstall all the previous 1.5 bits that had been on my system (I vaguely remember running this ages ago when I installed 1.5).  I opened a command line to C:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies and ran:

RelayConfigurationInstaller.exe /u

I then uninstalled the 1.5 SDK.  Finally I ran the RelayConfigurationInstall from the 1.6 SDK (located at C:\Program Files\Windows Azure SDK\v1.6\ServiceBus\bin).

RelayConfigurationInstaller.exe /i

Amazingly everything worked after that with no other changes.  I was set!

Favorite “New BizTalk Feature” and yet another reason BizTalk rocks

As most know by now the Visual Studio 11 Beta came out last week.  I have been eagerly trying out new features since I installed it at the MVP Summit.  The WCF features had me the most excited so far.  I have been discussing using UDP from BizTalk (via WCF) for some time with friends and coworkers.

I know there has been a “guidance” on this for some time, but many clients don’t like a guidance, they want something supported and in their platform.  Today my friend and coworker Madhav tied it all together.  He blogged about it here:

http://maddcoder.wordpress.com/2012/03/05/udp-broadcast-using-biztalk-server-2010-19/

It’s a great post and it opens a new world of opportunities for many WCF (and BizTalk) developers).  Most impressively to me is that BizTalk 2010 just works with the new bindings that are a part of WCF 4.5.  I think this is a great testament to the platform and the decision five years ago to move towards WCF for adapters.  It was awesome to see this today!

Fourteen Years of Software Architecture in 500 words

As I look back over an aggressive software development career now spanning back into the late nineties I stand at what I consider to be a very fortunate point.  I have deep experience with C++, C# (all of .NET), a plethora of distributed systems environments and tools, and more XML, messaging and database knowledge than is probably healthy for a developer.  I have enough experience to know when and why to follow certain patterns when developing systems and what to avoid (largely through trial and error – emphasis in the error part).  I also have an amazing job with a fantastic company in which I get to help budding developers and architects grow their careers.  This is the best part of my job.  These people push me to be my best and rethink everything I know (or think I do) all the time.  While doing so I was inspired to distill the essence of my software design approach into as few words as possible while still being entertaining (without the last part I was at 200 words). 

As a note I’ve not included this introduction in the word count. 

 

Start with use cases

Yea, maybe I’m dating myself here, but ultimately there is no real substitute for this.  All software starts and ends with a user otherwise it wouldn’t exist.  You can use stories if you like, but what you would start with in that case are notes about stories (from your conversations).  Look at what you have; it could be something like (randomly grabbed these from an old project):

As a customer I would like to be able to view my account balance

As an AR clerk I need to be able to apply a credit to an account

 

Extract core entities and services

I like to print these out myself (or copy the cards), but if you’re working in a word processor that’s fine too.  At this point Circle the nouns.  These are your basic system entities.  Now highlight the verbs; these are the services (whether they are web services or class methods, they are still services – go read Booch). 

In our examples above we have the following results.

As a customer I would like to be able to view my account balance

As an AR clerk I need to be able to apply a credit to an account

I’ve purposely not circled balance because that’s really more of an attribute of an account.  Already I can see a few things emerging.  Clearly the account entity is important, it’s in both stories.  Continue doing this until you whittle down the most recurring entities and the services that involve them.  You’ll have a little decision making here as to what is really an entity and what is an attribute. 

 

Return the focus to the user

Now zoom back out to the user level / UI.  Validate that your assumptions are correct and gather the entity specific attributes from the user or UI (again if it doesn’t get seen, you can probably defer it for a little while longer).  The focus on this user part is really to drive back to the service.  Again I use that term service because this may be a single operation / method or it may be many that are related (a composite service).  The only thing I can really say for sure is that it shouldn’t live in your entities.  It mixes data and processing / functionality too much and introduces coupling.  These are really the business services; we’ve left all the infrastructure out (like repositories).  That’s much more aesthetic and won’t fit into 500 worlds, but now is when you want to do it. 

Create storage

Notice this is my last step.  There’s a reason for that.  There was a time when data driven applications (or designs) were all the rage, but what everyone forgot was that the data still came from users.  Coupling data too closely to the core design can be dangerous.  Here you have to make many choices about how to store data.  By leaving this last, behind repositories, you’re free to choose whatever implementation you like. 

Conclusion – also not in world count

Our craft is really just that – a craft.  There are a lot of grey areas and many tradeoffs to be assessed.  Parts of it are as hard as science like memory management, which even in managed languages is still there, parallelization, and concurrency.  But other parts are much more subjective and require come critical skills and even language skills (as seen above) that are also vitally important to success.