juju/juju — pull request #218 by jameinel (2014-07-02 06:44:11+00:00)
Title: Update 'state/api' for Facade Versioning

This updates the client-side of the code to handle API versioning. (By client, this means User facing and Agent facing.)

This is the first in a series of 2 patches. This first one lays the groundwork and has the 'interesting' changes, the next patch has the giant mechanical change as we rewrite all of the api.Client* objects to use helpers rather than re-implementing everything in each one.

Overview of changes:

1) api.State.Call renamed to api.State.APICall. We had a *lot* of objects that implement some sort of Call interface. Try doing "grep -rnI \.Call" and you'll see how many places are using it, and not all of those actually match very well. I felt this makes it a lot clearer when a given line of code is actually making an RPC request, vs just doing a local call.

2) Instead of having most of the client facades have their own "def call" implementation that wraps the 5-parameter Call into a 3-parameter call, implement that same thing as base.FacadeCaller and have all of these implementations use that. Part of the motivation here is that we need to update all of that code to start passing version information, and it is far easier to just do it right in a common helper.

3) Implement base.FacadeCaller (note that the function name here is FacadeCall, again to distinguish what layer we are at. The old code was call() calling apistate.Call() calling rpcreflect.Call() which would go over the api, and call reflect.Call of an actual method, etc.)

4) Implement BestFacadeVersion. The logic is that on the client-side (juju) we store all of the best versions that we know about, and use that information to select the newest version from the server that is <= the one that we want. You can see the code in 'facadeversions.go'.

This also adds a test that the versions stored in facadeversions.go match the actual best version that is available in the apiserver code. They are intentionally stored separately, because we don't want our runtime 'juju' code to actually depend on apiserver code. (Logically, apiserver should actually not be compiled into the 'juju' client, whether we actually manage that in real life is a different matter.)

5) Update some of the 'common' code for the FacadeCaller paradigm. There are a lot of changes that follow this as this spreads to all the other api facades, but I wanted to only have a little bit of that code to directly review.
In general, it means stuff like "common.Life" that used to take a Caller and a facadeName, can just take the FacadeCaller directly.