You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2015/02/09 00:53:25 UTC
svn commit: r1658277 [17/38] - in /lucene/dev/branches/lucene6005: ./
dev-tools/ dev-tools/idea/solr/contrib/dataimporthandler/
dev-tools/idea/solr/contrib/velocity/ dev-tools/maven/lucene/replicator/
dev-tools/maven/solr/ dev-tools/maven/solr/contrib/...
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java Sun Feb 8 23:53:14 2015
@@ -17,46 +17,187 @@
package org.apache.solr.response;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Locale;
import java.util.Properties;
+import java.util.ResourceBundle;
+import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SolrResponseBase;
+import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.util.plugin.SolrCoreAware;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.apache.velocity.tools.ConversionUtils;
import org.apache.velocity.tools.generic.ComparisonDateTool;
+import org.apache.velocity.tools.generic.ContextTool;
import org.apache.velocity.tools.generic.DisplayTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.ListTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
+import org.apache.velocity.tools.generic.ResourceTool;
import org.apache.velocity.tools.generic.SortTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class VelocityResponseWriter implements QueryResponseWriter {
+public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAware {
+ // init param names, these are _only_ loaded at init time (no per-request control of these)
+ // - multiple different named writers could be created with different init params
+ public static final String TEMPLATE_BASE_DIR = "template.base.dir";
+ public static final String PARAMS_RESOURCE_LOADER_ENABLED = "params.resource.loader.enabled";
+ public static final String SOLR_RESOURCE_LOADER_ENABLED = "solr.resource.loader.enabled";
+ public static final String PROPERTIES_FILE = "init.properties.file";
+
+ // request param names
+ public static final String TEMPLATE = "v.template";
+ public static final String LAYOUT = "v.layout";
+ public static final String LAYOUT_ENABLED = "v.layout.enabled";
+ public static final String CONTENT_TYPE = "v.contentType";
+ public static final String JSON = "v.json";
+ public static final String LOCALE = "v.locale";
+
+ public static final String TEMPLATE_EXTENSION = ".vm";
+ public static final String DEFAULT_CONTENT_TYPE = "text/html;charset=UTF-8";
+ public static final String JSON_CONTENT_TYPE = "application/json;charset=UTF-8";
+
+ private File fileResourceLoaderBaseDir;
+ private boolean paramsResourceLoaderEnabled;
+ private boolean solrResourceLoaderEnabled;
+ private String initPropertiesFileName; // used just to hold from init() to inform()
+
+ private static final Logger log = LoggerFactory.getLogger(VelocityResponseWriter.class);
+ private static final SolrVelocityLogger velocityLogger = new SolrVelocityLogger(log);
+ private Properties velocityInitProps = new Properties();
- // TODO: maybe pass this Logger to the template for logging from there?
-// private static final Logger log = LoggerFactory.getLogger(VelocityResponseWriter.class);
+ @Override
+ public void init(NamedList args) {
+ fileResourceLoaderBaseDir = null;
+ String templateBaseDir = (String) args.get(TEMPLATE_BASE_DIR);
+
+ if (templateBaseDir != null && !templateBaseDir.isEmpty()) {
+ fileResourceLoaderBaseDir = new File(templateBaseDir).getAbsoluteFile();
+ if (!fileResourceLoaderBaseDir.exists()) { // "*not* exists" condition!
+ log.warn(TEMPLATE_BASE_DIR + " specified does not exist: " + fileResourceLoaderBaseDir);
+ fileResourceLoaderBaseDir = null;
+ } else {
+ if (!fileResourceLoaderBaseDir.isDirectory()) { // "*not* a directory" condition
+ log.warn(TEMPLATE_BASE_DIR + " specified is not a directory: " + fileResourceLoaderBaseDir);
+ fileResourceLoaderBaseDir = null;
+ }
+ }
+ }
+
+ // params resource loader: off by default
+ Boolean prle = args.getBooleanArg(PARAMS_RESOURCE_LOADER_ENABLED);
+ paramsResourceLoaderEnabled = (null == prle ? false : prle);
+
+ // solr resource loader: on by default
+ Boolean srle = args.getBooleanArg(SOLR_RESOURCE_LOADER_ENABLED);
+ solrResourceLoaderEnabled = (null == srle ? true : srle);
+
+ initPropertiesFileName = (String) args.get(PROPERTIES_FILE);
+ }
+
+ @Override
+ public void inform(SolrCore core) {
+ // need to leverage SolrResourceLoader, so load init.properties.file here instead of init()
+ if (initPropertiesFileName != null) {
+ InputStream is = null;
+ try {
+ velocityInitProps.load(new InputStreamReader(core.getResourceLoader().openResource(initPropertiesFileName), StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ log.warn("Error loading " + PROPERTIES_FILE + " specified property file: " + initPropertiesFileName, e);
+ }
+ }
+ }
+
+ @Override
+ public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
+ String contentType = request.getParams().get(CONTENT_TYPE);
+
+ // Use the v.contentType specified, or either of the default content types depending on the presence of v.json
+ return (contentType != null) ? contentType : ((request.getParams().get(JSON) == null) ? DEFAULT_CONTENT_TYPE : JSON_CONTENT_TYPE);
+ }
@Override
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
- VelocityEngine engine = getEngine(request); // TODO: have HTTP headers available for configuring engine
+ VelocityEngine engine = createEngine(request); // TODO: have HTTP headers available for configuring engine
Template template = getTemplate(engine, request);
+ VelocityContext context = createContext(request, response);
+ context.put("engine", engine); // for $engine.resourceExists(...)
+
+ String layoutTemplate = request.getParams().get(LAYOUT);
+ boolean layoutEnabled = request.getParams().getBool(LAYOUT_ENABLED, true) && layoutTemplate != null;
+
+ String jsonWrapper = request.getParams().get(JSON);
+ boolean wrapResponse = layoutEnabled || jsonWrapper != null;
+
+ // create output
+ if (!wrapResponse) {
+ // straight-forward template/context merge to output
+ template.merge(context, writer);
+ }
+ else {
+ // merge to a string buffer, then wrap with layout and finally as JSON
+ StringWriter stringWriter = new StringWriter();
+ template.merge(context, stringWriter);
+
+ if (layoutEnabled) {
+ context.put("content", stringWriter.toString());
+ stringWriter = new StringWriter();
+ try {
+ engine.getTemplate(layoutTemplate + TEMPLATE_EXTENSION).merge(context, stringWriter);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ if (jsonWrapper != null) {
+ writer.write(jsonWrapper + "(");
+ writer.write(getJSONWrap(stringWriter.toString()));
+ writer.write(')');
+ } else { // using a layout, but not JSON wrapping
+ writer.write(stringWriter.toString());
+ }
+ }
+ }
+
+ private VelocityContext createContext(SolrQueryRequest request, SolrQueryResponse response) {
VelocityContext context = new VelocityContext();
context.put("request", request);
+ // Register useful Velocity "tools"
+ context.put("log", log); // TODO: add test
+ context.put("esc", new EscapeTool());
+ context.put("date", new ComparisonDateTool());
+ context.put("list", new ListTool());
+ context.put("math", new MathTool());
+ context.put("number", new NumberTool());
+ context.put("sort", new SortTool());
+ context.put("display", new DisplayTool());
+ context.put("resource", new SolrVelocityResourceTool(
+ request.getCore().getSolrConfig().getResourceLoader().getClassLoader(),
+ request.getParams().get(LOCALE)));
+
// Turn the SolrQueryResponse into a SolrResponse.
// QueryResponse has lots of conveniences suitable for a view
// Problem is, which SolrResponse class to use?
@@ -65,14 +206,15 @@ public class VelocityResponseWriter impl
// create a new instance. But for now the implementation simply
// uses QueryResponse, and if it chokes in a known way, fall back
// to bare bones SolrResponseBase.
- // TODO: Can this writer know what the handler class is? With echoHandler=true it can get its string name at least
+ // Can this writer know what the handler class is? With echoHandler=true it can get its string name at least
SolrResponse rsp = new QueryResponse();
NamedList<Object> parsedResponse = BinaryResponseWriter.getParsedResponse(request, response);
try {
rsp.setResponse(parsedResponse);
// page only injected if QueryResponse works
- context.put("page", new PageTool(request, response)); // page tool only makes sense for a SearchHandler request... *sigh*
+ context.put("page", new PageTool(request, response)); // page tool only makes sense for a SearchHandler request
+ context.put("debug",((QueryResponse)rsp).getDebugMap());
} catch (ClassCastException e) {
// known edge case where QueryResponse's extraction assumes "response" is a SolrDocumentList
// (AnalysisRequestHandler emits a "response")
@@ -81,81 +223,69 @@ public class VelocityResponseWriter impl
}
context.put("response", rsp);
- // Velocity context tools - TODO: make these pluggable
- context.put("esc", new EscapeTool());
- context.put("date", new ComparisonDateTool());
- context.put("list", new ListTool());
- context.put("math", new MathTool());
- context.put("number", new NumberTool());
- context.put("sort", new SortTool());
- context.put("display", new DisplayTool());
-
- context.put("engine", engine); // for $engine.resourceExists(...)
-
- String layout_template = request.getParams().get("v.layout");
- String json_wrapper = request.getParams().get("v.json");
- boolean wrap_response = (layout_template != null) || (json_wrapper != null);
-
- // create output, optionally wrap it into a json object
- if (wrap_response) {
- StringWriter stringWriter = new StringWriter();
- template.merge(context, stringWriter);
-
- if (layout_template != null) {
- context.put("content", stringWriter.toString());
- stringWriter = new StringWriter();
- try {
- engine.getTemplate(layout_template + ".vm").merge(context, stringWriter);
- } catch (Exception e) {
- throw new IOException(e.getMessage());
- }
- }
-
- if (json_wrapper != null) {
- writer.write(request.getParams().get("v.json") + "(");
- writer.write(getJSONWrap(stringWriter.toString()));
- writer.write(')');
- } else { // using a layout, but not JSON wrapping
- writer.write(stringWriter.toString());
- }
- } else {
- template.merge(context, writer);
- }
+ return context;
}
- private VelocityEngine getEngine(SolrQueryRequest request) {
+ private VelocityEngine createEngine(SolrQueryRequest request) {
VelocityEngine engine = new VelocityEngine();
- engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
- SolrVelocityResourceLoader resourceLoader =
- new SolrVelocityResourceLoader(request.getCore().getSolrConfig().getResourceLoader());
- engine.setProperty("solr.resource.loader.instance", resourceLoader);
- engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "params,solr");
+ // route all Velocity logging through Solr's logging facility
+ engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, velocityLogger);
- // TODO: Externalize Velocity properties
- String propFile = request.getParams().get("v.properties");
- try {
- Properties props = new Properties();
- // Don't create a separate velocity log file by default.
- props.put(RuntimeConstants.RUNTIME_LOG, "");
-
- if (propFile == null) {
- engine.init(props);
- } else {
- InputStream is = null;
- try {
- is = resourceLoader.getResourceStream(propFile);
- props.load(new InputStreamReader(is, StandardCharsets.UTF_8));
- engine.init(props);
- }
- finally {
- if (is != null) is.close();
- }
- }
+ // Set some engine properties that improve the experience
+ // - these could be considered in the future for parameterization, but can also be overridden by using
+ // the init.properties.file setting. (TODO: add a test for this properties set here overridden)
+
+ // load the built-in _macros.vm first, then load VM_global_library.vm for legacy (pre-5.0) support,
+ // and finally allow macros.vm to have the final say and override anything defined in the preceding files.
+ engine.setProperty(RuntimeConstants.VM_LIBRARY, "_macros.vm,VM_global_library.vm,macros.vm");
+
+ // Standard templates autoload, but not the macro one(s), by default, so let's just make life
+ // easier, and consistent, for macro development too.
+ engine.setProperty(RuntimeConstants.VM_LIBRARY_AUTORELOAD, "true");
+
+ /*
+ Set up Velocity resource loader(s)
+ terminology note: "resource loader" is overloaded here, there is Solr's resource loader facility for plugins,
+ and there are Velocity template resource loaders. It's confusing, they overlap: there is a Velocity resource
+ loader that loads templates from Solr's resource loader (SolrVelocityResourceLoader).
+
+ The Velocity resource loader order is [params,][file,][solr], intentionally ordered in this manner, and each
+ one optional and individually enable-able. By default, only "solr" (resource loader) is used, parsing templates
+ from a velocity/ sub-tree in either the classpath or under conf/.
+
+ A common usage would be to enable the file template loader, keeping the solr loader enabled; the Velocity resource
+ loader path would then be "file,solr" (params is disabled by default). The basic browse templates are built into
+ this plugin, but can be individually overridden by placing a same-named template in the template.base.dir specified
+ directory.
+ */
+ ArrayList<String> loaders = new ArrayList<String>();
+ if (paramsResourceLoaderEnabled) {
+ loaders.add("params");
+ engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
}
- catch (Exception e) {
- throw new RuntimeException(e);
+ if (fileResourceLoaderBaseDir != null) {
+ loaders.add("file");
+ engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, fileResourceLoaderBaseDir.getAbsolutePath());
}
+ if (solrResourceLoaderEnabled) {
+ // The solr resource loader serves templates under a velocity/ subtree from <lib>, conf/,
+ // or SolrCloud's configuration tree. Or rather the other way around, other resource loaders are rooted
+ // from the top, whereas this is velocity/ sub-tree rooted.
+ loaders.add("solr");
+ engine.setProperty("solr.resource.loader.instance", new SolrVelocityResourceLoader(request.getCore().getSolrConfig().getResourceLoader()));
+ }
+
+ // Always have the built-in classpath loader. This is needed when using VM_LIBRARY macros, as they are required
+ // to be present if specified, and we want to have a nice macros facility built-in for users to use easily, and to
+ // extend in custom ways.
+ loaders.add("builtin");
+ engine.setProperty("builtin.resource.loader.instance", new ClasspathResourceLoader());
+
+ engine.setProperty(RuntimeConstants.RESOURCE_LOADER, StringUtils.join(loaders,','));
+
+ // bring in any custom properties too
+ engine.init(velocityInitProps);
return engine;
}
@@ -163,18 +293,19 @@ public class VelocityResponseWriter impl
private Template getTemplate(VelocityEngine engine, SolrQueryRequest request) throws IOException {
Template template;
- String template_name = request.getParams().get("v.template");
- String qt = request.getParams().get("qt");
+ String templateName = request.getParams().get(TEMPLATE);
+
+ String qt = request.getParams().get(CommonParams.QT);
String path = (String) request.getContext().get("path");
- if (template_name == null && path != null) {
- template_name = path;
+ if (templateName == null && path != null) {
+ templateName = path;
} // TODO: path is never null, so qt won't get picked up maybe special case for '/select' to use qt, otherwise use path?
- if (template_name == null && qt != null) {
- template_name = qt;
+ if (templateName == null && qt != null) {
+ templateName = qt;
}
- if (template_name == null) template_name = "index";
+ if (templateName == null) templateName = "index";
try {
- template = engine.getTemplate(template_name + ".vm");
+ template = engine.getTemplate(templateName + TEMPLATE_EXTENSION);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
@@ -182,12 +313,7 @@ public class VelocityResponseWriter impl
return template;
}
- @Override
- public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
- return request.getParams().get("v.contentType", "text/html;charset=UTF-8");
- }
-
- private String getJSONWrap(String xmlResult) { // TODO: maybe noggit or Solr's JSON utilities can make this cleaner?
+ private String getJSONWrap(String xmlResult) { // maybe noggit or Solr's JSON utilities can make this cleaner?
// escape the double quotes and backslashes
String replace1 = xmlResult.replaceAll("\\\\", "\\\\\\\\");
replace1 = replace1.replaceAll("\\n", "\\\\n");
@@ -197,7 +323,34 @@ public class VelocityResponseWriter impl
return "{\"result\":\"" + replaced + "\"}";
}
- @Override
- public void init(NamedList args) {
+ // see: http://svn.apache.org/repos/asf/velocity/tools/branches/2.0.x/src/main/java/org/apache/velocity/tools/generic/ResourceTool.java
+ private class SolrVelocityResourceTool extends ResourceTool {
+
+ private final Locale locale;
+ private ClassLoader solrClassLoader;
+
+ public SolrVelocityResourceTool(ClassLoader cl, String localeString) {
+ this.solrClassLoader = cl;
+ Locale l = toLocale(localeString);
+ this.locale = (l == null ? Locale.ROOT : l);
+ }
+
+ @Override
+ protected ResourceBundle getBundle(String baseName, Object loc) {
+ // resource bundles for this tool must be in velocity "package"
+ return ResourceBundle.getBundle("velocity." + baseName, locale, solrClassLoader);
+ }
+
+ // Why did Velocity Tools make this private? Copied from ResourceTools.java
+ private Locale toLocale(Object obj) {
+ if (obj == null) {
+ return null;
+ }
+ if (obj instanceof Locale) {
+ return (Locale) obj;
+ }
+ String s = String.valueOf(obj);
+ return ConversionUtils.toLocale(s);
+ }
}
}
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/browse.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/browse.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/browse.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/browse.vm Sun Feb 8 23:53:14 2015
@@ -1,4 +1,8 @@
-#set($params = $request.params)
+#*
+ - Make search box bigger
+ - Add in pivot and other facets?
+ - Work on template default selection logic
+*#
## Show Error Message, if any
<div class="error">
@@ -7,11 +11,11 @@
<div class="query-box">
<form id="query-form" action="#{url_for_home}" method="GET">
- Find:
- <input type="text" id="q" name="q" value="$!esc.html($params.get('q'))"/>
+ $resource.find:
+ <input type="text" id="q" name="q" value="$!esc.html($request.params.get('q'))"/>
<input type="submit"/>
- #if($request.params.get('debugQuery'))
+ #if($debug) ## TODO: this would automatically happen when arbitrary parameters are kept on URLs
<input type="hidden" name="debug" value="true"/>
#end
#foreach($fq in $request.params.getParams('fq'))
@@ -19,7 +23,7 @@
#end
<div class="constraints">
- #foreach($fq in $params.getParams('fq'))
+ #foreach($fq in $request.params.getParams('fq'))
#set($previous_fq_count=$velocityCount - 1)
#if($fq != '')
>
@@ -29,7 +33,7 @@
</div>
<div class="parsed_query_header">
- #if($request.params.get('debugQuery'))
+ #if($debug)
<a href="#" onclick='jQuery(this).siblings("div").toggle(); return false;'>toggle parsed query</a>
<div class="parsed_query" style="display:none">$response.response.debug.parsedquery</div>
#end
@@ -46,11 +50,10 @@
<span>
<span class="results-found">$page.results_found</span>
results found in
- ${response.responseHeader.QTime} ms
+ ${response.responseHeader.QTime}ms
</span>
- Page <span class="page-num">$page.current_page_number</span>
- of <span class="page-count">$page.page_count</span>
+ $resource.page_of.insert($page.current_page_number,$page.page_count)
</div>
## Render Results, actual matching docs
@@ -59,13 +62,12 @@
</div>
<div class="pagination">
- #link_to_previous_page("previous")
+ #link_to_previous_page
<span class="results-found">$page.results_found</span>
results found.
- Page <span class="page-num">$page.current_page_number</span>
- of <span class="page-count">$page.page_count</span>
+ $resource.page_of.insert($page.current_page_number,$page.page_count)
- #link_to_next_page("next")
+ #link_to_next_page
</div>
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/error.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/error.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/error.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/error.vm Sun Feb 8 23:53:14 2015
@@ -1,10 +1,3 @@
-#**
- * Show Error Message, if any
- *#
-
-## Show Error Message, if any
-## Usually rendered inside div class=error
-
#if( $response.response.error.code )
<h1>ERROR $response.response.error.code</h1>
$response.response.error.msg
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/footer.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/footer.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/footer.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/footer.vm Sun Feb 8 23:53:14 2015
@@ -2,14 +2,14 @@
<div>
<span>Options:</span>
- #if($request.params.get('debugQuery'))
+ #if($debug)
<a href="#url_for_home?#q#if($list.size($request.params.getParams('fq')) > 0)&#fqs($request.params.getParams('fq'))#end">
disable debug</a>
#else
<a href="#url_for_lens&debug=true&fl=*,score">enable debug</a>
#end
-
- <a href="#url_for_lens&wt=xml#if($request.params.get('debugQuery'))&debug=true#end">XML results</a>
+ <a href="#url_for_lens&wt=xml#if($debug)&debug=true#end">XML results</a> ## TODO: Add links for other formats, maybe dynamically?
</div>
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/head.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/head.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/head.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/head.vm Sun Feb 8 23:53:14 2015
@@ -3,9 +3,12 @@
*#
<title>Solr browse: #core_name</title>
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
<link rel="icon" type="image/x-icon" href="#{url_root}/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="#{url_root}/img/favicon.ico"/>
+
<script type="text/javascript" src="#{url_root}/js/lib/jquery-1.7.2.min.js"></script>
<style>
@@ -17,17 +20,6 @@
#head{
width: 100%;
}
- .array-field {
- border: 2px solid #474747;
- background: #FFE9D8;
- padding: 5px;
- margin: 5px;
- }
-
- .array-field-list li {
- list-style: circle;
- margin-left: 20px;
- }
.parsed_query_header {
font-family: Helvetica, Arial, sans-serif;
@@ -47,7 +39,11 @@
}
a {
- color: #43a4b1;
+ color: #305CB3;
+ }
+
+ em {
+ color: #FF833D;
}
.facets {
@@ -61,7 +57,7 @@
}
.facets h2 {
- background: #EA897E;
+ background: #D9411E;
padding: 2px 5px;
}
@@ -82,18 +78,9 @@
font-weight: bold;
}
- .highlight {
- color: white;
- background-color: gray;
- border: 1px black solid;
- }
-
- .highlight-box {
- margin-left: 15px;
- }
-
.field-name {
font-weight: bold;
+ // align="right" valign="top"
}
.highlighted-facet-field {
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/hit.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/hit.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/hit.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/hit.vm Sun Feb 8 23:53:14 2015
@@ -1,24 +1,27 @@
-#set($docId = $doc.getFieldValue('id'))
+#set($docId = $doc.getFirstValue($request.schema.uniqueKeyField.name))
+
<div class="result-document">
<table>
#foreach( $fieldName in $doc.fieldNames )
- #foreach( $value in $doc.getFieldValues($fieldName) )
<tr>
- <th align="right" valign="top">
- #if( $foreach.count == 1 )
- $fieldName:
- #end
+ <th align="right" valign="top" style="field-name">
+ $esc.html($fieldName):
</th>
<td align="left" valign="top">
- $esc.html($value) <br/>
+ #field($fieldName)
</td>
</tr>
- #end
#end
</table>
+ #if($debug)
+ <a href="#" onclick='jQuery(this).siblings("pre").toggle(); return false;'>toggle explain</a>
+ <pre style="display:none">
+ $response.getExplainMap().get($docId)
+ </pre>
+ #end
</div>
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/layout.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/layout.vm?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/layout.vm (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/resources/velocity/layout.vm Sun Feb 8 23:53:14 2015
@@ -5,7 +5,7 @@
<body>
<div id="admin"><a href="#url_root/#/#core_name">Solr Admin</a></div>
<div id="head">
- <a href="#url_for_home#if($request.params.get('debugQuery'))?debugQuery=true#end"><img src="#{url_root}/img/solr.svg" id="logo"/></a>
+ <a href="#url_for_home#if($debug)?debug=true#end"><img src="#{url_root}/img/solr.svg" id="logo"/></a>
</div>
<div id="content">
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml Sun Feb 8 23:53:14 2015
@@ -16,65 +16,12 @@
limitations under the License.
-->
-<!--
- For more details about configurations options that may appear in
- this file, see http://wiki.apache.org/solr/SolrConfigXml.
--->
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
- <indexConfig>
- <useCompoundFile>${useCompoundFile:false}</useCompoundFile>
- </indexConfig>
-
- <lib dir="../../contrib/velocity/lib" />
- <lib dir="../../dist/" regex="solr-velocity-\d.*\.jar" />
- <dataDir>${solr.data.dir:}</dataDir>
-
-
- <directoryFactory name="DirectoryFactory"
- class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
-
- <updateHandler class="solr.DirectUpdateHandler2">
- </updateHandler>
-
- <query>
- <maxBooleanClauses>1024</maxBooleanClauses>
- <filterCache class="solr.FastLRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <queryResultCache class="solr.LRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <documentCache class="solr.LRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <enableLazyFieldLoading>true</enableLazyFieldLoading>
-
- <queryResultWindowSize>20</queryResultWindowSize>
- <queryResultMaxDocsCached>200</queryResultMaxDocsCached>
- <listener event="newSearcher" class="solr.QuerySenderListener">
- <arr name="queries">
- </arr>
- </listener>
- <listener event="firstSearcher" class="solr.QuerySenderListener">
- <arr name="queries">
- <lst>
- <str name="q">static firstSearcher warming in solrconfig.xml</str>
- </lst>
- </arr>
- </listener>
- <useColdSearcher>false</useColdSearcher>
- <maxWarmingSearchers>2</maxWarmingSearchers>
-
- </query>
- <requestDispatcher handleSelect="true" >
- <requestParsers enableRemoteStreaming="true"
- multipartUploadLimitInKB="2048000" />
- <httpCaching never304="true" />
- </requestDispatcher>
+
+ <!--<lib dir="../../contrib/velocity/lib" />-->
+ <!--<lib dir="../../dist/" regex="solr-velocity-\d.*\.jar" />-->
+
<requestHandler name="search" class="solr.SearchHandler" default="true">
<lst name="defaults">
@@ -83,13 +30,9 @@
</lst>
</requestHandler>
- <requestHandler name="/update" class="solr.UpdateRequestHandler" />
-
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter"/>
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
+ <queryResponseWriter name="velocityWithInitProps" class="solr.VelocityResponseWriter">
+ <str name="init.properties.file">velocity-init.properties</str>
+ </queryResponseWriter>
</config>
Modified: lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java Sun Feb 8 23:53:14 2015
@@ -18,27 +18,39 @@
package org.apache.solr.velocity;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.util.NamedList;
import org.apache.solr.response.QueryResponseWriter;
+import org.apache.solr.response.SolrParamResourceLoader;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.response.VelocityResponseWriter;
import org.apache.solr.request.SolrQueryRequest;
import org.junit.BeforeClass;
import org.junit.Test;
+import java.io.IOException;
import java.io.StringWriter;
public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml", "schema.xml", getFile("velocity/solr").getAbsolutePath());
+ System.out.println(getFile("velocity/solr").getAbsolutePath());
}
@Test
- public void testCustomParamTemplate() throws Exception {
- // This test doesn't use the Solr core, just the response writer directly
+ public void testVelocityResponseWriterRegistered() {
+ QueryResponseWriter writer = h.getCore().getQueryResponseWriter("velocity");
+ assertTrue("VrW registered check", writer instanceof VelocityResponseWriter);
+ }
+ @Test
+ public void testCustomParamTemplate() throws Exception {
org.apache.solr.response.VelocityResponseWriter vrw = new VelocityResponseWriter();
- SolrQueryRequest req = req("v.template","custom", "v.template.custom","$response.response.response_data");
+ NamedList<String> nl = new NamedList<String>();
+ nl.add(VelocityResponseWriter.PARAMS_RESOURCE_LOADER_ENABLED, "true");
+ vrw.init(nl);
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
+ SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
SolrQueryResponse rsp = new SolrQueryResponse();
StringWriter buf = new StringWriter();
rsp.add("response_data", "testing");
@@ -47,14 +59,118 @@ public class VelocityResponseWriterTest
}
@Test
- public void testVelocityResponseWriterRegistered() {
- QueryResponseWriter writer = h.getCore().getQueryResponseWriter("velocity");
+ public void testParamResourceLoaderDisabled() throws Exception {
+ VelocityResponseWriter vrw = new VelocityResponseWriter();
+ // by default param resource loader is disabled, no need to set it here
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
+ SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ StringWriter buf = new StringWriter();
+ try {
+ vrw.write(buf, req, rsp);
+ fail("Should have thrown exception due to missing template");
+ } catch (IOException e) {
+ // expected exception
+ }
+ }
- assertTrue("VrW registered check", writer instanceof VelocityResponseWriter);
+ @Test
+ public void testFileResourceLoader() throws Exception {
+ VelocityResponseWriter vrw = new VelocityResponseWriter();
+ NamedList<String> nl = new NamedList<String>();
+ nl.add("template.base.dir", getFile("velocity").getAbsolutePath());
+ vrw.init(nl);
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"file");
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ StringWriter buf = new StringWriter();
+ vrw.write(buf, req, rsp);
+ assertEquals("testing", buf.toString());
}
@Test
public void testSolrResourceLoaderTemplate() throws Exception {
- assertEquals("0", h.query(req("q","*:*", "wt","velocity","v.template","numFound")));
+ assertEquals("0", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"numFound")));
}
+
+ @Test
+ public void testMacros() throws Exception {
+ // tests that a macro in a custom macros.vm is visible
+ assertEquals("test_macro_SUCCESS", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_visible")));
+
+ // tests that a builtin (_macros.vm) macro, #url_root in this case, can be overridden in a custom macros.vm
+ // the macro is also defined in VM_global_library.vm, which should also be overridden by macros.vm
+ assertEquals("Loaded from: macros.vm", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_overridden")));
+
+ // tests that macros defined in VM_global_library.vm are visible. This file was where macros in pre-5.0 versions were defined
+ assertEquals("legacy_macro_SUCCESS", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_legacy_support")));
+ }
+
+ @Test
+ public void testInitProps() throws Exception {
+ // The test init properties file turns off being able to use $foreach.index (the implicit loop counter)
+ // The foreach.vm template uses $!foreach.index, with ! suppressing the literal "$foreach.index" output
+
+ assertEquals("01", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"foreach")));
+ assertEquals("", h.query(req("q","*:*", "wt","velocityWithInitProps",VelocityResponseWriter.TEMPLATE,"foreach")));
+ }
+
+ @Test
+ public void testLocaleFeature() throws Exception {
+ assertEquals("Color", h.query(req("q", "*:*", "wt", "velocity", VelocityResponseWriter.TEMPLATE, "locale",
+ VelocityResponseWriter.LOCALE,"en_US")));
+ assertEquals("Colour", h.query(req("q", "*:*", "wt", "velocity", VelocityResponseWriter.TEMPLATE, "locale",
+ VelocityResponseWriter.LOCALE,"en_UK")));
+ }
+
+ @Test
+ public void testLayoutFeature() throws Exception {
+ assertEquals("{{{0}}}", h.query(req("q","*:*", "wt","velocity",
+ VelocityResponseWriter.TEMPLATE,"numFound", VelocityResponseWriter.LAYOUT,"layout")));
+
+ // even with v.layout specified, layout can be disabled explicitly
+ assertEquals("0", h.query(req("q","*:*", "wt","velocity",
+ VelocityResponseWriter.TEMPLATE,"numFound",
+ VelocityResponseWriter.LAYOUT,"layout",
+ VelocityResponseWriter.LAYOUT_ENABLED,"false")));
+ }
+
+ @Test
+ public void testJSONWrapper() throws Exception {
+ assertEquals("foo({\"result\":\"0\"})", h.query(req("q", "*:*", "wt", "velocity",
+ VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON,"foo")));
+
+ // Now with layout, for good measure
+ assertEquals("foo({\"result\":\"{{{0}}}\"})", h.query(req("q", "*:*", "wt", "velocity",
+ VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON,"foo",
+ VelocityResponseWriter.LAYOUT,"layout")));
+ }
+
+ @Test
+ public void testContentType() throws Exception {
+ VelocityResponseWriter vrw = new VelocityResponseWriter();
+ NamedList<String> nl = new NamedList<String>();
+ vrw.init(nl);
+ SolrQueryResponse rsp = new SolrQueryResponse();
+
+ // with v.json=wrf, content type should default to application/json
+ assertEquals("application/json;charset=UTF-8",
+ vrw.getContentType(req(VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON, "wrf"), rsp));
+
+ // with no v.json specified, the default text/html should be returned
+ assertEquals("text/html;charset=UTF-8",
+ vrw.getContentType(req(VelocityResponseWriter.TEMPLATE, "numFound"), rsp));
+
+ // if v.contentType is specified, that should be used, even if v.json is specified
+ assertEquals("text/plain",
+ vrw.getContentType(req(VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.CONTENT_TYPE,"text/plain"), rsp));
+ assertEquals("text/plain",
+ vrw.getContentType(req(VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON,"wrf",
+ VelocityResponseWriter.CONTENT_TYPE,"text/plain"), rsp));
+ }
+
}
Modified: lucene/dev/branches/lucene6005/solr/core/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/build.xml?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/build.xml (original)
+++ lucene/dev/branches/lucene6005/solr/core/build.xml Sun Feb 8 23:53:14 2015
@@ -63,7 +63,7 @@
<target name="resolve" depends="ivy-availability-check,ivy-fail,ivy-configure">
<sequential>
<ivy:retrieve conf="compile,compile.hadoop" type="jar,bundle" sync="${ivy.sync}" log="download-only" symlink="${ivy.symlink}"/>
- <ivy:retrieve conf="test,test.DfsMiniCluster" type="jar,bundle,test" sync="${ivy.sync}" log="download-only" symlink="${ivy.symlink}"
+ <ivy:retrieve conf="test,test.DfsMiniCluster,test.MiniKdc" type="jar,bundle,test" sync="${ivy.sync}" log="download-only" symlink="${ivy.symlink}"
pattern="${test.lib.dir}/[artifact]-[revision](-[classifier]).[ext]"/>
</sequential>
</target>
Modified: lucene/dev/branches/lucene6005/solr/core/ivy.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/ivy.xml?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/ivy.xml (original)
+++ lucene/dev/branches/lucene6005/solr/core/ivy.xml Sun Feb 8 23:53:14 2015
@@ -19,13 +19,14 @@
<ivy-module version="2.0" xmlns:maven="http://ant.apache.org/ivy/maven">
<info organisation="org.apache.solr" module="core"/>
- <configurations defaultconfmapping="compile->master;compile.hadoop->master;test->master;test.DfsMiniCluster->master">
+ <configurations defaultconfmapping="compile->master;compile.hadoop->master;test->master;test.DfsMiniCluster->master;test.MiniKdc->master">
<!-- artifacts in the "compile" and "compile.hadoop" configurations will go into solr/core/lib/ -->
<conf name="compile" transitive="false"/>
<conf name="compile.hadoop" transitive="false"/>
- <!-- artifacts in the "test" and "test.DfsMiniCluster" configuration will go into solr/core/test-lib/ -->
+ <!-- artifacts in the "test", "test.DfsMiniCluster", and "test.MiniKdc" configuration will go into solr/core/test-lib/ -->
<conf name="test" transitive="false"/>
<conf name="test.DfsMiniCluster" transitive="false"/>
+ <conf name="test.MiniKdc" transitive="false"/>
</configurations>
<dependencies>
@@ -46,7 +47,6 @@
<dependency org="log4j" name="log4j" rev="${/log4j/log4j}" conf="compile"/>
<dependency org="org.slf4j" name="slf4j-log4j12" rev="${/org.slf4j/slf4j-log4j12}" conf="compile"/>
- <dependency org="javax.servlet" name="javax.servlet-api" rev="${/javax.servlet/javax.servlet-api}" conf="test"/>
<dependency org="org.easymock" name="easymock" rev="${/org.easymock/easymock}" conf="test"/>
<dependency org="cglib" name="cglib-nodep" rev="${/cglib/cglib-nodep}" conf="test"/>
<dependency org="org.objenesis" name="objenesis" rev="${/org.objenesis/objenesis}" conf="test"/>
@@ -62,6 +62,8 @@
<dependency org="org.apache.hadoop" name="hadoop-annotations" rev="${/org.apache.hadoop/hadoop-annotations}" conf="compile.hadoop"/>
<dependency org="org.apache.hadoop" name="hadoop-auth" rev="${/org.apache.hadoop/hadoop-auth}" conf="compile.hadoop"/>
<dependency org="commons-configuration" name="commons-configuration" rev="${/commons-configuration/commons-configuration}" conf="compile.hadoop"/>
+ <dependency org="commons-collections" name="commons-collections" rev="${/commons-collections/commons-collections}" conf="compile.hadoop"/>
+
<dependency org="com.google.protobuf" name="protobuf-java" rev="${/com.google.protobuf/protobuf-java}" conf="compile.hadoop"/>
<dependency org="com.googlecode.concurrentlinkedhashmap" name="concurrentlinkedhashmap-lru" rev="${/com.googlecode.concurrentlinkedhashmap/concurrentlinkedhashmap-lru}" conf="compile.hadoop"/>
@@ -75,8 +77,13 @@
<dependency org="org.mortbay.jetty" name="jetty" rev="${/org.mortbay.jetty/jetty}" conf="test.DfsMiniCluster"/>
<dependency org="org.mortbay.jetty" name="jetty-util" rev="${/org.mortbay.jetty/jetty-util}" conf="test.DfsMiniCluster"/>
<dependency org="com.sun.jersey" name="jersey-core" rev="${/com.sun.jersey/jersey-core}" conf="test.DfsMiniCluster"/>
+ <dependency org="com.sun.jersey" name="jersey-server" rev="${/com.sun.jersey/jersey-server}" conf="test.DfsMiniCluster"/>
<dependency org="commons-collections" name="commons-collections" rev="${/commons-collections/commons-collections}" conf="test.DfsMiniCluster"/>
+ <!-- Hadoop MiniKdc Dependencies-->
+ <dependency org="org.apache.hadoop" name="hadoop-minikdc" rev="${/org.apache.hadoop/hadoop-minikdc}" conf="test.MiniKdc"/>
+ <dependency org="org.apache.directory.server" name="apacheds-all" rev="${/org.apache.directory.server/apacheds-all}" conf="test.MiniKdc"/>
+
<exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
</dependencies>
</ivy-module>
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/analysis/SolrAnalyzer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/analysis/SolrAnalyzer.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/analysis/SolrAnalyzer.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/analysis/SolrAnalyzer.java Sun Feb 8 23:53:14 2015
@@ -17,10 +17,9 @@
package org.apache.solr.analysis;
-import org.apache.lucene.analysis.*;
+import org.apache.lucene.analysis.Analyzer;
import java.io.Reader;
-import java.io.IOException;
/**
*
@@ -37,14 +36,8 @@ public abstract class SolrAnalyzer exten
return posIncGap;
}
- /** wrap the reader in a CharStream, if appropriate */
- @Deprecated
- public Reader charStream(Reader reader) {
- return reader;
- }
-
@Override
protected Reader initReader(String fieldName, Reader reader) {
- return charStream(reader);
+ return reader;
}
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java Sun Feb 8 23:53:14 2015
@@ -17,6 +17,7 @@
package org.apache.solr.client.solrj.embedded;
+import com.google.common.base.Strings;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
@@ -30,7 +31,6 @@ import org.apache.solr.common.params.Sol
import org.apache.solr.common.util.JavaBinCodec;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
-import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
@@ -62,25 +62,10 @@ public class EmbeddedSolrServer extends
/**
* Use the other constructor using a CoreContainer and a name.
- * @deprecated use {@link #EmbeddedSolrServer(CoreContainer, String)} instead.
*/
- @Deprecated
public EmbeddedSolrServer(SolrCore core)
{
- if ( core == null ) {
- throw new NullPointerException("SolrCore instance required");
- }
- CoreDescriptor dcore = core.getCoreDescriptor();
- if (dcore == null)
- throw new NullPointerException("CoreDescriptor required");
-
- CoreContainer cores = dcore.getCoreContainer();
- if (cores == null)
- throw new NullPointerException("CoreContainer required");
-
- coreName = dcore.getName();
- coreContainer = cores;
- _parser = new SolrRequestParsers( null );
+ this(core.getCoreDescriptor().getCoreContainer(), core.getName());
}
/**
@@ -93,8 +78,10 @@ public class EmbeddedSolrServer extends
if ( coreContainer == null ) {
throw new NullPointerException("CoreContainer instance required");
}
+ if (Strings.isNullOrEmpty(coreName))
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Core name cannot be empty");
this.coreContainer = coreContainer;
- this.coreName = coreName == null? "" : coreName;
+ this.coreName = coreName;
_parser = new SolrRequestParsers( null );
}
@@ -129,10 +116,8 @@ public class EmbeddedSolrServer extends
}
}
// Perhaps the path is to manage the cores
- if( handler == null &&
- coreContainer != null &&
- path.equals( coreContainer.getAdminPath() ) ) {
- handler = coreContainer.getMultiCoreHandler();
+ if (handler == null) {
+ handler = coreContainer.getRequestHandler(path);
}
}
if( handler == null ) {
@@ -210,16 +195,11 @@ public class EmbeddedSolrServer extends
}
// Now write it out
- NamedList<Object> normalized = getParsedResponse(req, rsp);
+ NamedList<Object> normalized = BinaryResponseWriter.getParsedResponse(req, rsp);
return normalized;
- }
- catch( IOException iox ) {
+ } catch( IOException | SolrException iox ) {
throw iox;
- }
- catch( SolrException sx ) {
- throw sx;
- }
- catch( Exception ex ) {
+ } catch( Exception ex ) {
throw new SolrServerException( ex );
}
finally {
@@ -230,22 +210,10 @@ public class EmbeddedSolrServer extends
}
/**
- * Returns a response object equivalent to what you get from the XML/JSON/javabin parser. Documents
- * become SolrDocuments, DocList becomes SolrDocumentList etc.
- *
- * @deprecated use {@link BinaryResponseWriter#getParsedResponse(SolrQueryRequest, SolrQueryResponse)}
- */
- @Deprecated
- public NamedList<Object> getParsedResponse( SolrQueryRequest req, SolrQueryResponse rsp )
- {
- return BinaryResponseWriter.getParsedResponse(req, rsp);
- }
-
- /**
* Shutdown all cores within the EmbeddedSolrServer instance
*/
@Override
- public void shutdown() {
+ public void close() throws IOException {
coreContainer.shutdown();
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java Sun Feb 8 23:53:14 2015
@@ -19,17 +19,18 @@ package org.apache.solr.client.solrj.emb
import org.apache.solr.servlet.SolrDispatchFilter;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.LowResourceMonitor;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.bio.SocketConnector;
-import org.eclipse.jetty.server.handler.GzipHandler;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.session.HashSessionIdManager;
-import org.eclipse.jetty.server.ssl.SslConnector;
-import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
-import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -62,6 +63,9 @@ import java.util.concurrent.atomic.Atomi
* @since solr 1.3
*/
public class JettySolrRunner {
+
+ private static final AtomicLong JETTY_ID_COUNTER = new AtomicLong();
+
Server server;
FilterHolder dispatchFilter;
@@ -71,6 +75,7 @@ public class JettySolrRunner {
private String solrConfigFilename;
private String schemaFilename;
+ private final String coreRootDirectory;
private boolean waitOnSolr = false;
@@ -89,6 +94,8 @@ public class JettySolrRunner {
private String coreNodeName;
+ private final String name;
+
/** Maps servlet holders (i.e. factories: class + init params) to path specs */
private SortedMap<ServletHolder,String> extraServlets = new TreeMap<>();
private SortedMap<Class,String> extraRequestFilters;
@@ -147,12 +154,16 @@ public class JettySolrRunner {
public JettySolrRunner(String solrHome, String context, int port) {
this.init(solrHome, context, port, true);
+ this.name = "jetty-" + JETTY_ID_COUNTER.incrementAndGet();
+ this.coreRootDirectory = System.getProperty("coreRootDirectory", null);
}
public JettySolrRunner(String solrHome, String context, int port, String solrConfigFilename, String schemaFileName) {
this.init(solrHome, context, port, true);
this.solrConfigFilename = solrConfigFilename;
this.schemaFilename = schemaFileName;
+ this.name = "jetty-" + JETTY_ID_COUNTER.incrementAndGet();
+ this.coreRootDirectory = System.getProperty("coreRootDirectory", null);
}
public JettySolrRunner(String solrHome, String context, int port,
@@ -160,6 +171,8 @@ public class JettySolrRunner {
this.init(solrHome, context, port, stopAtShutdown);
this.solrConfigFilename = solrConfigFilename;
this.schemaFilename = schemaFileName;
+ this.name = "jetty-" + JETTY_ID_COUNTER.incrementAndGet();
+ this.coreRootDirectory = System.getProperty("coreRootDirectory", null);
}
/**
@@ -197,23 +210,20 @@ public class JettySolrRunner {
this.schemaFilename = schemaFileName;
this.sslConfig = sslConfig;
+ this.name = "jetty-" + JETTY_ID_COUNTER.incrementAndGet();
+ this.coreRootDirectory = System.getProperty("coreRootDirectory", null);
+
this.init(solrHome, context, port, stopAtShutdown);
}
private void init(String solrHome, String context, int port, boolean stopAtShutdown) {
this.context = context;
- server = new Server(port);
this.solrHome = solrHome;
this.stopAtShutdown = stopAtShutdown;
- server.setStopAtShutdown(stopAtShutdown);
- if (!stopAtShutdown) {
- server.setGracefulShutdown(0);
- }
+
System.setProperty("solr.solr.home", solrHome);
if (System.getProperty("jetty.testMode") != null) {
- final String connectorName = System.getProperty("tests.jettyConnector", "SelectChannel");
-
// if this property is true, then jetty will be configured to use SSL
// leveraging the same system properties as java to specify
// the keystore/truststore if they are set unless specific config
@@ -227,52 +237,56 @@ public class JettySolrRunner {
final SslContextFactory sslcontext = new SslContextFactory(false);
sslInit(useSsl, sslcontext);
- final Connector connector;
- if ("SelectChannel".equals(connectorName)) {
- final SelectChannelConnector c = useSsl
- ? new SslSelectChannelConnector(sslcontext)
- : new SelectChannelConnector();
- c.setReuseAddress(true);
- c.setLowResourcesMaxIdleTime(1500);
- c.setSoLingerTime(0);
- connector = c;
- } else if ("Socket".equals(connectorName)) {
- final SocketConnector c = useSsl
- ? new SslSocketConnector(sslcontext)
- : new SocketConnector();
- c.setReuseAddress(true);
- c.setSoLingerTime(0);
- connector = c;
+ QueuedThreadPool qtp = new QueuedThreadPool();
+ qtp.setMaxThreads(10000);
+ qtp.setIdleTimeout((int) TimeUnit.SECONDS.toMillis(5));
+ qtp.setStopTimeout((int) TimeUnit.MINUTES.toMillis(1));
+
+ server = new Server(qtp);
+ server.setStopAtShutdown(stopAtShutdown);
+ server.manage(qtp);
+
+ ServerConnector connector;
+ if (useSsl) {
+ HttpConfiguration configuration = new HttpConfiguration();
+ configuration.setSecureScheme("https");
+ configuration.addCustomizer(new SecureRequestCustomizer());
+ connector = new ServerConnector(server, new SslConnectionFactory(sslcontext, "http/1.1"),
+ new HttpConnectionFactory(configuration));
} else {
- throw new IllegalArgumentException("Illegal value for system property 'tests.jettyConnector': " + connectorName);
+ connector = new ServerConnector(server, new HttpConnectionFactory());
}
+ connector.setReuseAddress(true);
+ connector.setSoLingerTime(0);
connector.setPort(port);
connector.setHost("127.0.0.1");
- // Connectors by default inherit server's thread pool.
- QueuedThreadPool qtp = new QueuedThreadPool();
- qtp.setMaxThreads(10000);
- qtp.setMaxIdleTimeMs((int) TimeUnit.MILLISECONDS.toMillis(200));
- qtp.setMaxStopTimeMs((int) TimeUnit.MINUTES.toMillis(1));
- server.setThreadPool(qtp);
+ // Enable Low Resources Management
+ LowResourceMonitor lowResources = new LowResourceMonitor(server);
+ lowResources.setLowResourcesIdleTimeout(1500);
+ lowResources.setMaxConnections(10000);
+ server.addBean(lowResources);
server.setConnectors(new Connector[] {connector});
server.setSessionIdManager(new HashSessionIdManager(new Random()));
} else {
- if (server.getThreadPool() == null) {
- // Connectors by default inherit server's thread pool.
- QueuedThreadPool qtp = new QueuedThreadPool();
- qtp.setMaxThreads(10000);
- qtp.setMaxIdleTimeMs((int) TimeUnit.SECONDS.toMillis(5));
- qtp.setMaxStopTimeMs((int) TimeUnit.SECONDS.toMillis(1));
- server.setThreadPool(qtp);
- }
+ ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory());
+ connector.setPort(port);
+
+ QueuedThreadPool qtp = new QueuedThreadPool();
+ qtp.setMaxThreads(10000);
+ qtp.setIdleTimeout((int) TimeUnit.SECONDS.toMillis(5));
+ qtp.setStopTimeout((int) TimeUnit.SECONDS.toMillis(1));
+
+ server = new Server(qtp);
+ server.setStopAtShutdown(stopAtShutdown);
+ server.manage(qtp);
}
// Initialize the servlets
- final ServletContextHandler root = new ServletContextHandler(server,context,ServletContextHandler.SESSIONS);
- root.setHandler(new GzipHandler());
+ final ServletContextHandler root = new ServletContextHandler(server, context, ServletContextHandler.SESSIONS);
+ root.addFilter(GzipFilter.class, "*", EnumSet.of(DispatcherType.REQUEST));
server.addLifeCycleListener(new LifeCycle.Listener() {
@Override
@@ -299,6 +313,8 @@ public class JettySolrRunner {
solrConfigFilename);
if (schemaFilename != null) System.setProperty("schema",
schemaFilename);
+ if (coreRootDirectory != null)
+ System.setProperty("coreRootDirectory", coreRootDirectory);
// SolrDispatchFilter filter = new SolrDispatchFilter();
// FilterHolder fh = new FilterHolder(filter);
debugFilter = root.addFilter(DebugFilter.class, "*", EnumSet.of(DispatcherType.REQUEST) );
@@ -309,11 +325,11 @@ public class JettySolrRunner {
EnumSet.of(DispatcherType.REQUEST)));
}
}
- dispatchFilter = root.addFilter(SolrDispatchFilter.class, "*", EnumSet.of(DispatcherType.REQUEST) );
for (ServletHolder servletHolder : extraServlets.keySet()) {
String pathSpec = extraServlets.get(servletHolder);
root.addServlet(servletHolder, pathSpec);
}
+ dispatchFilter = root.addFilter(SolrDispatchFilter.class, "*", EnumSet.of(DispatcherType.REQUEST) );
if (solrConfigFilename != null) System.clearProperty("solrconfig");
if (schemaFilename != null) System.clearProperty("schema");
System.clearProperty("solr.solr.home");
@@ -339,7 +355,7 @@ public class JettySolrRunner {
sslcontext.setKeyStorePassword(sslConfig.getKeyStorePassword());
}
if (null != sslConfig.getTrustStore()) {
- sslcontext.setTrustStore(System
+ sslcontext.setTrustStorePath(System
.getProperty(sslConfig.getTrustStore()));
}
if (null != sslConfig.getTrustStorePassword()) {
@@ -359,7 +375,7 @@ public class JettySolrRunner {
(System.getProperty("javax.net.ssl.keyStorePassword"));
}
if (null != System.getProperty("javax.net.ssl.trustStore")) {
- sslcontext.setTrustStore
+ sslcontext.setTrustStorePath
(System.getProperty("javax.net.ssl.trustStore"));
}
if (null != System.getProperty("javax.net.ssl.trustStorePassword")) {
@@ -464,7 +480,7 @@ public class JettySolrRunner {
if (0 == conns.length) {
throw new RuntimeException("Jetty Server has no Connectors");
}
- return (proxyPort != -1) ? proxyPort : conns[0].getLocalPort();
+ return (proxyPort != -1) ? proxyPort : ((ServerConnector) conns[0]).getLocalPort();
}
/**
@@ -489,7 +505,7 @@ public class JettySolrRunner {
}
/**
- * Returns a base URL consisting of the protocal, host, and port for a
+ * Returns a base URL consisting of the protocol, host, and port for a
* Connector in use by the Jetty Server contained in this runner.
*/
public URL getBaseUrl() {
@@ -499,12 +515,12 @@ public class JettySolrRunner {
if (0 == conns.length) {
throw new IllegalStateException("Jetty Server has no Connectors");
}
- Connector c = conns[0];
+ ServerConnector c = (ServerConnector) conns[0];
if (c.getLocalPort() < 0) {
throw new IllegalStateException("Jetty Connector is not open: " +
c.getLocalPort());
}
- protocol = (c instanceof SslConnector) ? "https" : "http";
+ protocol = c.getDefaultProtocol().equals("SSL-http/1.1") ? "https" : "http";
return new URL(protocol, c.getHost(), c.getLocalPort(), context);
} catch (MalformedURLException e) {
@@ -615,6 +631,11 @@ class NoLog implements Logger {
}
@Override
+ public void debug(String s, long l) {
+
+ }
+
+ @Override
public String getName() {
return toString();
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java Sun Feb 8 23:53:14 2015
@@ -17,6 +17,7 @@ package org.apache.solr.cloud;
* limitations under the License.
*/
+import com.google.common.base.Strings;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.SolrParams;
@@ -49,10 +50,14 @@ public class CloudDescriptor {
public CloudDescriptor(String coreName, Properties props, CoreDescriptor cd) {
this.cd = cd;
this.shardId = props.getProperty(CoreDescriptor.CORE_SHARD, null);
+ if (Strings.isNullOrEmpty(shardId))
+ this.shardId = null;
// If no collection name is specified, we default to the core name
this.collectionName = props.getProperty(CoreDescriptor.CORE_COLLECTION, coreName);
this.roles = props.getProperty(CoreDescriptor.CORE_ROLES, null);
this.nodeName = props.getProperty(CoreDescriptor.CORE_NODE_NAME);
+ if (Strings.isNullOrEmpty(nodeName))
+ this.nodeName = null;
this.numShards = PropertiesUtil.toInteger(props.getProperty(CloudDescriptor.NUM_SHARDS), null);
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java Sun Feb 8 23:53:14 2015
@@ -122,10 +122,13 @@ public class DistributedQueue {
for (String childName : childNames) {
if (childName != null) {
try {
- ZkNodeProps message = ZkNodeProps.load(zookeeper.getData(dir + "/" + childName, null, null, true));
- if (message.containsKey(OverseerCollectionProcessor.ASYNC)) {
- LOG.info(">>>> {}", message.get(OverseerCollectionProcessor.ASYNC));
- if(message.get(OverseerCollectionProcessor.ASYNC).equals(requestId)) return true;
+ byte[] data = zookeeper.getData(dir + "/" + childName, null, null, true);
+ if (data != null) {
+ ZkNodeProps message = ZkNodeProps.load(data);
+ if (message.containsKey(OverseerCollectionProcessor.ASYNC)) {
+ LOG.debug(">>>> {}", message.get(OverseerCollectionProcessor.ASYNC));
+ if(message.get(OverseerCollectionProcessor.ASYNC).equals(requestId)) return true;
+ }
}
} catch (KeeperException.NoNodeException e) {
// Another client removed the node first, try next
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java Sun Feb 8 23:53:14 2015
@@ -113,9 +113,8 @@ public class LeaderInitiatedRecoveryThre
} else {
log.info("Asking core={} coreNodeName={} on " + recoveryUrl + " to recover", coreNeedingRecovery, replicaCoreNodeName);
}
-
- HttpSolrClient client = new HttpSolrClient(recoveryUrl);
- try {
+
+ try (HttpSolrClient client = new HttpSolrClient(recoveryUrl)) {
client.setSoTimeout(60000);
client.setConnectionTimeout(15000);
try {
@@ -139,8 +138,6 @@ public class LeaderInitiatedRecoveryThre
continueTrying = false;
}
}
- } finally {
- client.shutdown();
}
// wait a few seconds
@@ -193,7 +190,7 @@ public class LeaderInitiatedRecoveryThre
// additional safeguard against the replica trying to be in the active state
// before acknowledging the leader initiated recovery command
- if (continueTrying && collection != null && shardId != null) {
+ if (collection != null && shardId != null) {
try {
// call out to ZooKeeper to get the leader-initiated recovery state
String lirState =
@@ -218,20 +215,25 @@ public class LeaderInitiatedRecoveryThre
List<ZkCoreNodeProps> replicaProps =
zkStateReader.getReplicaProps(collection, shardId, leaderCoreNodeName);
if (replicaProps != null && replicaProps.size() > 0) {
- String replicaState = replicaProps.get(0).getState();
- if (ZkStateReader.ACTIVE.equals(replicaState)) {
- // replica published its state as "active",
- // which is bad if lirState is still "down"
- if (ZkStateReader.DOWN.equals(lirState)) {
- // OK, so the replica thinks it is active, but it never ack'd the leader initiated recovery
- // so its state cannot be trusted and it needs to be told to recover again ... and we keep looping here
- log.warn("Replica core={} coreNodeName={} set to active but the leader thinks it should be in recovery;"
- + " forcing it back to down state to re-run the leader-initiated recovery process; props: "+replicaProps.get(0), coreNeedingRecovery, replicaCoreNodeName);
- zkController.ensureReplicaInLeaderInitiatedRecovery(collection,
- shardId, replicaUrl, nodeProps, true); // force republish state to "down"
+ for (ZkCoreNodeProps prop : replicaProps) {
+ if (replicaCoreNodeName.equals(((Replica) prop.getNodeProps()).getName())) {
+ String replicaState = prop.getState();
+ if (ZkStateReader.ACTIVE.equals(replicaState)) {
+ // replica published its state as "active",
+ // which is bad if lirState is still "down"
+ if (ZkStateReader.DOWN.equals(lirState)) {
+ // OK, so the replica thinks it is active, but it never ack'd the leader initiated recovery
+ // so its state cannot be trusted and it needs to be told to recover again ... and we keep looping here
+ log.warn("Replica core={} coreNodeName={} set to active but the leader thinks it should be in recovery;"
+ + " forcing it back to down state to re-run the leader-initiated recovery process; props: "+replicaProps.get(0), coreNeedingRecovery, replicaCoreNodeName);
+ zkController.ensureReplicaInLeaderInitiatedRecovery(collection,
+ shardId, replicaUrl, nodeProps, true); // force republish state to "down"
+ }
+ }
+ break;
}
- }
- }
+ }
+ }
}
} catch (Exception ignoreMe) {
log.warn("Failed to determine state of core={} coreNodeName={} due to: "+ignoreMe, coreNeedingRecovery, replicaCoreNodeName);
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/Overseer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/Overseer.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/Overseer.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/Overseer.java Sun Feb 8 23:53:14 2015
@@ -58,7 +58,7 @@ import org.apache.solr.common.params.Col
import org.apache.solr.core.ConfigSolr;
import org.apache.solr.handler.component.ShardHandler;
import org.apache.solr.update.UpdateShardHandler;
-import org.apache.solr.util.IOUtils;
+import org.apache.solr.common.util.IOUtils;
import org.apache.solr.util.stats.Clock;
import org.apache.solr.util.stats.Timer;
import org.apache.solr.util.stats.TimerContext;
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java Sun Feb 8 23:53:14 2015
@@ -17,19 +17,8 @@ package org.apache.solr.cloud;
* limitations under the License.
*/
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest.Create;
import org.apache.solr.common.SolrException;
@@ -44,8 +33,19 @@ import org.apache.solr.update.UpdateShar
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
// TODO: how to tmp exclude nodes?
@@ -85,6 +85,7 @@ public class OverseerAutoReplicaFailover
private volatile boolean isClosed;
private ZkStateReader zkStateReader;
private final Cache<String,Long> baseUrlForBadNodes;
+ private Set<String> liveNodes = Collections.EMPTY_SET;
private final int workLoopDelay;
private final int waitAfterExpiration;
@@ -151,11 +152,13 @@ public class OverseerAutoReplicaFailover
return;
}
if (clusterState != null) {
- if (lastClusterStateVersion == clusterState.getZkClusterStateVersion() && baseUrlForBadNodes.size() == 0) {
+ if (lastClusterStateVersion == clusterState.getZkClusterStateVersion() && baseUrlForBadNodes.size() == 0 &&
+ liveNodes.equals(clusterState.getLiveNodes())) {
// nothing has changed, no work to do
return;
}
-
+
+ liveNodes = clusterState.getLiveNodes();
lastClusterStateVersion = clusterState.getZkClusterStateVersion();
Set<String> collections = clusterState.getCollections();
for (final String collection : collections) {
@@ -418,12 +421,11 @@ public class OverseerAutoReplicaFailover
private boolean createSolrCore(final String collection,
final String createUrl, final String dataDir, final String ulogDir,
final String coreNodeName, final String coreName) {
- HttpSolrClient server = null;
- try {
+
+ try (HttpSolrClient client = new HttpSolrClient(createUrl)) {
log.debug("create url={}", createUrl);
- server = new HttpSolrClient(createUrl);
- server.setConnectionTimeout(30000);
- server.setSoTimeout(60000);
+ client.setConnectionTimeout(30000);
+ client.setSoTimeout(60000);
Create createCmd = new Create();
createCmd.setCollection(collection);
createCmd.setCoreNodeName(coreNodeName);
@@ -432,14 +434,10 @@ public class OverseerAutoReplicaFailover
createCmd.setCoreName(coreName);
createCmd.setDataDir(dataDir);
createCmd.setUlogDir(ulogDir);
- server.request(createCmd);
+ client.request(createCmd);
} catch (Exception e) {
SolrException.log(log, "Exception trying to create new replica on " + createUrl, e);
return false;
- } finally {
- if (server != null) {
- server.shutdown();
- }
}
return true;
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java Sun Feb 8 23:53:14 2015
@@ -1161,7 +1161,7 @@ public class OverseerCollectionProcessor
private void deleteCollection(ZkNodeProps message, NamedList results)
throws KeeperException, InterruptedException {
- String collection = message.getStr("name");
+ final String collection = message.getStr("name");
try {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(CoreAdminParams.ACTION, CoreAdminAction.UNLOAD.toString());
@@ -1181,7 +1181,7 @@ public class OverseerCollectionProcessor
boolean removed = false;
while (System.nanoTime() < timeout) {
Thread.sleep(100);
- removed = !zkStateReader.getClusterState().hasCollection(message.getStr(collection));
+ removed = !zkStateReader.getClusterState().hasCollection(collection);
if (removed) {
Thread.sleep(500); // just a bit of time so it's more likely other
// readers see on return
@@ -1190,7 +1190,7 @@ public class OverseerCollectionProcessor
}
if (!removed) {
throw new SolrException(ErrorCode.SERVER_ERROR,
- "Could not fully remove collection: " + message.getStr("name"));
+ "Could not fully remove collection: " + collection);
}
} finally {
@@ -1801,19 +1801,14 @@ public class OverseerCollectionProcessor
static UpdateResponse softCommit(String url) throws SolrServerException, IOException {
- HttpSolrClient client = null;
- try {
- client = new HttpSolrClient(url);
+
+ try (HttpSolrClient client = new HttpSolrClient(url)) {
client.setConnectionTimeout(30000);
client.setSoTimeout(120000);
UpdateRequest ureq = new UpdateRequest();
ureq.setParams(new ModifiableSolrParams());
ureq.setAction(AbstractUpdateRequest.ACTION.COMMIT, false, true, true);
return ureq.process(client);
- } finally {
- if (client != null) {
- client.shutdown();
- }
}
}
@@ -2318,6 +2313,13 @@ public class OverseerCollectionProcessor
if (clusterState.hasCollection(collectionName)) {
throw new SolrException(ErrorCode.BAD_REQUEST, "collection already exists: " + collectionName);
}
+
+ String configName = getConfigName(collectionName, message);
+ if (configName == null) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, "No config set found to associate with the collection.");
+ } else if (!validateConfig(configName)) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, "Can not find the specified config set: " + configName);
+ }
try {
// look at the replication factor and see if it matches reality
@@ -2385,7 +2387,7 @@ public class OverseerCollectionProcessor
}
boolean isLegacyCloud = Overseer.isLegacy(zkStateReader.getClusterProps());
- String configName = createConfNode(collectionName, message, isLegacyCloud);
+ createConfNode(configName, collectionName, isLegacyCloud);
Overseer.getInQueue(zkStateReader.getZkClient()).offer(ZkStateReader.toJSON(message));
@@ -2621,24 +2623,38 @@ public class OverseerCollectionProcessor
} while (srsp != null);
}
- private String createConfNode(String coll, ZkNodeProps message, boolean isLegacyCloud) throws KeeperException, InterruptedException {
+ private String getConfigName(String coll, ZkNodeProps message) throws KeeperException, InterruptedException {
String configName = message.getStr(OverseerCollectionProcessor.COLL_CONF);
- if(configName == null){
+
+ if (configName == null) {
// if there is only one conf, use that
- List<String> configNames=null;
+ List<String> configNames = null;
try {
configNames = zkStateReader.getZkClient().getChildren(ZkController.CONFIGS_ZKNODE, null, true);
if (configNames != null && configNames.size() == 1) {
configName = configNames.get(0);
// no config set named, but there is only 1 - use it
log.info("Only one config set found in zk - using it:" + configName);
+ } else if (configNames.contains(coll)) {
+ configName = coll;
}
} catch (KeeperException.NoNodeException e) {
}
-
}
+ return configName;
+ }
+
+ private boolean validateConfig(String configName) throws KeeperException, InterruptedException {
+ return zkStateReader.getZkClient().exists(ZkController.CONFIGS_ZKNODE + "/" + configName, true);
+ }
+ /**
+ * This doesn't validate the config (path) itself and is just responsible for creating the confNode.
+ * That check should be done before the config node is created.
+ */
+ private void createConfNode(String configName, String coll, boolean isLegacyCloud) throws KeeperException, InterruptedException {
+
if (configName != null) {
String collDir = ZkStateReader.COLLECTIONS_ZKNODE + "/" + coll;
log.info("creating collections conf node {} ", collDir);
@@ -2655,7 +2671,6 @@ public class OverseerCollectionProcessor
throw new SolrException(ErrorCode.BAD_REQUEST,"Unable to get config name");
}
}
- return configName;
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java Sun Feb 8 23:53:14 2015
@@ -200,17 +200,14 @@ public class RecoveryStrategy extends Th
private void commitOnLeader(String leaderUrl) throws SolrServerException,
IOException {
- HttpSolrClient server = new HttpSolrClient(leaderUrl);
- try {
- server.setConnectionTimeout(30000);
+ try (HttpSolrClient client = new HttpSolrClient(leaderUrl)) {
+ client.setConnectionTimeout(30000);
UpdateRequest ureq = new UpdateRequest();
ureq.setParams(new ModifiableSolrParams());
ureq.getParams().set(DistributedUpdateProcessor.COMMIT_END_POINT, true);
ureq.getParams().set(UpdateParams.OPEN_SEARCHER, false);
ureq.setAction(AbstractUpdateRequest.ACTION.COMMIT, false, true).process(
- server);
- } finally {
- server.shutdown();
+ client);
}
}
@@ -594,9 +591,9 @@ public class RecoveryStrategy extends Th
private void sendPrepRecoveryCmd(String leaderBaseUrl, String leaderCoreName, Slice slice)
throws SolrServerException, IOException, InterruptedException, ExecutionException {
- HttpSolrClient server = new HttpSolrClient(leaderBaseUrl);
- try {
- server.setConnectionTimeout(30000);
+
+ try (HttpSolrClient client = new HttpSolrClient(leaderBaseUrl)) {
+ client.setConnectionTimeout(30000);
WaitForState prepCmd = new WaitForState();
prepCmd.setCoreName(leaderCoreName);
prepCmd.setNodeName(zkController.getNodeName());
@@ -607,14 +604,12 @@ public class RecoveryStrategy extends Th
if (!Slice.CONSTRUCTION.equals(slice.getState()) && !Slice.RECOVERY.equals(slice.getState())) {
prepCmd.setOnlyIfLeaderActive(true);
}
- HttpUriRequestResponse mrr = server.httpUriRequest(prepCmd);
+ HttpUriRequestResponse mrr = client.httpUriRequest(prepCmd);
prevSendPreRecoveryHttpUriRequest = mrr.httpUriRequest;
log.info("Sending prep recovery command to {}; {}", leaderBaseUrl, prepCmd.toString());
mrr.future.get();
- } finally {
- server.shutdown();
}
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java Sun Feb 8 23:53:14 2015
@@ -91,12 +91,9 @@ public class SolrZkServer {
if (zkProps.getClientPortAddress() == null) {
zkProps.setClientPort(Integer.parseInt(solrPort)+1000);
}
- } catch (QuorumPeerConfig.ConfigException e) {
+ } catch (QuorumPeerConfig.ConfigException | IOException e) {
if (zkRun != null)
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
- } catch (IOException e) {
- if (zkRun != null)
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
}
}
@@ -186,9 +183,7 @@ class SolrZkServerProps extends QuorumPe
return cfg;
- } catch (IOException e) {
- throw new ConfigException("Error processing " + path, e);
- } catch (IllegalArgumentException e) {
+ } catch (IOException | IllegalArgumentException e) {
throw new ConfigException("Error processing " + path, e);
}
}
Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java?rev=1658277&r1=1658276&r2=1658277&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java Sun Feb 8 23:53:14 2015
@@ -267,8 +267,8 @@ public class SyncStrategy {
recoverRequestCmd.setAction(CoreAdminAction.REQUESTRECOVERY);
recoverRequestCmd.setCoreName(coreName);
- HttpSolrClient client = new HttpSolrClient(baseUrl, SyncStrategy.this.client);
- try {
+ ;
+ try (HttpSolrClient client = new HttpSolrClient(baseUrl, SyncStrategy.this.client)) {
client.setConnectionTimeout(30000);
client.setSoTimeout(120000);
client.request(recoverRequestCmd);
@@ -277,8 +277,6 @@ public class SyncStrategy {
if (t instanceof Error) {
throw (Error) t;
}
- } finally {
- client.shutdown();
}
}
};