SOLR-6533: logging added and formatting fixed

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1658916 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2015-02-11 10:40:03 +00:00
parent 78e1153dcb
commit 648eebbe92
3 changed files with 194 additions and 167 deletions

View File

@ -2138,37 +2138,38 @@ public final class ZkController {
*
* @return true on success
*/
public static boolean persistConfigResourceToZooKeeper( ZkSolrResourceLoader zkLoader, int znodeVersion ,
String resourceName, byte[] content,
boolean createIfNotExists) {
public static boolean persistConfigResourceToZooKeeper(ZkSolrResourceLoader zkLoader, int znodeVersion,
String resourceName, byte[] content,
boolean createIfNotExists) {
final ZkController zkController = zkLoader.getZkController();
final SolrZkClient zkClient = zkController.getZkClient();
final String resourceLocation = zkLoader.getConfigSetZkPath() + "/" + resourceName;
String errMsg = "Failed to persist resource at {0} - old {1}";
try {
try {
zkClient.setData(resourceLocation , content,znodeVersion, true);
zkClient.setData(resourceLocation, content, znodeVersion, true);
log.info("Persisted config data to node {} ", resourceLocation);
touchConfDir(zkLoader);
} catch (NoNodeException e) {
if(createIfNotExists){
if (createIfNotExists) {
try {
zkClient.create(resourceLocation,content, CreateMode.PERSISTENT,true);
zkClient.create(resourceLocation, content, CreateMode.PERSISTENT, true);
touchConfDir(zkLoader);
} catch (KeeperException.NodeExistsException nee) {
try {
Stat stat = zkClient.exists(resourceLocation, null, true);
log.info("failed to set data version in zk is {0} and expected version is {1} ", stat.getVersion(),znodeVersion);
log.info("failed to set data version in zk is {0} and expected version is {1} ", stat.getVersion(), znodeVersion);
} catch (Exception e1) {
log.warn("could not get stat");
}
log.info(MessageFormat.format(errMsg,resourceLocation,znodeVersion));
throw new ResourceModifiedInZkException(ErrorCode.CONFLICT, MessageFormat.format(errMsg,resourceLocation,znodeVersion) + ", retry.");
log.info(MessageFormat.format(errMsg, resourceLocation, znodeVersion));
throw new ResourceModifiedInZkException(ErrorCode.CONFLICT, MessageFormat.format(errMsg, resourceLocation, znodeVersion) + ", retry.");
}
}
}
} catch (KeeperException.BadVersionException bve){
} catch (KeeperException.BadVersionException bve) {
int v = -1;
try {
Stat stat = zkClient.exists(resourceLocation, null, true);
@ -2177,9 +2178,9 @@ public final class ZkController {
log.error(e.getMessage());
}
log.info(MessageFormat.format(errMsg+ " zkVersion= "+v,resourceLocation,znodeVersion));
throw new ResourceModifiedInZkException(ErrorCode.CONFLICT, MessageFormat.format(errMsg,resourceLocation,znodeVersion) + ", retry.");
}catch (ResourceModifiedInZkException e){
log.info(MessageFormat.format(errMsg + " zkVersion= " + v, resourceLocation, znodeVersion));
throw new ResourceModifiedInZkException(ErrorCode.CONFLICT, MessageFormat.format(errMsg, resourceLocation, znodeVersion) + ", retry.");
} catch (ResourceModifiedInZkException e) {
throw e;
} catch (Exception e) {
if (e instanceof InterruptedException) {
@ -2192,10 +2193,10 @@ public final class ZkController {
return true;
}
public static void touchConfDir(ZkSolrResourceLoader zkLoader) {
public static void touchConfDir(ZkSolrResourceLoader zkLoader) {
SolrZkClient zkClient = zkLoader.getZkController().getZkClient();
try {
zkClient.setData(zkLoader.getConfigSetZkPath(),new byte[]{0},true);
zkClient.setData(zkLoader.getConfigSetZkPath(), new byte[]{0}, true);
} catch (Exception e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt(); // Restore the interrupted status

View File

@ -90,16 +90,17 @@ public class SolrConfigHandler extends RequestHandlerBase {
setWt(req, "json");
String httpMethod = (String) req.getContext().get("httpMethod");
Command command = new Command(req, rsp, httpMethod);
if("POST".equals(httpMethod)){
if(configEditing_disabled) throw new SolrException(SolrException.ErrorCode.FORBIDDEN," solrconfig editing is not enabled");
if ("POST".equals(httpMethod)) {
if (configEditing_disabled)
throw new SolrException(SolrException.ErrorCode.FORBIDDEN, " solrconfig editing is not enabled");
command.handlePOST();
} else {
} else {
command.handleGET();
}
}
private static class Command{
private static class Command {
private final SolrQueryRequest req;
private final SolrQueryResponse resp;
private final String method;
@ -111,9 +112,9 @@ public class SolrConfigHandler extends RequestHandlerBase {
this.resp = resp;
this.method = httpMethod;
path = (String) req.getContext().get("path");
if(path == null) path= getDefaultPath();
parts =StrUtils.splitSmart(path, '/');
if(parts.get(0).isEmpty()) parts.remove(0);
if (path == null) path = getDefaultPath();
parts = StrUtils.splitSmart(path, '/');
if (parts.get(0).isEmpty()) parts.remove(0);
}
private String getDefaultPath() {
@ -121,28 +122,28 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
private void handleGET() {
if(parts.size() == 1) {
if (parts.size() == 1) {
resp.add("config", getConfigDetails());
} else {
if(ConfigOverlay.NAME.equals(parts.get(1))){
if (ConfigOverlay.NAME.equals(parts.get(1))) {
resp.add(ConfigOverlay.NAME, req.getCore().getSolrConfig().getOverlay().toMap());
}else if(RequestParams.NAME.equals(parts.get(1))) {
if(parts.size() == 3){
} else if (RequestParams.NAME.equals(parts.get(1))) {
if (parts.size() == 3) {
RequestParams params = req.getCore().getSolrConfig().getRequestParams();
MapSolrParams p = params.getParams(parts.get(2));
Map m =new LinkedHashMap<>();
Map m = new LinkedHashMap<>();
m.put(ConfigOverlay.ZNODEVER, params.getZnodeVersion());
if(p!=null){
m.put(RequestParams.NAME,ZkNodeProps.makeMap(parts.get(2), p.getMap()));
if (p != null) {
m.put(RequestParams.NAME, ZkNodeProps.makeMap(parts.get(2), p.getMap()));
}
resp.add(SolrQueryResponse.NAME, m);
} else {
resp.add(SolrQueryResponse.NAME,req.getCore().getSolrConfig().getRequestParams().toMap());
resp.add(SolrQueryResponse.NAME, req.getCore().getSolrConfig().getRequestParams().toMap());
}
} else {
Map<String, Object> m = getConfigDetails();
resp.add("config", ZkNodeProps.makeMap(parts.get(1),m.get(parts.get(1))));
resp.add("config", ZkNodeProps.makeMap(parts.get(1), m.get(parts.get(1))));
}
}
}
@ -150,12 +151,12 @@ public class SolrConfigHandler extends RequestHandlerBase {
private Map<String, Object> getConfigDetails() {
Map<String, Object> map = req.getCore().getSolrConfig().toMap();
Map reqHandlers = (Map) map.get(SolrRequestHandler.TYPE);
if(reqHandlers == null) map.put(SolrRequestHandler.TYPE, reqHandlers = new LinkedHashMap<>());
if (reqHandlers == null) map.put(SolrRequestHandler.TYPE, reqHandlers = new LinkedHashMap<>());
List<PluginInfo> plugins = PluginsRegistry.getHandlers(req.getCore());
for (PluginInfo plugin : plugins) {
if(SolrRequestHandler.TYPE.equals( plugin.type)){
if(!reqHandlers.containsKey(plugin.name)){
reqHandlers.put(plugin.name,plugin.toMap());
if (SolrRequestHandler.TYPE.equals(plugin.type)) {
if (!reqHandlers.containsKey(plugin.name)) {
reqHandlers.put(plugin.name, plugin.toMap());
}
}
}
@ -173,18 +174,18 @@ public class SolrConfigHandler extends RequestHandlerBase {
for (ContentStream stream : streams)
ops.addAll(CommandOperation.parse(stream.getReader()));
List<Map> errList = CommandOperation.captureErrors(ops);
if(!errList.isEmpty()) {
resp.add(CommandOperation.ERR_MSGS,errList);
if (!errList.isEmpty()) {
resp.add(CommandOperation.ERR_MSGS, errList);
return;
}
try {
for (;;) {
for (; ; ) {
ArrayList<CommandOperation> opsCopy = new ArrayList<>(ops.size());
for (CommandOperation op : ops) opsCopy.add(op.getCopy());
try {
if(parts.size()>1 && RequestParams.NAME.equals(parts.get(1))){
RequestParams params = RequestParams.getFreshRequestParams(req.getCore().getResourceLoader(),req.getCore().getSolrConfig().getRequestParams());
if (parts.size() > 1 && RequestParams.NAME.equals(parts.get(1))) {
RequestParams params = RequestParams.getFreshRequestParams(req.getCore().getResourceLoader(), req.getCore().getSolrConfig().getRequestParams());
handleParams(opsCopy, params);
} else {
ConfigOverlay overlay = SolrConfig.getConfigOverlay(req.getCore().getResourceLoader());
@ -193,7 +194,7 @@ public class SolrConfigHandler extends RequestHandlerBase {
break;//succeeded . so no need to go over the loop again
} catch (ZkController.ResourceModifiedInZkException e) {
//retry
log.info("Race condition, the node is modified in ZK by someone else " +e.getMessage());
log.info("Race condition, the node is modified in ZK by someone else " + e.getMessage());
}
}
} catch (Exception e) {
@ -204,7 +205,6 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
private void handleParams(ArrayList<CommandOperation> ops, RequestParams params) {
for (CommandOperation op : ops) {
switch (op.name) {
@ -215,7 +215,7 @@ public class SolrConfigHandler extends RequestHandlerBase {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Map val =null;
Map val = null;
String key = entry.getKey();
if (key == null || key.trim().isEmpty()) {
op.addError("null key ");
@ -223,7 +223,7 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
key = key.trim();
String err = validateName(key);
if (err !=null) {
if (err != null) {
op.addError(err);
continue;
}
@ -268,16 +268,16 @@ public class SolrConfigHandler extends RequestHandlerBase {
List errs = CommandOperation.captureErrors(ops);
if (!errs.isEmpty()) {
resp.add(CommandOperation.ERR_MSGS,errs);
resp.add(CommandOperation.ERR_MSGS, errs);
return;
}
SolrResourceLoader loader = req.getCore().getResourceLoader();
if (loader instanceof ZkSolrResourceLoader) {
ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) loader;
if(ops.isEmpty()) {
if (ops.isEmpty()) {
ZkController.touchConfDir(zkLoader);
}else {
} else {
ZkController.persistConfigResourceToZooKeeper(zkLoader, params.getZnodeVersion(),
RequestParams.RESOURCE, params.toByteArray(), true);
}
@ -289,59 +289,63 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
private void handleCommands(List<CommandOperation> ops, ConfigOverlay overlay ) throws IOException {
for (CommandOperation op : ops) {
switch (op.name) {
case SET_PROPERTY:
overlay = applySetProp(op, overlay);
break;
case UNSET_PROPERTY:
overlay = applyUnset(op, overlay);
break;
case SET_USER_PROPERTY:
overlay = applySetUserProp(op, overlay);
break;
case UNSET_USER_PROPERTY:
overlay = applyUnsetUserProp(op, overlay);
break;
default: {
List<String> pcs = StrUtils.splitSmart(op.name.toLowerCase(Locale.ROOT), '-');
if (pcs.size() != 2) {
op.addError(MessageFormat.format("Unknown operation ''{0}'' ", op.name));
} else {
String prefix = pcs.get(0);
String name = pcs.get(1);
if (cmdPrefixes.contains(prefix) && namedPlugins.containsKey(name)) {
SolrConfig.SolrPluginInfo info = namedPlugins.get(name);
if ("delete".equals(prefix)) {
overlay = deleteNamedComponent(op, overlay, info.tag);
} else {
overlay = updateNamedPlugin(info, op, overlay, prefix.equals("create"));
}
} else {
private void handleCommands(List<CommandOperation> ops, ConfigOverlay overlay) throws IOException {
for (CommandOperation op : ops) {
switch (op.name) {
case SET_PROPERTY:
overlay = applySetProp(op, overlay);
break;
case UNSET_PROPERTY:
overlay = applyUnset(op, overlay);
break;
case SET_USER_PROPERTY:
overlay = applySetUserProp(op, overlay);
break;
case UNSET_USER_PROPERTY:
overlay = applyUnsetUserProp(op, overlay);
break;
default: {
List<String> pcs = StrUtils.splitSmart(op.name.toLowerCase(Locale.ROOT), '-');
if (pcs.size() != 2) {
op.addError(MessageFormat.format("Unknown operation ''{0}'' ", op.name));
} else {
String prefix = pcs.get(0);
String name = pcs.get(1);
if (cmdPrefixes.contains(prefix) && namedPlugins.containsKey(name)) {
SolrConfig.SolrPluginInfo info = namedPlugins.get(name);
if ("delete".equals(prefix)) {
overlay = deleteNamedComponent(op, overlay, info.tag);
} else {
overlay = updateNamedPlugin(info, op, overlay, prefix.equals("create"));
}
} else {
op.addError(MessageFormat.format("Unknown operation ''{0}'' ", op.name));
}
}
}
}
}
}
List errs = CommandOperation.captureErrors(ops);
if (!errs.isEmpty()) {
resp.add(CommandOperation.ERR_MSGS,errs);
return;
List errs = CommandOperation.captureErrors(ops);
if (!errs.isEmpty()) {
log.info("Failed to run commands errors are {}", StrUtils.join(errs, ','));
resp.add(CommandOperation.ERR_MSGS, errs);
return;
}
SolrResourceLoader loader = req.getCore().getResourceLoader();
if (loader instanceof ZkSolrResourceLoader) {
ZkController.persistConfigResourceToZooKeeper((ZkSolrResourceLoader) loader, overlay.getZnodeVersion(),
ConfigOverlay.RESOURCE_NAME, overlay.toByteArray(), true);
log.info("Executed config commands successfully and persited to ZK {}", ops);
} else {
SolrResourceLoader.persistConfLocally(loader, ConfigOverlay.RESOURCE_NAME, overlay.toByteArray());
req.getCore().getCoreDescriptor().getCoreContainer().reload(req.getCore().getName());
log.info("Executed config commands successfully and persited to File System {}", ops);
}
}
SolrResourceLoader loader = req.getCore().getResourceLoader();
if (loader instanceof ZkSolrResourceLoader) {
ZkController.persistConfigResourceToZooKeeper((ZkSolrResourceLoader) loader,overlay.getZnodeVersion(),
ConfigOverlay.RESOURCE_NAME,overlay.toByteArray(),true);
} else {
SolrResourceLoader.persistConfLocally(loader, ConfigOverlay.RESOURCE_NAME, overlay.toByteArray());
req.getCore().getCoreDescriptor().getCoreContainer().reload(req.getCore().getName());
}
}
private ConfigOverlay deleteNamedComponent(CommandOperation op, ConfigOverlay overlay, String typ) {
String name = op.getStr(CommandOperation.ROOT_OBJ);
if (op.hasError()) return overlay;
@ -353,7 +357,7 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
}
private ConfigOverlay updateNamedPlugin(SolrConfig.SolrPluginInfo info , CommandOperation op, ConfigOverlay overlay, boolean isCeate) {
private ConfigOverlay updateNamedPlugin(SolrConfig.SolrPluginInfo info, CommandOperation op, ConfigOverlay overlay, boolean isCeate) {
String name = op.getStr(NAME);
String clz = op.getStr(CLASS_NAME);
op.getMap(PluginInfo.DEFAULTS, null);
@ -394,7 +398,7 @@ public class SolrConfigHandler extends RequestHandlerBase {
private ConfigOverlay applySetUserProp(CommandOperation op, ConfigOverlay overlay) {
Map<String, Object> m = op.getDataMap();
if(op.hasError()) return overlay;
if (op.hasError()) return overlay;
for (Map.Entry<String, Object> e : m.entrySet()) {
String name = e.getKey();
Object val = e.getValue();
@ -405,9 +409,9 @@ public class SolrConfigHandler extends RequestHandlerBase {
private ConfigOverlay applyUnsetUserProp(CommandOperation op, ConfigOverlay overlay) {
List<String> name = op.getStrs(CommandOperation.ROOT_OBJ);
if(op.hasError()) return overlay;
if (op.hasError()) return overlay;
for (String o : name) {
if(!overlay.getUserProps().containsKey(o)) {
if (!overlay.getUserProps().containsKey(o)) {
op.addError(format("No such property ''{0}''", name));
} else {
overlay = overlay.unsetUserProperty(o);
@ -417,13 +421,12 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
private ConfigOverlay applyUnset(CommandOperation op, ConfigOverlay overlay) {
List<String> name = op.getStrs(CommandOperation.ROOT_OBJ);
if(op.hasError()) return overlay;
if (op.hasError()) return overlay;
for (String o : name) {
if(!ConfigOverlay.isEditableProp(o, false, null)) {
if (!ConfigOverlay.isEditableProp(o, false, null)) {
op.addError(format(NOT_EDITABLE, name));
} else {
overlay = overlay.unsetProperty(o);
@ -434,11 +437,11 @@ public class SolrConfigHandler extends RequestHandlerBase {
private ConfigOverlay applySetProp(CommandOperation op, ConfigOverlay overlay) {
Map<String, Object> m = op.getDataMap();
if(op.hasError()) return overlay;
if (op.hasError()) return overlay;
for (Map.Entry<String, Object> e : m.entrySet()) {
String name = e.getKey();
Object val = e.getValue();
if(!ConfigOverlay.isEditableProp(name, false, null)) {
if (!ConfigOverlay.isEditableProp(name, false, null)) {
op.addError(format(NOT_EDITABLE, name));
continue;
}
@ -450,26 +453,26 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
public static String validateName(String s) {
for(int i=0;i<s.length();i++) {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if((c >= 'A' && c<='Z') ||
(c >='a' && c<='z') ||
(c >='0' && c<='9') ||
c == '_'||
c == '-'||
c == '.'
if ((c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
c == '_' ||
c == '-' ||
c == '.'
) continue;
else {
return MessageFormat.format("''{0}'' name should only have chars [a-zA-Z_-.0-9] ",s);
return MessageFormat.format("''{0}'' name should only have chars [a-zA-Z_-.0-9] ", s);
}
}
return null;
}
static void setWt(SolrQueryRequest req, String wt){
static void setWt(SolrQueryRequest req, String wt) {
SolrParams params = req.getParams();
if( params.get(CommonParams.WT) != null ) return;//wt is set by user
Map<String,String> map = new HashMap<>(1);
if (params.get(CommonParams.WT) != null) return;//wt is set by user
Map<String, String> map = new HashMap<>(1);
map.put(CommonParams.WT, wt);
map.put("indent", "true");
req.setParams(SolrParams.wrapDefaults(params, new MapSolrParams(map)));
@ -477,16 +480,18 @@ public class SolrConfigHandler extends RequestHandlerBase {
@Override
public SolrRequestHandler getSubHandler(String path) {
if(subPaths.contains(path)) return this;
if(path.startsWith("/params/")) return this;
if (subPaths.contains(path)) return this;
if (path.startsWith("/params/")) return this;
return null;
}
private static Set<String> subPaths = new HashSet<>(Arrays.asList("/overlay", "/params",
"/query","/jmx","/requestDispatcher"));
private static Set<String> subPaths = new HashSet<>(Arrays.asList("/overlay", "/params",
"/query", "/jmx", "/requestDispatcher"));
static {
for (SolrConfig.SolrPluginInfo solrPluginInfo : SolrConfig.plugins) subPaths.add("/"+solrPluginInfo.tag.replaceAll("/",""));
for (SolrConfig.SolrPluginInfo solrPluginInfo : SolrConfig.plugins)
subPaths.add("/" + solrPluginInfo.tag.replaceAll("/", ""));
}
@ -510,7 +515,6 @@ public class SolrConfigHandler extends RequestHandlerBase {
}
public static final String SET_PROPERTY = "set-property";
public static final String UNSET_PROPERTY = "unset-property";
public static final String SET_USER_PROPERTY = "set-user-property";
@ -518,6 +522,6 @@ public class SolrConfigHandler extends RequestHandlerBase {
public static final String SET = "set";
public static final String UPDATE = "update";
public static final String CREATE = "create";
private static Set<String> cmdPrefixes = ImmutableSet.of(CREATE , UPDATE, "delete");
private static Set<String> cmdPrefixes = ImmutableSet.of(CREATE, UPDATE, "delete");
}

View File

@ -19,6 +19,7 @@ package org.apache.solr.util;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
@ -26,14 +27,17 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.common.cloud.ZkStateReader;
import org.noggit.JSONParser;
import org.noggit.ObjectBuilder;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.solr.common.cloud.ZkNodeProps.makeMap;
public class CommandOperation {
public class CommandOperation {
public final String name;
private Object commandData;//this is most often a map
private List<String> errors = new ArrayList<>();
@ -43,16 +47,16 @@ public class CommandOperation {
this.name = operationName;
}
public String getStr(String key, String def){
if(ROOT_OBJ.equals(key)){
public String getStr(String key, String def) {
if (ROOT_OBJ.equals(key)) {
Object obj = getRootPrimitive();
return obj == def ? null: String.valueOf(obj);
return obj == def ? null : String.valueOf(obj);
}
String s = (String) getMapVal(key);
return s == null ? def : s;
}
public Map<String,Object> getDataMap(){
public Map<String, Object> getDataMap() {
if (commandData instanceof Map) {
return (Map) commandData;
}
@ -60,16 +64,16 @@ public class CommandOperation {
return Collections.EMPTY_MAP;
}
private Object getRootPrimitive(){
private Object getRootPrimitive() {
if (commandData instanceof Map) {
errors.add(MessageFormat.format("The value has to be a string for command : ''{0}'' ",name));
errors.add(MessageFormat.format("The value has to be a string for command : ''{0}'' ", name));
return null;
}
return commandData;
}
public Object getVal(String key){
public Object getVal(String key) {
return getMapVal(key);
}
@ -78,43 +82,45 @@ public class CommandOperation {
Map metaData = (Map) commandData;
return metaData.get(key);
} else {
String msg= " value has to be an object for operation :"+name;
if(!errors.contains(msg)) errors.add(msg);
String msg = " value has to be an object for operation :" + name;
if (!errors.contains(msg)) errors.add(msg);
return null;
}
}
public List<String> getStrs(String key){
public List<String> getStrs(String key) {
List<String> val = getStrs(key, null);
if(val == null) {
if (val == null) {
errors.add(MessageFormat.format(REQD, key));
}
return val;
}
static final String REQD = "''{0}'' is a required field";
/**Get collection of values for a key. If only one val is present a
/**
* Get collection of values for a key. If only one val is present a
* single value collection is returned
*/
public List<String> getStrs(String key, List<String> def){
public List<String> getStrs(String key, List<String> def) {
Object v = null;
if(ROOT_OBJ.equals(key)) {
if (ROOT_OBJ.equals(key)) {
v = getRootPrimitive();
} else {
v = getMapVal(key);
}
if(v == null){
if (v == null) {
return def;
} else {
if (v instanceof List) {
ArrayList<String> l = new ArrayList<>();
for (Object o : (List)v) {
ArrayList<String> l = new ArrayList<>();
for (Object o : (List) v) {
l.add(String.valueOf(o));
}
if(l.isEmpty()) return def;
return l;
if (l.isEmpty()) return def;
return l;
} else {
return singletonList(String.valueOf(v));
}
@ -122,23 +128,24 @@ public class CommandOperation {
}
/**Get a required field. If missing it adds to the errors
/**
* Get a required field. If missing it adds to the errors
*/
public String getStr(String key){
if(ROOT_OBJ.equals(key)){
public String getStr(String key) {
if (ROOT_OBJ.equals(key)) {
Object obj = getRootPrimitive();
if(obj == null) {
errors.add(MessageFormat.format(REQD,name));
if (obj == null) {
errors.add(MessageFormat.format(REQD, name));
}
return obj == null ? null: String.valueOf(obj);
return obj == null ? null : String.valueOf(obj);
}
String s = getStr(key,null);
if(s==null) errors.add(MessageFormat.format(REQD, key));
String s = getStr(key, null);
if (s == null) errors.add(MessageFormat.format(REQD, key));
return s;
}
private Map errorDetails(){
private Map errorDetails() {
return makeMap(name, commandData, ERR_MSGS, errors);
}
@ -147,18 +154,19 @@ public class CommandOperation {
}
public void addError(String s) {
if(errors.contains(s)) return;
if (errors.contains(s)) return;
errors.add(s);
}
/**Get all the values from the metadata for the command
/**
* Get all the values from the metadata for the command
* without the specified keys
*/
public Map getValuesExcluding(String... keys) {
getMapVal(null);
if(hasError()) return emptyMap();//just to verify the type is Map
LinkedHashMap<String, Object> cp = new LinkedHashMap<>((Map<String,?>) commandData);
if(keys == null) return cp;
if (hasError()) return emptyMap();//just to verify the type is Map
LinkedHashMap<String, Object> cp = new LinkedHashMap<>((Map<String, ?>) commandData);
if (keys == null) return cp;
for (String key : keys) {
cp.remove(key);
}
@ -169,12 +177,14 @@ public class CommandOperation {
public List<String> getErrors() {
return errors;
}
public static final String ERR_MSGS = "errorMessages";
public static final String ROOT_OBJ = "";
public static List<Map> captureErrors(List<CommandOperation> ops){
public static List<Map> captureErrors(List<CommandOperation> ops) {
List<Map> errors = new ArrayList<>();
for (CommandOperation op : ops) {
if(op.hasError()) {
if (op.hasError()) {
errors.add(op.errorDetails());
}
}
@ -182,21 +192,22 @@ public class CommandOperation {
}
/**Parse the command operations into command objects
/**
* Parse the command operations into command objects
*/
public static List<CommandOperation> parse(Reader rdr ) throws IOException {
public static List<CommandOperation> parse(Reader rdr) throws IOException {
JSONParser parser = new JSONParser(rdr);
ObjectBuilder ob = new ObjectBuilder(parser);
if(parser.lastEvent() != JSONParser.OBJECT_START) {
if (parser.lastEvent() != JSONParser.OBJECT_START) {
throw new RuntimeException("The JSON must be an Object of the form {\"command\": {...},...");
}
List<CommandOperation> operations = new ArrayList<>();
for(;;) {
for (; ; ) {
int ev = parser.nextEvent();
if (ev==JSONParser.OBJECT_END) return operations;
Object key = ob.getKey();
if (ev == JSONParser.OBJECT_END) return operations;
Object key = ob.getKey();
ev = parser.nextEvent();
Object val = ob.getVal();
if (val instanceof List) {
@ -210,14 +221,15 @@ public class CommandOperation {
}
}
public CommandOperation getCopy(){
return new CommandOperation(name,commandData);
public CommandOperation getCopy() {
return new CommandOperation(name, commandData);
}
public Map getMap(String key, Map def) {
Object o =getMapVal(key);
if(o==null) return def;
if ( !(o instanceof Map)) {
Object o = getMapVal(key);
if (o == null) return def;
if (!(o instanceof Map)) {
addError(MessageFormat.format("''{0}'' must be a map", key));
return def;
} else {
@ -225,4 +237,14 @@ public class CommandOperation {
}
}
@Override
public String toString() {
try {
return new String(ZkStateReader.toJSON(singletonMap(name, commandData)), IOUtils.UTF_8);
} catch (UnsupportedEncodingException e) {
//should not happen
return "";
}
}
}