I think we should not make ZkCLI a Swiss Army Knife. ZkCLI should deal with ZK operations, like uploading and downloading. Changing then content of a json-file is not a ZK operation. Why not see it as different things. So what you need to do if you want to make arbitrary changes to json-content of a znode in ZK is
zkcli getfile thefile.json
<use another tool for modifying thefile.json>
zkcli putfile thefile.json
It would be nice to make different tools that can make operations on the different types of jsons we have in a safe way - ensuring e.g. consistency, integrity, validity etc. But I think those tools should use the classes already handling those jsons, and not have anything to do with ZkCLI. E.g. a tool for manipulating clusterstate.json should use classes from org.apache.solr.common.cloud in solrj project, like ZkStateReader, ClusterState, ClusterStateUpdater etc. Then it is always those classes that are used to operate on a specific type of json, and we only have to build consistency, integrity, validity etc into those classes (separation of concern). The new thing should be that those classes can be used via an external tool also when no Solr nodes are running.
At least make sure to use those existing classes for actually reading/writing/verifying the jsons, and make separate tool-classes. Changing ZkCLI to be able to trigger operations in those tool-classes is less important, but personally I do not like - actually, if it has to be, I would rather see e.g. an ClusterPropCLI-tool support a "do-in-zk"-flag making it use ZkCLI tool to download first, do its manipulations and then use ZkCLI to upload again. That is, new tools that use ZkCLI (if you are too lazy doing the download/upload using ZkCLI yourself), instead of the other way around, where ZkCLI uses other tools or even just does json-manipulation itself. Please do not try to implement rules about what can and cannot be in a specific type of json, what operations you can do on it etc two places in the code-base - use what we already have.
Would like to see clean definitions of which classes own responsibilities. E.g.
- ClusterState.java own the responsibility of a clusterstate.json always being consistent, valid etc. You never do changes to clusterstate.json with using ClusterState.java
- ClusterStateUpdater own the set of allowed operations on clusterstate.json. You never manipulate a clusterstate.json without going through ClusterStateUpdater. The new off-line ClusterStateCLI-tool should use ClusterStateUpdater to do its operations - just change ClusterStateUpdater, so that it support receiving jobs not coming from other sources than overseer queue.
Yes, I know you primarily talk about ClusterProps, but the principle will be the same. It is just that I know more about which classes handle cluster-state than which handle cluster-props.
That said, maybe you can live with using e.g. http://trentm.com/json/ (or one of the million other command-line json tools available) in <use another tool for modifying thefile.json> above?