Add an optional 'ZKMapListener' to ZooKeeperMap which fires as nodes are added, changed, or removed.

Hi John,

We talked a bit about the contribution process for proposing and implementing enhancements for the "commons" lib a few weeks ago. Thanks for your help with the pants build process.

I've attached a diff that adds an optional "ZKMapListener" to ZooKeeperMap which allows users to be notified as child ZNodes are added, modified, and removed. The change preserves existing compatibility and interfaces, with the addition of a new constructor which optionally accepts the change listener. When nodes are added or their data changed, it fires "mapListener.nodeChanged(key, value)." Similarly when removed, the listener fires "mapListener.nodeRemoved(key)."

We're in the process of phasing in a stripped-down and mavenized version of the ZooKeeperClient and ZooKeeperMap libs with this modification to power our cluster membership and distributed stream processing at Boundary. We've been using this in production for about a week and the client seems to be working well -- thanks for releasing it (previously, we'd used Twitter's scala-zookeeper-client but noticed some odd behavior). I've begun the process of integrating this version of the client into Ordasity, our clustering library for stateful stream processing on the JVM (http://github.com/boundary/ordasity). The change to ZooKeeperMap allows Ordasity to be notified as topology and workload in ZooKeeper change, triggering it to reconfigure itself appropriately.

Let me know if you'd be interested in merging this pull request or if you have questions / concerns about the implementation, code style, or comments.

Thanks,

– Scott