From 648eebbe922ba376598b8639ddcebfa11d57f293 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Wed, 11 Feb 2015 10:40:03 +0000 Subject: [PATCH] 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 --- .../org/apache/solr/cloud/ZkController.java | 31 +-- .../solr/handler/SolrConfigHandler.java | 214 +++++++++--------- .../apache/solr/util/CommandOperation.java | 116 ++++++---- 3 files changed, 194 insertions(+), 167 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 96661d292bc..be94f644486 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -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 diff --git a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java index 094deff531b..79f776187ac 100644 --- a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java @@ -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 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 getConfigDetails() { Map 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 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 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 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 ops, RequestParams params) { for (CommandOperation op : ops) { switch (op.name) { @@ -215,7 +215,7 @@ public class SolrConfigHandler extends RequestHandlerBase { for (Map.Entry 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 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 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 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 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 m = op.getDataMap(); - if(op.hasError()) return overlay; + if (op.hasError()) return overlay; for (Map.Entry 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 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 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 m = op.getDataMap(); - if(op.hasError()) return overlay; + if (op.hasError()) return overlay; for (Map.Entry 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= '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 map = new HashMap<>(1); + if (params.get(CommonParams.WT) != null) return;//wt is set by user + Map 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 subPaths = new HashSet<>(Arrays.asList("/overlay", "/params", - "/query","/jmx","/requestDispatcher")); + private static Set 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 cmdPrefixes = ImmutableSet.of(CREATE , UPDATE, "delete"); + private static Set cmdPrefixes = ImmutableSet.of(CREATE, UPDATE, "delete"); } diff --git a/solr/core/src/java/org/apache/solr/util/CommandOperation.java b/solr/core/src/java/org/apache/solr/util/CommandOperation.java index 89fdb37bcf4..64f914d02e8 100644 --- a/solr/core/src/java/org/apache/solr/util/CommandOperation.java +++ b/solr/core/src/java/org/apache/solr/util/CommandOperation.java @@ -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 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 getDataMap(){ + public Map 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 getStrs(String key){ + public List getStrs(String key) { List 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 getStrs(String key, List def){ + public List getStrs(String key, List 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 l = new ArrayList<>(); - for (Object o : (List)v) { + ArrayList 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 cp = new LinkedHashMap<>((Map) commandData); - if(keys == null) return cp; + if (hasError()) return emptyMap();//just to verify the type is Map + LinkedHashMap cp = new LinkedHashMap<>((Map) commandData); + if (keys == null) return cp; for (String key : keys) { cp.remove(key); } @@ -169,12 +177,14 @@ public class CommandOperation { public List getErrors() { return errors; } + public static final String ERR_MSGS = "errorMessages"; public static final String ROOT_OBJ = ""; - public static List captureErrors(List ops){ + + public static List captureErrors(List ops) { List 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 parse(Reader rdr ) throws IOException { + public static List 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 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 ""; + } + } }