On Thu, Feb 14, 2013 at 04:24:48PM -0800, Frank Zhang wrote:
> I have said too much about XML files recently, excuse me for raising this 
> topic again, 
> I really want to elaborate why text (e.g XML) configuration files is so 
> important and how 
> it decouples your project especially for project written by static language 
> like java.
> 
> Let me cite our new ApiDiscoveryService as an example(This service is very 
> good, I use it
> as example just because I encounter a small problem and the problem is a good 
> study case
> for decoupling code using text configuration files).
> 
> The problem is: ApiDiscoveryService discovers API commands by invoking 
> PluggableService. getCommands().
> Each plugin service needs to implement getCommands() which returns a 
> List<Class<?>> including classes of
> API command the plugin service supports. This is good, lots of project use 
> similar way in plugin system.
> 
> ManagementServerImpl is a special API service, it registers all orchestration 
> API commands like *addHost*. Now
> I have a special API called *addBaremetalHost* which inherits *addHost* 
> adding one more field.  *addBaremetalHost*
> is actually handled by the same orchestration code as *addHost*(but different 
> HostDiscover which is another story),
> unfortunately, this API belongs to my Baremetal plugin that means I can't add 
> it into  ManagementServerImpl. getCommands()
> because orchestration code should not have a dependency to plugin code.
> 
> The solution is simple, I use a BaremetalManager to register 
> *addBaremetalHost* and inject/call orchestration code to deal with it.
> 
> However, this case shows us how compiling time dependency in static language 
> makes your code tight coupling. 
> Everybody programing in java/C/C++ knows the pain of planning your project 
> skeleton to avoid circular dependency. 
> One of solutions is to use text configuration file. Back to our example, 
> ApiDiscoveryService, we can put a folder which
> stores API configuration XML at a well-known place, every PluggableService 
> has a XML file describing its API and Spring bean
> name in the folder. for example:
> 
> <apiService>
>       <api>
>               <command> 
> com.cloud.baremetal.manager.AddBaremetalHostCmd</command>
>               <acl>some acl</acl>
>               <owner>Spring_bean_name_of_baremetal_manager</owner>
>       </api>          
> <apiService>
> 
> When ApiDiscoveryService starts, it scans the folder and parses XML files to 
> discover every api/theirs properties/owner bean. By doing this, 
> ApiDiscoveryService/
> PluggableService/API command classes totally have no compiling time 
> dependency, they can freely seat in any packages as long as these packages 
> present in
> classpath during runtime. To my case, I don't have to inject orchestration 
> code in my plugin anymore,  I just use a XML file to tell ApiDiscoveryService 
> that addBaremetalHost
> is taken cared by ManagementServerImpl as well though ManagementServerImpl 
> has no knowledge about it.
> 
> CloudStack used to have similar idea command.properties, unfortunately it's 
> only used as ACL declaration now.
> 
> This is a trivial example,  but it reflects a truth that compiling dependency 
> is naturally making your code tight. Many people criticize dynamic language 
> is error-prone because it
> lacks compiling time check, but as another side of coin, it's also easy to 
> produce loose-coupling code. Thinking about OpenStack, if you were going to 
> use Java to fork it, I am pretty
> sure the compiling time dependency will drive you crazy.  For instance, 
> java-nova and java-cinder both need to know Volume that represents vm disk, 
> now where do you define it? in java-nova?
> in java-cinder? Then who depends on who? Or totally don't define any data 
> structure, using a HashMap to transmit primitive variables, then where is 
> beauty of compiling check?
> 
> As we have adopted Spring that uses XML a lot in CloudStack, I suggest us 
> taking more consideration of text configuration file when designing a new 
> feature. it really works.
> 
>

+1 to what Frank is saying.  Runtime configuration is much more flexible
than compile-time scenarios!

-chip

Reply via email to