You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2015/03/09 17:29:09 UTC
svn commit: r1665295 [2/3] - in /lucene/dev/branches/branch_5x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/cloud/
solr/core/src/java/org/apache/solr/core/
solr/core/src/java/org/apache/solr/handler/
solr/core/src/java/org/apache/solr/handle...
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrCore.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrCore.java Mon Mar 9 16:29:08 2015
@@ -17,6 +17,7 @@
package org.apache.solr.core;
+import javax.xml.parsers.ParserConfigurationException;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
@@ -24,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.Writer;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@@ -56,9 +56,8 @@ import java.util.concurrent.atomic.Atomi
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
-import javax.xml.parsers.ParserConfigurationException;
-
import org.apache.commons.io.FileUtils;
+import org.apache.lucene.analysis.util.ResourceLoader;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexDeletionPolicy;
@@ -87,15 +86,8 @@ import org.apache.solr.handler.IndexFetc
import org.apache.solr.handler.ReplicationHandler;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.admin.ShowFileRequestHandler;
-import org.apache.solr.handler.component.DebugComponent;
-import org.apache.solr.handler.component.ExpandComponent;
-import org.apache.solr.handler.component.FacetComponent;
import org.apache.solr.handler.component.HighlightComponent;
-import org.apache.solr.handler.component.MoreLikeThisComponent;
-import org.apache.solr.handler.component.QueryComponent;
-import org.apache.solr.handler.component.RealTimeGetComponent;
import org.apache.solr.handler.component.SearchComponent;
-import org.apache.solr.handler.component.StatsComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.BinaryResponseWriter;
@@ -154,14 +146,14 @@ import org.xml.sax.SAXException;
*
*/
public final class SolrCore implements SolrInfoMBean, Closeable {
- public static final String version="1.0";
+ public static final String version="1.0";
// These should *only* be used for debugging or monitoring purposes
public static final AtomicLong numOpens = new AtomicLong();
public static final AtomicLong numCloses = new AtomicLong();
public static Map<SolrCore,Exception> openHandles = Collections.synchronizedMap(new IdentityHashMap<SolrCore, Exception>());
-
+
public static final Logger log = LoggerFactory.getLogger(SolrCore.class);
public static final Logger requestLog = LoggerFactory.getLogger(SolrCore.class.getName() + ".Request");
@@ -180,29 +172,30 @@ public final class SolrCore implements S
private final String ulogDir;
private final UpdateHandler updateHandler;
private final SolrCoreState solrCoreState;
-
+
private final long startTime;
private final RequestHandlers reqHandlers;
- private final Map<String,SearchComponent> searchComponents;
+ private final PluginBag<SearchComponent> searchComponents = new PluginBag<>(SearchComponent.class, this);
private final Map<String,UpdateRequestProcessorChain> updateProcessorChains;
private final Map<String, SolrInfoMBean> infoRegistry;
private IndexDeletionPolicyWrapper solrDelPolicy;
private DirectoryFactory directoryFactory;
private IndexReaderFactory indexReaderFactory;
private final Codec codec;
+ private final MemClassLoader memClassLoader;
private final List<Runnable> confListeners = new CopyOnWriteArrayList<>();
-
+
private final ReentrantLock ruleExpiryLock;
-
+
public long getStartTime() { return startTime; }
-
+
private RestManager restManager;
-
+
public RestManager getRestManager() {
return restManager;
}
-
+
static int boolean_query_max_clause_count = Integer.MIN_VALUE;
// only change the BooleanQuery maxClauseCount once for ALL cores...
void booleanQueryMaxClauseCount() {
@@ -215,7 +208,7 @@ public final class SolrCore implements S
}
}
}
-
+
/**
* The SolrResourceLoader used to load all resources for this core.
* @since solr 1.3
@@ -238,7 +231,7 @@ public final class SolrCore implements S
public SolrConfig getSolrConfig() {
return solrConfig;
}
-
+
/**
* Gets the schema resource name used by this core instance.
* @since solr 1.3
@@ -248,15 +241,15 @@ public final class SolrCore implements S
}
/** @return the latest snapshot of the schema used by this core instance. */
- public IndexSchema getLatestSchema() {
+ public IndexSchema getLatestSchema() {
return schema;
}
-
+
/** Sets the latest schema snapshot to be used by this core instance. */
public void setLatestSchema(IndexSchema replacementSchema) {
schema = replacementSchema;
}
-
+
public String getDataDir() {
return dataDir;
}
@@ -300,12 +293,12 @@ public final class SolrCore implements S
final InputStream is = new PropertiesInputStream(input);
try {
p.load(new InputStreamReader(is, StandardCharsets.UTF_8));
-
+
String s = p.getProperty("index");
if (s != null && s.trim().length() > 0) {
result = dataDir + s;
}
-
+
} catch (Exception e) {
log.error("Unable to load " + IndexFetcher.INDEX_PROPERTIES, e);
} finally {
@@ -331,15 +324,15 @@ public final class SolrCore implements S
}
private String lastNewIndexDir; // for debugging purposes only... access not synchronized, but that's ok
-
+
public DirectoryFactory getDirectoryFactory() {
return directoryFactory;
}
-
+
public IndexReaderFactory getIndexReaderFactory() {
return indexReaderFactory;
}
-
+
@Override
public String getName() {
return name;
@@ -372,13 +365,13 @@ public final class SolrCore implements S
PluginInfo info = solrConfig.getPluginInfo(IndexDeletionPolicy.class.getName());
IndexDeletionPolicy delPolicy = null;
if(info != null){
- delPolicy = createInstance(info.className,IndexDeletionPolicy.class,"Deletion Policy for SOLR");
+ delPolicy = createInstance(info.className, IndexDeletionPolicy.class, "Deletion Policy for SOLR", this, getResourceLoader());
if (delPolicy instanceof NamedListInitializedPlugin) {
((NamedListInitializedPlugin) delPolicy).init(info.initArgs);
}
} else {
delPolicy = new SolrDeletionPolicy();
- }
+ }
solrDelPolicy = new IndexDeletionPolicyWrapper(delPolicy);
}
@@ -406,7 +399,7 @@ public final class SolrCore implements S
* NOTE: this function is not thread safe. However, it is safe to call within the
* <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
* Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
- *
+ *
* @see SolrCoreAware
*/
public void registerFirstSearcherListener( SolrEventListener listener )
@@ -418,7 +411,7 @@ public final class SolrCore implements S
* NOTE: this function is not thread safe. However, it is safe to call within the
* <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
* Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
- *
+ *
* @see SolrCoreAware
*/
public void registerNewSearcherListener( SolrEventListener listener )
@@ -430,7 +423,7 @@ public final class SolrCore implements S
* NOTE: this function is not thread safe. However, it is safe to call within the
* <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
* Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
- *
+ *
* @see SolrCoreAware
*/
public QueryResponseWriter registerResponseWriter( String name, QueryResponseWriter responseWriter ){
@@ -439,7 +432,7 @@ public final class SolrCore implements S
public SolrCore reload(ConfigSet coreConfig) throws IOException,
ParserConfigurationException, SAXException {
-
+
solrCoreState.increfSolrCoreState();
SolrCore currentCore;
boolean indexDirChange = !getNewIndexDir().equals(getIndexDir());
@@ -449,17 +442,17 @@ public final class SolrCore implements S
} else {
currentCore = this;
}
-
+
SolrCore core = new SolrCore(getName(), getDataDir(), coreConfig.getSolrConfig(),
coreConfig.getIndexSchema(), coreDescriptor, updateHandler, this.solrDelPolicy, currentCore);
core.solrDelPolicy = this.solrDelPolicy;
-
+
// we open a new indexwriter to pick up the latest config
core.getUpdateHandler().getSolrCoreState().newIndexWriter(core, false);
-
+
core.getSearcher(true, false, null, true);
-
+
return core;
}
@@ -487,15 +480,15 @@ public final class SolrCore implements S
indexReaderFactory.init(info.initArgs);
} else {
indexReaderFactory = new StandardIndexReaderFactory();
- }
+ }
this.indexReaderFactory = indexReaderFactory;
}
-
+
// protect via synchronized(SolrCore.class)
private static Set<String> dirs = new HashSet<>();
void initIndex(boolean reload) throws IOException {
-
+
String indexDir = getNewIndexDir();
boolean indexExists = getDirectoryFactory().exists(indexDir);
boolean firstTime;
@@ -507,7 +500,7 @@ public final class SolrCore implements S
initIndexReaderFactory();
if (indexExists && firstTime && !reload) {
-
+
Directory dir = directoryFactory.get(indexDir, DirContext.DEFAULT,
getSolrConfig().indexConfig.lockType);
try {
@@ -517,7 +510,7 @@ public final class SolrCore implements S
logid
+ "WARNING: Solr index directory '{}' is locked. Unlocking...",
indexDir);
- dir.makeLock(IndexWriter.WRITE_LOCK_NAME).close();
+ dir.makeLock(IndexWriter.WRITE_LOCK_NAME).close();
} else {
log.error(logid
+ "Solr index directory '{}' is locked. Throwing exception",
@@ -525,7 +518,7 @@ public final class SolrCore implements S
throw new LockObtainFailedException(
"Index locked for write for core " + name);
}
-
+
}
} finally {
directoryFactory.release(dir);
@@ -537,26 +530,15 @@ public final class SolrCore implements S
log.warn(logid+"Solr index directory '" + new File(indexDir) + "' doesn't exist."
+ " Creating new index...");
- SolrIndexWriter writer = SolrIndexWriter.create(this, "SolrCore.initIndex", indexDir, getDirectoryFactory(), true,
+ SolrIndexWriter writer = SolrIndexWriter.create(this, "SolrCore.initIndex", indexDir, getDirectoryFactory(), true,
getLatestSchema(), solrConfig.indexConfig, solrDelPolicy, codec);
writer.close();
}
-
- }
- /** Creates an instance by trying a constructor that accepts a SolrCore before
- * trying the default (no arg) constructor.
- *@param className the instance class to create
- *@param cast the class or interface that the instance should extend or implement
- *@param msg a message helping compose the exception error if any occurs.
- *@return the desired instance
- *@throws SolrException if the object could not be instantiated
- */
- private <T> T createInstance(String className, Class<T> cast, String msg) {
- return createInstance(className,cast,msg, this);
}
+
/**
* Creates an instance by trying a constructor that accepts a SolrCore before
* trying the default (no arg) constructor.
@@ -568,11 +550,11 @@ public final class SolrCore implements S
* @return the desired instance
* @throws SolrException if the object could not be instantiated
*/
- public static <T> T createInstance(String className, Class<T> cast, String msg, SolrCore core) {
+ public static <T> T createInstance(String className, Class<T> cast, String msg, SolrCore core, ResourceLoader resourceLoader) {
Class<? extends T> clazz = null;
if (msg == null) msg = "SolrCore Object";
try {
- clazz = core.getResourceLoader().findClass(className, cast);
+ clazz = resourceLoader.findClass(className, cast);
//most of the classes do not have constructors which takes SolrCore argument. It is recommended to obtain SolrCore by implementing SolrCoreAware.
// So invariably always it will cause a NoSuchMethodException. So iterate though the list of available constructors
Constructor<?>[] cons = clazz.getConstructors();
@@ -582,7 +564,7 @@ public final class SolrCore implements S
return cast.cast(con.newInstance(core));
}
}
- return core.getResourceLoader().newInstance(className, cast);//use the empty constructor
+ return resourceLoader.newInstance(className, cast);//use the empty constructor
} catch (SolrException e) {
throw e;
} catch (Exception e) {
@@ -596,7 +578,7 @@ public final class SolrCore implements S
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error Instantiating " + msg + ", " + className + " failed to instantiate " + cast.getName(), e);
}
}
-
+
private UpdateHandler createReloadedUpdateHandler(String className, String msg, UpdateHandler updateHandler) {
Class<? extends UpdateHandler> clazz = null;
if (msg == null) msg = "SolrCore Object";
@@ -609,7 +591,7 @@ public final class SolrCore implements S
Class<?>[] types = con.getParameterTypes();
if(types.length == 2 && types[0] == SolrCore.class && types[1] == UpdateHandler.class){
return UpdateHandler.class.cast(con.newInstance(this, updateHandler));
- }
+ }
}
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Error Instantiating "+msg+", "+className+ " could not find proper constructor for " + UpdateHandler.class.getName());
} catch (SolrException e) {
@@ -628,7 +610,7 @@ public final class SolrCore implements S
public <T extends Object> T createInitInstance(PluginInfo info,Class<T> cast, String msg, String defClassName){
if(info == null) return null;
- T o = createInstance(info.className == null ? defClassName : info.className,cast, msg);
+ T o = createInstance(info.className == null ? defClassName : info.className ,cast, msg,this, getResourceLoader());
if (o instanceof PluginInfoInitialized) {
((PluginInfoInitialized) o).init(info);
} else if (o instanceof NamedListInitializedPlugin) {
@@ -640,26 +622,14 @@ public final class SolrCore implements S
return o;
}
- public SolrEventListener createEventListener(String className) {
- return createInstance(className, SolrEventListener.class, "Event Listener");
- }
-
- public SolrRequestHandler createRequestHandler(String className) {
- return createInstance(className, SolrRequestHandler.class, "Request Handler");
- }
-
private UpdateHandler createUpdateHandler(String className) {
- return createInstance(className, UpdateHandler.class, "Update Handler");
+ return createInstance(className, UpdateHandler.class, "Update Handler", this, getResourceLoader());
}
-
+
private UpdateHandler createUpdateHandler(String className, UpdateHandler updateHandler) {
return createReloadedUpdateHandler(className, "Update Handler", updateHandler);
}
- private QueryResponseWriter createQueryResponseWriter(String className) {
- return createInstance(className, QueryResponseWriter.class, "Query Response Writer");
- }
-
/**
* Creates a new core and register it in the list of cores.
* If a core with the same name already exists, it will be stopped and replaced by this one.
@@ -697,11 +667,11 @@ public final class SolrCore implements S
this.updateHandler = null;
this.isReloaded = true;
this.reqHandlers = null;
- this.searchComponents = null;
this.updateProcessorChains = null;
this.infoRegistry = null;
this.codec = null;
this.ruleExpiryLock = null;
+ this.memClassLoader = null;
solrCoreState = null;
}
@@ -719,7 +689,7 @@ public final class SolrCore implements S
this.setName( name );
resourceLoader = config.getResourceLoader();
this.solrConfig = config;
-
+
if (updateHandler == null) {
initDirectoryFactory();
}
@@ -784,7 +754,7 @@ public final class SolrCore implements S
schema = IndexSchemaFactory.buildIndexSchema(IndexSchema.DEFAULT_SCHEMA_FILE, config);
}
this.schema = schema;
- final SimilarityFactory similarityFactory = schema.getSimilarityFactory();
+ final SimilarityFactory similarityFactory = schema.getSimilarityFactory();
if (similarityFactory instanceof SolrCoreAware) {
// Similarity needs SolrCore before inform() is called on all registered SolrCoreAware listeners below
((SolrCoreAware)similarityFactory).inform(this);
@@ -796,21 +766,21 @@ public final class SolrCore implements S
this.slowQueryThresholdMillis = config.slowQueryThresholdMillis;
booleanQueryMaxClauseCount();
-
+
final CountDownLatch latch = new CountDownLatch(1);
try {
-
+
initListeners();
-
+
if (delPolicy == null) {
initDeletionPolicy();
} else {
this.solrDelPolicy = delPolicy;
}
-
+
this.codec = initCodec(solrConfig, schema);
-
+
if (updateHandler == null) {
solrCoreState = new DefaultSolrCoreState(getDirectoryFactory());
} else {
@@ -818,17 +788,15 @@ public final class SolrCore implements S
directoryFactory = solrCoreState.getDirectoryFactory();
this.isReloaded = true;
}
-
+ memClassLoader = new MemClassLoader(PluginBag.RuntimeLib.getLibObjects(this, solrConfig.getPluginInfos(PluginBag.RuntimeLib.class.getName())), getResourceLoader());
initIndex(prev != null);
-
+
initWriters();
- initQParsers();
- initValueSourceParsers();
- initTransformerFactories();
-
- this.searchComponents = Collections
- .unmodifiableMap(loadSearchComponents());
-
+ qParserPlugins.init(createInstances(QParserPlugin.standardPlugins), this);
+ valueSourceParsers.init(ValueSourceParser.standardValueSourceParsers, this);
+ transformerFactories.init(TransformerFactory.defaultFactories, this);
+ loadSearchComponents();
+
// Processors initialized before the handlers
updateProcessorChains = loadUpdateProcessorChains();
reqHandlers = new RequestHandlers(this);
@@ -836,9 +804,9 @@ public final class SolrCore implements S
// Handle things that should eventually go away
initDeprecatedSupport();
-
+
statsCache = initStatsCache();
-
+
// cause the executor to stall so firstSearcher events won't fire
// until after inform() has been called for all components.
// searchExecutor must be single-threaded for this to work
@@ -849,7 +817,7 @@ public final class SolrCore implements S
return null;
}
});
-
+
// use the (old) writer to open the first searcher
RefCounted<IndexWriter> iwRef = null;
if (prev != null) {
@@ -867,9 +835,9 @@ public final class SolrCore implements S
};
}
}
-
+
String updateHandlerClass = solrConfig.getUpdateHandlerInfo().className;
-
+
if (updateHandler == null) {
this.updateHandler = createUpdateHandler(updateHandlerClass == null ? DirectUpdateHandler2.class
.getName() : updateHandlerClass);
@@ -886,10 +854,10 @@ public final class SolrCore implements S
newReaderCreator = null;
if (iwRef != null) iwRef.decref();
}
-
+
// Initialize the RestManager
restManager = initRestManager();
-
+
// Finally tell anyone who wants to know
resourceLoader.inform(resourceLoader);
resourceLoader.inform(this); // last call before the latch is released.
@@ -899,7 +867,7 @@ public final class SolrCore implements S
if (e instanceof OutOfMemoryError) {
throw (OutOfMemoryError)e;
}
-
+
try {
this.close();
} catch (Throwable t) {
@@ -908,8 +876,8 @@ public final class SolrCore implements S
}
log.error("Error while closing", t);
}
-
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
e.getMessage(), e);
} finally {
// allow firstSearcher events to fire and make sure it is released
@@ -917,7 +885,7 @@ public final class SolrCore implements S
}
infoRegistry.put("core", this);
-
+
// register any SolrInfoMBeans SolrResourceLoader initialized
//
// this must happen after the latch is released, because a JMX server impl may
@@ -925,7 +893,7 @@ public final class SolrCore implements S
// and a SolrCoreAware MBean may have properties that depend on getting a Searcher
// from the core.
resourceLoader.inform(infoRegistry);
-
+
CoreContainer cc = cd.getCoreContainer();
if (cc != null && cc.isZooKeeperAware()) {
@@ -951,7 +919,7 @@ public final class SolrCore implements S
ruleExpiryLock = new ReentrantLock();
registerConfListener();
}
-
+
private Codec initCodec(SolrConfig solrConfig, final IndexSchema schema) {
final PluginInfo info = solrConfig.getPluginInfo(CodecFactory.class.getName());
final CodecFactory factory;
@@ -986,7 +954,7 @@ public final class SolrCore implements S
}
return factory.getCodec();
}
-
+
private StatsCache initStatsCache() {
final StatsCache cache;
PluginInfo pluginInfo = solrConfig.getPluginInfo(StatsCache.class.getName());
@@ -1016,7 +984,7 @@ public final class SolrCore implements S
UpdateRequestProcessorChain def = initPlugins(map,UpdateRequestProcessorChain.class, UpdateRequestProcessorChain.class.getName());
if(def == null){
def = map.get(null);
- }
+ }
if (def == null) {
log.info("no updateRequestProcessorChain defined as default, creating implicit default");
// construct the default chain
@@ -1031,14 +999,14 @@ public final class SolrCore implements S
map.put("", def);
return map;
}
-
+
public SolrCoreState getSolrCoreState() {
return solrCoreState;
- }
+ }
/**
* @return an update processor registered to the given name. Throw an exception if this chain is undefined
- */
+ */
public UpdateRequestProcessorChain getUpdateProcessingChain( final String name )
{
UpdateRequestProcessorChain chain = updateProcessorChains.get( name );
@@ -1048,7 +1016,7 @@ public final class SolrCore implements S
}
return chain;
}
-
+
// this core current usage count
private final AtomicInteger refCount = new AtomicInteger(1);
@@ -1056,7 +1024,7 @@ public final class SolrCore implements S
public void open() {
refCount.incrementAndGet();
}
-
+
/**
* Close all resources allocated by the core if it is no longer in use...
* <ul>
@@ -1065,7 +1033,7 @@ public final class SolrCore implements S
* <li>all CloseHooks will be notified</li>
* <li>All MBeans will be unregistered from MBeanServer if JMX was enabled
* </li>
- * </ul>
+ * </ul>
* <p>
* The behavior of this method is determined by the result of decrementing
* the core's reference count (A core is created with a reference count of 1)...
@@ -1079,7 +1047,7 @@ public final class SolrCore implements S
* is taken.
* </li>
* </ul>
- * @see #isClosed()
+ * @see #isClosed()
*/
public void close() {
int count = refCount.decrementAndGet();
@@ -1097,7 +1065,7 @@ public final class SolrCore implements S
try {
hook.preClose( this );
} catch (Throwable e) {
- SolrException.log(log, e);
+ SolrException.log(log, e);
if (e instanceof Error) {
throw (Error) e;
}
@@ -1106,6 +1074,18 @@ public final class SolrCore implements S
}
if(reqHandlers != null) reqHandlers.close();
+ responseWriters.close();
+ searchComponents.close();
+ qParserPlugins.close();
+ valueSourceParsers.close();
+ transformerFactories.close();
+
+ if (memClassLoader != null) {
+ try {
+ memClassLoader.close();
+ } catch (Exception e) {
+ }
+ }
try {
@@ -1118,7 +1098,7 @@ public final class SolrCore implements S
throw (Error) e;
}
}
-
+
boolean coreStateClosed = false;
try {
if (solrCoreState != null) {
@@ -1134,7 +1114,7 @@ public final class SolrCore implements S
throw (Error) e;
}
}
-
+
try {
ExecutorUtil.shutdownAndAwaitTermination(searcherExecutor);
} catch (Throwable e) {
@@ -1168,9 +1148,9 @@ public final class SolrCore implements S
throw (Error) e;
}
}
-
+
if (coreStateClosed) {
-
+
try {
directoryFactory.close();
} catch (Throwable e) {
@@ -1179,10 +1159,10 @@ public final class SolrCore implements S
throw (Error) e;
}
}
-
+
}
-
+
if( closeHooks != null ) {
for( CloseHook hook : closeHooks ) {
try {
@@ -1195,7 +1175,7 @@ public final class SolrCore implements S
}
}
}
-
+
// For debugging
// numCloses.incrementAndGet();
// openHandles.remove(this);
@@ -1205,12 +1185,12 @@ public final class SolrCore implements S
public int getOpenCount() {
return refCount.get();
}
-
+
/** Whether this core is closed. */
public boolean isClosed() {
return refCount.get() <= 0;
}
-
+
@Override
protected void finalize() throws Throwable {
try {
@@ -1258,113 +1238,74 @@ public final class SolrCore implements S
////////////////////////////////////////////////////////////////////////////////
/**
- * Get the request handler registered to a given name.
- *
+ * Get the request handler registered to a given name.
+ *
* This function is thread safe.
*/
public SolrRequestHandler getRequestHandler(String handlerName) {
- return RequestHandlerBase.getRequestHandler(RequestHandlers.normalize(handlerName), reqHandlers.getRequestHandlers());
+ return RequestHandlerBase.getRequestHandler(RequestHandlers.normalize(handlerName), reqHandlers.handlers);
}
/**
- * Returns an unmodifiable Map containing the registered handlers of the specified type.
- */
- public <T extends SolrRequestHandler> Map<String,T> getRequestHandlers(Class<T> clazz) {
- return reqHandlers.getAll(clazz);
- }
-
- /**
* Returns an unmodifiable Map containing the registered handlers
*/
- public Map<String,SolrRequestHandler> getRequestHandlers() {
- return reqHandlers.getRequestHandlers();
+ public PluginBag<SolrRequestHandler> getRequestHandlers() {
+ return reqHandlers.handlers;
}
/**
* Registers a handler at the specified location. If one exists there, it will be replaced.
* To remove a handler, register <code>null</code> at its path
- *
+ *
* Once registered the handler can be accessed through:
* <pre>
* http://${host}:${port}/${context}/${handlerName}
- * or:
+ * or:
* http://${host}:${port}/${context}/select?qt=${handlerName}
- * </pre>
- *
+ * </pre>
+ *
* Handlers <em>must</em> be initialized before getting registered. Registered
* handlers can immediately accept requests.
- *
+ *
* This call is thread safe.
- *
+ *
* @return the previous <code>SolrRequestHandler</code> registered to this name <code>null</code> if none.
*/
public SolrRequestHandler registerRequestHandler(String handlerName, SolrRequestHandler handler) {
return reqHandlers.register(handlerName,handler);
}
-
+
/**
* Register the default search components
*/
- private Map<String, SearchComponent> loadSearchComponents()
+ private void loadSearchComponents()
{
- Map<String, SearchComponent> components = new HashMap<>();
- initPlugins(components,SearchComponent.class);
- for (Map.Entry<String, SearchComponent> e : components.entrySet()) {
- SearchComponent c = e.getValue();
- if (c instanceof HighlightComponent) {
- HighlightComponent hl = (HighlightComponent) c;
- if(!HighlightComponent.COMPONENT_NAME.equals(e.getKey())){
- components.put(HighlightComponent.COMPONENT_NAME,hl);
+ Map<String, SearchComponent> instances = createInstances(SearchComponent.standard_components);
+ for (Map.Entry<String, SearchComponent> e : instances.entrySet()) e.getValue().setName(e.getKey());
+ searchComponents.init(instances, this);
+
+ for (String name : searchComponents.keySet()) {
+ if (searchComponents.isLoaded(name) && searchComponents.get(name) instanceof HighlightComponent) {
+ if (!HighlightComponent.COMPONENT_NAME.equals(name)) {
+ searchComponents.put(HighlightComponent.COMPONENT_NAME, searchComponents.getRegistry().get(name));
}
break;
}
}
- addIfNotPresent(components,HighlightComponent.COMPONENT_NAME,HighlightComponent.class);
- addIfNotPresent(components,QueryComponent.COMPONENT_NAME,QueryComponent.class);
- addIfNotPresent(components,FacetComponent.COMPONENT_NAME,FacetComponent.class);
- addIfNotPresent(components,MoreLikeThisComponent.COMPONENT_NAME,MoreLikeThisComponent.class);
- addIfNotPresent(components,StatsComponent.COMPONENT_NAME,StatsComponent.class);
- addIfNotPresent(components,DebugComponent.COMPONENT_NAME,DebugComponent.class);
- addIfNotPresent(components,RealTimeGetComponent.COMPONENT_NAME,RealTimeGetComponent.class);
- addIfNotPresent(components,ExpandComponent.COMPONENT_NAME,ExpandComponent.class);
-
- return components;
- }
- private <T> void addIfNotPresent(Map<String ,T> registry, String name, Class<? extends T> c){
- if(!registry.containsKey(name)){
- T searchComp = resourceLoader.newInstance(c.getName(), c);
- if (searchComp instanceof NamedListInitializedPlugin){
- ((NamedListInitializedPlugin)searchComp).init( new NamedList<String>() );
- }
- if(searchComp instanceof SearchComponent) {
- ((SearchComponent)searchComp).setName(name);
- }
- registry.put(name, searchComp);
- if (searchComp instanceof SolrInfoMBean){
- infoRegistry.put(((SolrInfoMBean)searchComp).getName(), (SolrInfoMBean)searchComp);
- }
- }
}
-
/**
* @return a Search Component registered to a given name. Throw an exception if the component is undefined
*/
- public SearchComponent getSearchComponent( String name )
- {
- SearchComponent component = searchComponents.get( name );
- if( component == null ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
- "Unknown Search Component: "+name );
- }
- return component;
+ public SearchComponent getSearchComponent(String name) {
+ return searchComponents.get(name);
}
/**
* Accessor for all the Search Components
* @return An unmodifiable Map of Search Components
*/
- public Map<String, SearchComponent> getSearchComponents() {
+ public PluginBag<SearchComponent> getSearchComponents() {
return searchComponents;
}
@@ -1374,7 +1315,7 @@ public final class SolrCore implements S
/**
* RequestHandlers need access to the updateHandler so they can all talk to the
- * same RAM indexer.
+ * same RAM indexer.
*/
public UpdateHandler getUpdateHandler() {
return updateHandler;
@@ -1529,7 +1470,7 @@ public final class SolrCore implements S
DirectoryReader currentReader = newestSearcher.get().getRawReader();
// SolrCore.verbose("start reopen from",previousSearcher,"writer=",writer);
-
+
RefCounted<IndexWriter> writer = getUpdateHandler().getSolrCoreState()
.getIndexWriter(null);
try {
@@ -1582,7 +1523,7 @@ public final class SolrCore implements S
// so that we pick up any uncommitted changes and so we don't go backwards
// in time on a core reload
DirectoryReader newReader = newReaderCreator.call();
- tmp = new SolrIndexSearcher(this, newIndexDir, getLatestSchema(),
+ tmp = new SolrIndexSearcher(this, newIndexDir, getLatestSchema(),
(realtime ? "realtime":"main"), newReader, true, !realtime, true, directoryFactory);
} else {
RefCounted<IndexWriter> writer = getUpdateHandler().getSolrCoreState().getIndexWriter(this);
@@ -1626,7 +1567,7 @@ public final class SolrCore implements S
}
}
-
+
/**
* Get a {@link SolrIndexSearcher} or start the process of creating a new one.
* <p>
@@ -1764,7 +1705,7 @@ public final class SolrCore implements S
// if the underlying seracher has not changed, no warming is needed
if (newSearcher != currSearcher) {
-
+
// warm the new searcher based on the current searcher.
// should this go before the other event handlers or after?
if (currSearcher != null) {
@@ -1783,7 +1724,7 @@ public final class SolrCore implements S
}
});
}
-
+
if (currSearcher == null) {
future = searcherExecutor.submit(new Callable() {
@Override
@@ -1802,7 +1743,7 @@ public final class SolrCore implements S
}
});
}
-
+
if (currSearcher != null) {
future = searcherExecutor.submit(new Callable() {
@Override
@@ -1821,7 +1762,7 @@ public final class SolrCore implements S
}
});
}
-
+
}
@@ -2005,9 +1946,9 @@ public final class SolrCore implements S
if (handler==null) {
String msg = "Null Request Handler '" +
req.getParams().get(CommonParams.QT) + "'";
-
+
if (log.isWarnEnabled()) log.warn(logid + msg + ":" + req);
-
+
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, msg);
}
@@ -2094,7 +2035,7 @@ public final class SolrCore implements S
if( ep != null ) {
EchoParamStyle echoParams = EchoParamStyle.get( ep );
if( echoParams == null ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,"Invalid value '" + ep + "' for " + CommonParams.HEADER_ECHO_PARAMS
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Invalid value '" + ep + "' for " + CommonParams.HEADER_ECHO_PARAMS
+ " parameter, use '" + EchoParamStyle.EXPLICIT + "' or '" + EchoParamStyle.ALL + "'" );
}
if( echoParams == EchoParamStyle.EXPLICIT ) {
@@ -2109,10 +2050,11 @@ public final class SolrCore implements S
SolrException.log(log,null,e);
}
-
-
- private QueryResponseWriter defaultResponseWriter;
- private final Map<String, QueryResponseWriter> responseWriters = new HashMap<>();
+ public PluginBag<QueryResponseWriter> getResponseWriters() {
+ return responseWriters;
+ }
+
+ private final PluginBag<QueryResponseWriter> responseWriters = new PluginBag<>(QueryResponseWriter.class, this);
public static final Map<String ,QueryResponseWriter> DEFAULT_RESPONSE_WRITERS ;
static{
HashMap<String, QueryResponseWriter> m= new HashMap<>();
@@ -2147,165 +2089,60 @@ public final class SolrCore implements S
};
}
+ public MemClassLoader getMemClassLoader() {
+ return memClassLoader;
+ }
+
public interface RawWriter {
public void write(OutputStream os) throws IOException ;
}
-
+
/** Configure the query response writers. There will always be a default writer; additional
* writers may also be configured. */
private void initWriters() {
- // use link map so we iterate in the same order
- Map<PluginInfo,QueryResponseWriter> writers = new LinkedHashMap<>();
- for (PluginInfo info : solrConfig.getPluginInfos(QueryResponseWriter.class.getName())) {
- try {
- QueryResponseWriter writer;
- String startup = info.attributes.get("startup") ;
- if( startup != null ) {
- if( "lazy".equals(startup) ) {
- log.info("adding lazy queryResponseWriter: " + info.className);
- writer = new LazyQueryResponseWriterWrapper(this, info.className, info.initArgs );
- } else {
- throw new Exception( "Unknown startup value: '"+startup+"' for: "+info.className );
- }
- } else {
- writer = createQueryResponseWriter(info.className);
- }
- writers.put(info,writer);
- QueryResponseWriter old = registerResponseWriter(info.name, writer);
- if(old != null) {
- log.warn("Multiple queryResponseWriter registered to the same name: " + info.name + " ignoring: " + old.getClass().getName());
- }
- if(info.isDefault()){
- if(defaultResponseWriter != null)
- log.warn("Multiple default queryResponseWriter registered, using: " + info.name);
- defaultResponseWriter = writer;
- }
- log.info("created "+info.name+": " + info.className);
- } catch (Exception ex) {
- SolrException e = new SolrException
- (SolrException.ErrorCode.SERVER_ERROR, "QueryResponseWriter init failure", ex);
- SolrException.log(log,null,e);
- throw e;
- }
- }
-
- // we've now registered all handlers, time to init them in the same order
- for (Map.Entry<PluginInfo,QueryResponseWriter> entry : writers.entrySet()) {
- PluginInfo info = entry.getKey();
- QueryResponseWriter writer = entry.getValue();
- responseWriters.put(info.name, writer);
- if (writer instanceof PluginInfoInitialized) {
- ((PluginInfoInitialized) writer).init(info);
- } else{
- writer.init(info.initArgs);
- }
- }
-
- NamedList emptyList = new NamedList();
- for (Map.Entry<String, QueryResponseWriter> entry : DEFAULT_RESPONSE_WRITERS.entrySet()) {
- if(responseWriters.get(entry.getKey()) == null) {
- responseWriters.put(entry.getKey(), entry.getValue());
- // call init so any logic in the default writers gets invoked
- entry.getValue().init(emptyList);
- }
- }
-
+ responseWriters.init(DEFAULT_RESPONSE_WRITERS, this);
// configure the default response writer; this one should never be null
- if (defaultResponseWriter == null) {
- defaultResponseWriter = responseWriters.get("standard");
- }
-
+ if (responseWriters.getDefault() == null) responseWriters.setDefault("standard");
}
-
+
+
/** Finds a writer by name, or returns the default writer if not found. */
public final QueryResponseWriter getQueryResponseWriter(String writerName) {
- if (writerName != null) {
- QueryResponseWriter writer = responseWriters.get(writerName);
- if (writer != null) {
- return writer;
- }
- }
- return defaultResponseWriter;
+ return responseWriters.get(writerName, true);
}
/** Returns the appropriate writer for a request. If the request specifies a writer via the
* 'wt' parameter, attempts to find that one; otherwise return the default writer.
*/
public final QueryResponseWriter getQueryResponseWriter(SolrQueryRequest request) {
- return getQueryResponseWriter(request.getParams().get(CommonParams.WT));
+ return getQueryResponseWriter(request.getParams().get(CommonParams.WT));
}
- private final Map<String, QParserPlugin> qParserPlugins = new HashMap<>();
- /** Configure the query parsers. */
- private void initQParsers() {
- initPlugins(qParserPlugins,QParserPlugin.class);
- // default parsers
- for (int i=0; i<QParserPlugin.standardPlugins.length; i+=2) {
- try {
- String name = (String)QParserPlugin.standardPlugins[i];
- if (null == qParserPlugins.get(name)) {
- Class<QParserPlugin> clazz = (Class<QParserPlugin>)QParserPlugin.standardPlugins[i+1];
- QParserPlugin plugin = clazz.newInstance();
- qParserPlugins.put(name, plugin);
- plugin.init(null);
- infoRegistry.put(name, plugin);
- }
- } catch (Exception e) {
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
- }
- }
- }
+ private final PluginBag<QParserPlugin> qParserPlugins = new PluginBag<>(QParserPlugin.class, this);
public QParserPlugin getQueryPlugin(String parserName) {
- QParserPlugin plugin = qParserPlugins.get(parserName);
- if (plugin != null) return plugin;
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown query parser '"+parserName+"'");
- }
-
- private final HashMap<String, ValueSourceParser> valueSourceParsers = new HashMap<>();
-
- /** Configure the ValueSource (function) plugins */
- private void initValueSourceParsers() {
- initPlugins(valueSourceParsers,ValueSourceParser.class);
- // default value source parsers
- for (Map.Entry<String, ValueSourceParser> entry : ValueSourceParser.standardValueSourceParsers.entrySet()) {
- try {
- String name = entry.getKey();
- if (null == valueSourceParsers.get(name)) {
- ValueSourceParser valueSourceParser = entry.getValue();
- valueSourceParsers.put(name, valueSourceParser);
- valueSourceParser.init(null);
- }
- } catch (Exception e) {
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
- }
- }
+ return qParserPlugins.get(parserName);
}
-
- private final HashMap<String, TransformerFactory> transformerFactories = new HashMap<>();
-
- /** Configure the TransformerFactory plugins */
- private void initTransformerFactories() {
- // Load any transformer factories
- initPlugins(transformerFactories,TransformerFactory.class);
-
- // Tell each transformer what its name is
- for( Map.Entry<String, TransformerFactory> entry : TransformerFactory.defaultFactories.entrySet() ) {
+ private final PluginBag<ValueSourceParser> valueSourceParsers = new PluginBag<>(ValueSourceParser.class, this);
+
+ private final PluginBag<TransformerFactory> transformerFactories = new PluginBag<>(TransformerFactory.class, this);
+
+ <T> Map<String, T> createInstances(Map<String, Class<? extends T>> map) {
+ Map<String, T> result = new LinkedHashMap<>();
+ for (Map.Entry<String, Class<? extends T>> e : map.entrySet()) {
try {
- String name = entry.getKey();
- if (null == valueSourceParsers.get(name)) {
- TransformerFactory f = entry.getValue();
- transformerFactories.put(name, f);
- // f.init(null); default ones don't need init
- }
- } catch (Exception e) {
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+ Object o = getResourceLoader().newInstance(e.getValue().getName(), e.getValue());
+ result.put(e.getKey(), (T) o);
+ } catch (Exception exp) {
+ //should never happen
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unbale to instantiate class", exp);
}
}
+ return result;
}
-
+
public TransformerFactory getTransformerFactory(String name) {
return transformerFactories.get(name);
}
@@ -2313,7 +2150,7 @@ public final class SolrCore implements S
public void addTransformerFactory(String name, TransformerFactory factory){
transformerFactories.put(name, factory);
}
-
+
/**
* @param registry The map to which the instance should be added to. The key is the name attribute
@@ -2321,7 +2158,7 @@ public final class SolrCore implements S
* @param defClassName If PluginInfo does not have a classname, use this as the classname
* @return The default instance . The one with (default=true)
*/
- public <T> T initPlugins(Map<String ,T> registry, Class<T> type, String defClassName){
+ private <T> T initPlugins(Map<String, T> registry, Class<T> type, String defClassName) {
return initPlugins(solrConfig.getPluginInfos(type.getName()), registry, type, defClassName);
}
@@ -2361,7 +2198,7 @@ public final class SolrCore implements S
public ValueSourceParser getValueSourceParser(String parserName) {
return valueSourceParsers.get(parserName);
}
-
+
/**
* Manage anything that should be taken care of in case configs change
*/
@@ -2370,19 +2207,19 @@ public final class SolrCore implements S
// TODO -- this should be removed in deprecation release...
String gettable = solrConfig.get("admin/gettableFiles", null );
if( gettable != null ) {
- log.warn(
+ log.warn(
"solrconfig.xml uses deprecated <admin/gettableFiles>, Please "+
"update your config to use the ShowFileRequestHandler." );
if( getRequestHandler( "/admin/file" ) == null ) {
NamedList<String> invariants = new NamedList<>();
-
+
// Hide everything...
Set<String> hide = new HashSet<>();
for (String file : solrConfig.getResourceLoader().listConfigDir()) {
hide.add(file.toUpperCase(Locale.ROOT));
- }
-
+ }
+
// except the "gettable" list
StringTokenizer st = new StringTokenizer( gettable );
while( st.hasMoreTokens() ) {
@@ -2391,7 +2228,7 @@ public final class SolrCore implements S
for( String s : hide ) {
invariants.add( ShowFileRequestHandler.HIDDEN, s );
}
-
+
NamedList<Object> args = new NamedList<>();
args.add( "invariants", invariants );
ShowFileRequestHandler handler = new ShowFileRequestHandler();
@@ -2404,12 +2241,12 @@ public final class SolrCore implements S
String facetSort = solrConfig.get("//bool[@name='facet.sort']", null);
if (facetSort != null) {
- log.warn(
+ log.warn(
"solrconfig.xml uses deprecated <bool name='facet.sort'>. Please "+
"update your config to use <string name='facet.sort'>.");
}
- }
-
+ }
+
/**
* Creates and initializes a RestManager based on configuration args in solrconfig.xml.
* RestManager provides basic storage support for managed resource data, such as to
@@ -2417,36 +2254,36 @@ public final class SolrCore implements S
*/
@SuppressWarnings("unchecked")
protected RestManager initRestManager() throws SolrException {
-
- PluginInfo restManagerPluginInfo =
+
+ PluginInfo restManagerPluginInfo =
getSolrConfig().getPluginInfo(RestManager.class.getName());
-
+
NamedList<String> initArgs = null;
RestManager mgr = null;
if (restManagerPluginInfo != null) {
if (restManagerPluginInfo.className != null) {
mgr = resourceLoader.newInstance(restManagerPluginInfo.className, RestManager.class);
}
-
+
if (restManagerPluginInfo.initArgs != null) {
- initArgs = (NamedList<String>)restManagerPluginInfo.initArgs;
+ initArgs = (NamedList<String>) restManagerPluginInfo.initArgs;
}
}
-
- if (mgr == null)
+
+ if (mgr == null)
mgr = new RestManager();
-
+
if (initArgs == null)
initArgs = new NamedList<>();
-
+
String collection = coreDescriptor.getCollectionName();
- StorageIO storageIO =
- ManagedResourceStorage.newStorageIO(collection, resourceLoader, initArgs);
+ StorageIO storageIO =
+ ManagedResourceStorage.newStorageIO(collection, resourceLoader, initArgs);
mgr.init(resourceLoader, initArgs, storageIO);
-
+
return mgr;
- }
-
+ }
+
public CoreDescriptor getCoreDescriptor() {
return coreDescriptor;
}
@@ -2516,10 +2353,10 @@ public final class SolrCore implements S
lst.add("shard", shard);
}
}
-
+
return lst;
}
-
+
public Codec getCodec() {
return codec;
}
@@ -2583,50 +2420,6 @@ public final class SolrCore implements S
}
}
- public final class LazyQueryResponseWriterWrapper implements QueryResponseWriter {
- private SolrCore _core;
- private String _className;
- private NamedList _args;
- private QueryResponseWriter _writer;
-
- public LazyQueryResponseWriterWrapper(SolrCore core, String className, NamedList args) {
- _core = core;
- _className = className;
- _args = args;
- _writer = null;
- }
-
- public synchronized QueryResponseWriter getWrappedWriter()
- {
- if( _writer == null ) {
- try {
- QueryResponseWriter writer = createQueryResponseWriter(_className);
- writer.init( _args );
- _writer = writer;
- }
- catch( Exception ex ) {
- throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "lazy loading error", ex );
- }
- }
- return _writer;
- }
-
-
- @Override
- public void init(NamedList args) {
- // do nothing
- }
-
- @Override
- public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
- getWrappedWriter().write(writer, request, response);
- }
-
- @Override
- public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
- return getWrappedWriter().getContentType(request, response);
- }
- }
/**Register to notify for any file change in the conf directory.
* If the file change results in a core reload , then the listener
@@ -2714,6 +2507,10 @@ public final class SolrCore implements S
};
}
+ public void registerInfoBean(String name, SolrInfoMBean solrInfoMBean) {
+ infoRegistry.put(name, solrInfoMBean);
+ }
+
private static boolean checkStale(SolrZkClient zkClient, String zkPath, int currentVersion) {
if(zkPath == null) return false;
try {
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java Mon Mar 9 16:29:08 2015
@@ -22,8 +22,7 @@ import org.apache.solr.common.params.Sol
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.PluginInfo;
-import org.apache.solr.core.RequestHandlers;
-import org.apache.solr.core.RequestParams;
+import org.apache.solr.core.PluginBag;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoMBean;
import org.apache.solr.request.SolrQueryRequest;
@@ -36,7 +35,6 @@ import org.apache.solr.util.stats.Timer;
import org.apache.solr.util.stats.TimerContext;
import java.net.URL;
-import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import static org.apache.solr.core.RequestParams.USEPARAM;
@@ -215,7 +213,7 @@ public abstract class RequestHandlerBase
*
* This function is thread safe.
*/
- public static SolrRequestHandler getRequestHandler(String handlerName, Map<String, SolrRequestHandler> reqHandlers) {
+ public static SolrRequestHandler getRequestHandler(String handlerName, PluginBag<SolrRequestHandler> reqHandlers) {
if(handlerName == null) return null;
SolrRequestHandler handler = reqHandlers.get(handlerName);
int idx = 0;
@@ -226,9 +224,6 @@ public abstract class RequestHandlerBase
String firstPart = handlerName.substring(0, idx);
handler = reqHandlers.get(firstPart);
if (handler == null) continue;
- if(handler instanceof RequestHandlers.LazyRequestHandlerWrapper) {
- handler = ((RequestHandlers.LazyRequestHandlerWrapper)handler).getWrappedHandler();
- }
if (handler instanceof NestedRequestHandler) {
return ((NestedRequestHandler) handler).getSubHandler(handlerName.substring(idx));
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java Mon Mar 9 16:29:08 2015
@@ -43,19 +43,14 @@ import org.apache.solr.common.util.Conte
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.ConfigOverlay;
import org.apache.solr.core.PluginInfo;
-import org.apache.solr.core.PluginsRegistry;
+import org.apache.solr.core.ImplicitPlugins;
import org.apache.solr.core.RequestParams;
import org.apache.solr.core.SolrConfig;
-import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.response.transform.TransformerFactory;
import org.apache.solr.schema.SchemaManager;
-import org.apache.solr.search.QParserPlugin;
-import org.apache.solr.search.ValueSourceParser;
import org.apache.solr.util.CommandOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,6 +59,7 @@ import static java.text.MessageFormat.fo
import static java.util.Collections.singletonList;
import static org.apache.solr.common.params.CoreAdminParams.NAME;
import static org.apache.solr.core.ConfigOverlay.NOT_EDITABLE;
+import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_CLASS;
import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_NAME;
import static org.apache.solr.schema.FieldType.CLASS_NAME;
@@ -152,7 +148,7 @@ public class SolrConfigHandler extends R
Map<String, Object> map = req.getCore().getSolrConfig().toMap();
Map reqHandlers = (Map) map.get(SolrRequestHandler.TYPE);
if (reqHandlers == null) map.put(SolrRequestHandler.TYPE, reqHandlers = new LinkedHashMap<>());
- List<PluginInfo> plugins = PluginsRegistry.getHandlers(req.getCore());
+ List<PluginInfo> plugins = ImplicitPlugins.getHandlers(req.getCore());
for (PluginInfo plugin : plugins) {
if (SolrRequestHandler.TYPE.equals(plugin.type)) {
if (!reqHandlers.containsKey(plugin.name)) {
@@ -316,7 +312,7 @@ public class SolrConfigHandler extends R
if ("delete".equals(prefix)) {
overlay = deleteNamedComponent(op, overlay, info.tag);
} else {
- overlay = updateNamedPlugin(info, op, overlay, prefix.equals("create"));
+ overlay = updateNamedPlugin(info, op, overlay, prefix.equals("create") || prefix.equals("add"));
}
} else {
op.addError(MessageFormat.format("Unknown operation ''{0}'' ", op.name));
@@ -359,7 +355,7 @@ public class SolrConfigHandler extends R
private ConfigOverlay updateNamedPlugin(SolrConfig.SolrPluginInfo info, CommandOperation op, ConfigOverlay overlay, boolean isCeate) {
String name = op.getStr(NAME);
- String clz = op.getStr(CLASS_NAME);
+ String clz = info.options.contains(REQUIRE_CLASS) ? op.getStr(CLASS_NAME) : op.getStr(CLASS_NAME, null);
op.getMap(PluginInfo.DEFAULTS, null);
op.getMap(PluginInfo.INVARIANTS, null);
op.getMap(PluginInfo.APPENDS, null);
@@ -383,10 +379,11 @@ public class SolrConfigHandler extends R
}
private boolean verifyClass(CommandOperation op, String clz, Class expected) {
- if (op.getStr("lib", null) == null) {
+ if (clz == null) return true;
+ if ( !"true".equals(String.valueOf(op.getStr("runtimeLib", null)))) {
//this is not dynamically loaded so we can verify the class right away
try {
- SolrCore.createInstance(clz, expected, expected.getSimpleName(), req.getCore());
+ req.getCore().createInitInstance(new PluginInfo(SolrRequestHandler.TYPE, op.getDataMap()), expected, clz, "");
} catch (Exception e) {
op.addError(e.getMessage());
return false;
@@ -522,6 +519,6 @@ public class SolrConfigHandler extends R
public static final String SET = "set";
public static final String UPDATE = "update";
public static final String CREATE = "create";
- private static Set<String> cmdPrefixes = ImmutableSet.of(CREATE, UPDATE, "delete");
+ private static Set<String> cmdPrefixes = ImmutableSet.of(CREATE, UPDATE, "delete", "add");
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/admin/AdminHandlers.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/admin/AdminHandlers.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/admin/AdminHandlers.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/admin/AdminHandlers.java Mon Mar 9 16:29:08 2015
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
+import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
@@ -36,7 +37,7 @@ import org.slf4j.LoggerFactory;
* @since solr 1.3
*/
@Deprecated
-public class AdminHandlers implements SolrCoreAware, SolrRequestHandler
+public class AdminHandlers extends RequestHandlerBase implements SolrCoreAware
{
public static Logger log = LoggerFactory.getLogger(AdminHandlers.class);
NamedList initArgs = null;
@@ -59,17 +60,12 @@ public class AdminHandlers implements So
public void init(NamedList args) {
this.initArgs = args;
}
-
+
@Override
public void inform(SolrCore core)
{
String path = null;
- for( Map.Entry<String, SolrRequestHandler> entry : core.getRequestHandlers().entrySet() ) {
- if( entry.getValue() == this ) {
- path = entry.getKey();
- break;
- }
- }
+ path = getPluginInfo().name;
if( path == null ) {
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
"The AdminHandler is not registered with the current core." );
@@ -107,9 +103,9 @@ public class AdminHandlers implements So
log.warn("<requestHandler name=\"/admin/\" \n class=\"solr.admin.AdminHandlers\" /> is deprecated . It is not required anymore");
}
-
+
@Override
- public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
+ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) {
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
"The AdminHandler should never be called directly" );
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java Mon Mar 9 16:29:08 2015
@@ -19,6 +19,9 @@ package org.apache.solr.handler.componen
import java.io.IOException;
import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrInfoMBean;
@@ -122,4 +125,21 @@ public abstract class SearchComponent im
public NamedList getStatistics() {
return null;
}
+
+ public static final Map<String, Class<? extends SearchComponent>> standard_components;
+ ;
+
+ static {
+ HashMap<String, Class<? extends SearchComponent>> map = new HashMap<>();
+ map.put(HighlightComponent.COMPONENT_NAME, HighlightComponent.class);
+ map.put(QueryComponent.COMPONENT_NAME, QueryComponent.class);
+ map.put(FacetComponent.COMPONENT_NAME, FacetComponent.class);
+ map.put(MoreLikeThisComponent.COMPONENT_NAME, MoreLikeThisComponent.class);
+ map.put(StatsComponent.COMPONENT_NAME, StatsComponent.class);
+ map.put(DebugComponent.COMPONENT_NAME, DebugComponent.class);
+ map.put(RealTimeGetComponent.COMPONENT_NAME, RealTimeGetComponent.class);
+ map.put(ExpandComponent.COMPONENT_NAME, ExpandComponent.class);
+ standard_components = Collections.unmodifiableMap(map);
+ }
+
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/QParserPlugin.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/QParserPlugin.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/QParserPlugin.java Mon Mar 9 16:29:08 2015
@@ -26,6 +26,9 @@ import org.apache.solr.search.mlt.MLTQPa
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrInfoMBean {
/** internal use - name of the default parser */
@@ -38,35 +41,39 @@ public abstract class QParserPlugin impl
* This result to NPE during initialization.
* For every plugin, listed here, NAME field has to be final and static.
*/
- public static final Object[] standardPlugins = {
- LuceneQParserPlugin.NAME, LuceneQParserPlugin.class,
- OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class,
- FunctionQParserPlugin.NAME, FunctionQParserPlugin.class,
- PrefixQParserPlugin.NAME, PrefixQParserPlugin.class,
- BoostQParserPlugin.NAME, BoostQParserPlugin.class,
- DisMaxQParserPlugin.NAME, DisMaxQParserPlugin.class,
- ExtendedDismaxQParserPlugin.NAME, ExtendedDismaxQParserPlugin.class,
- FieldQParserPlugin.NAME, FieldQParserPlugin.class,
- RawQParserPlugin.NAME, RawQParserPlugin.class,
- TermQParserPlugin.NAME, TermQParserPlugin.class,
- TermsQParserPlugin.NAME, TermsQParserPlugin.class,
- NestedQParserPlugin.NAME, NestedQParserPlugin.class,
- FunctionRangeQParserPlugin.NAME, FunctionRangeQParserPlugin.class,
- SpatialFilterQParserPlugin.NAME, SpatialFilterQParserPlugin.class,
- SpatialBoxQParserPlugin.NAME, SpatialBoxQParserPlugin.class,
- JoinQParserPlugin.NAME, JoinQParserPlugin.class,
- SurroundQParserPlugin.NAME, SurroundQParserPlugin.class,
- SwitchQParserPlugin.NAME, SwitchQParserPlugin.class,
- MaxScoreQParserPlugin.NAME, MaxScoreQParserPlugin.class,
- BlockJoinParentQParserPlugin.NAME, BlockJoinParentQParserPlugin.class,
- BlockJoinChildQParserPlugin.NAME, BlockJoinChildQParserPlugin.class,
- CollapsingQParserPlugin.NAME, CollapsingQParserPlugin.class,
- SimpleQParserPlugin.NAME, SimpleQParserPlugin.class,
- ComplexPhraseQParserPlugin.NAME, ComplexPhraseQParserPlugin.class,
- ReRankQParserPlugin.NAME, ReRankQParserPlugin.class,
- ExportQParserPlugin.NAME, ExportQParserPlugin.class,
- MLTQParserPlugin.NAME, MLTQParserPlugin.class
- };
+ public static final Map<String, Class<? extends QParserPlugin>> standardPlugins;
+
+ static {
+ HashMap<String, Class<? extends QParserPlugin>> map = new HashMap<>();
+ map.put(LuceneQParserPlugin.NAME, LuceneQParserPlugin.class);
+ map.put(OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class);
+ map.put(FunctionQParserPlugin.NAME, FunctionQParserPlugin.class);
+ map.put(PrefixQParserPlugin.NAME, PrefixQParserPlugin.class);
+ map.put(BoostQParserPlugin.NAME, BoostQParserPlugin.class);
+ map.put(DisMaxQParserPlugin.NAME, DisMaxQParserPlugin.class);
+ map.put(ExtendedDismaxQParserPlugin.NAME, ExtendedDismaxQParserPlugin.class);
+ map.put(FieldQParserPlugin.NAME, FieldQParserPlugin.class);
+ map.put(RawQParserPlugin.NAME, RawQParserPlugin.class);
+ map.put(TermQParserPlugin.NAME, TermQParserPlugin.class);
+ map.put(TermsQParserPlugin.NAME, TermsQParserPlugin.class);
+ map.put(NestedQParserPlugin.NAME, NestedQParserPlugin.class);
+ map.put(FunctionRangeQParserPlugin.NAME, FunctionRangeQParserPlugin.class);
+ map.put(SpatialFilterQParserPlugin.NAME, SpatialFilterQParserPlugin.class);
+ map.put(SpatialBoxQParserPlugin.NAME, SpatialBoxQParserPlugin.class);
+ map.put(JoinQParserPlugin.NAME, JoinQParserPlugin.class);
+ map.put(SurroundQParserPlugin.NAME, SurroundQParserPlugin.class);
+ map.put(SwitchQParserPlugin.NAME, SwitchQParserPlugin.class);
+ map.put(MaxScoreQParserPlugin.NAME, MaxScoreQParserPlugin.class);
+ map.put(BlockJoinParentQParserPlugin.NAME, BlockJoinParentQParserPlugin.class);
+ map.put(BlockJoinChildQParserPlugin.NAME, BlockJoinChildQParserPlugin.class);
+ map.put(CollapsingQParserPlugin.NAME, CollapsingQParserPlugin.class);
+ map.put(SimpleQParserPlugin.NAME, SimpleQParserPlugin.class);
+ map.put(ComplexPhraseQParserPlugin.NAME, ComplexPhraseQParserPlugin.class);
+ map.put(ReRankQParserPlugin.NAME, ReRankQParserPlugin.class);
+ map.put(ExportQParserPlugin.NAME, ExportQParserPlugin.class);
+ map.put(MLTQParserPlugin.NAME, MLTQParserPlugin.class);
+ standardPlugins = Collections.unmodifiableMap(map);
+ }
/** return a {@link QParser} */
public abstract QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req);
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java Mon Mar 9 16:29:08 2015
@@ -52,8 +52,8 @@ public class CommandOperation {
Object obj = getRootPrimitive();
return obj == def ? null : String.valueOf(obj);
}
- String s = (String) getMapVal(key);
- return s == null ? def : s;
+ Object o = getMapVal(key);
+ return o == null ? def : String.valueOf(o);
}
public Map<String, Object> getDataMap() {
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/OutputWriterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/OutputWriterTest.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/OutputWriterTest.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/OutputWriterTest.java Mon Mar 9 16:29:08 2015
@@ -19,16 +19,13 @@ package org.apache.solr;
import java.io.IOException;
import java.io.Writer;
-import java.util.List;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.PluginInfo;
-import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.PluginBag;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.QueryResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.response.XMLResponseWriter;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -94,11 +91,12 @@ public class OutputWriterTest extends So
}
public void testLazy() {
- QueryResponseWriter qrw = h.getCore().getQueryResponseWriter("useless");
- assertTrue("Should be a lazy class", qrw instanceof SolrCore.LazyQueryResponseWriterWrapper);
+ PluginBag.PluginHolder<QueryResponseWriter> qrw = h.getCore().getResponseWriters().getRegistry().get("useless");
+ assertTrue("Should be a lazy class", qrw instanceof PluginBag.LazyPluginHolder);
- qrw = h.getCore().getQueryResponseWriter("xml");
- assertTrue("Should not be a lazy class", qrw instanceof XMLResponseWriter);
+ qrw = h.getCore().getResponseWriters().getRegistry().get("xml");
+ assertTrue("Should not be a lazy class", qrw.isLoaded());
+ assertTrue("Should not be a lazy class", qrw.getClass() == PluginBag.PluginHolder.class);
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandler.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandler.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandler.java Mon Mar 9 16:29:08 2015
@@ -23,11 +23,41 @@ import java.io.IOException;
import org.apache.solr.handler.DumpRequestHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.util.plugin.SolrCoreAware;
+
+public class BlobStoreTestRequestHandler extends DumpRequestHandler implements Runnable, SolrCoreAware{
+
+ private SolrCore core;
+
+ private long version = 1;
+ private String watchedVal = null;
-public class BlobStoreTestRequestHandler extends DumpRequestHandler{
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
super.handleRequestBody(req, rsp);
rsp.add("class", this.getClass().getName());
+ rsp.add("x",watchedVal);
+ }
+
+ @Override
+ public void run() {
+ RequestParams p = core.getSolrConfig().getRequestParams();
+ RequestParams.VersionedParams v = p.getParams("watched");
+ if(v== null){
+ watchedVal = null;
+ version=-1;
+ return;
+ }
+ if(v.getVersion() != version){
+ watchedVal = v.getMap().get("x");
+ }
+ }
+
+ @Override
+ public void inform(SolrCore core) {
+ this.core = core;
+ core.addConfListener(this);
+ run();
+
}
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java Mon Mar 9 16:29:08 2015
@@ -19,7 +19,6 @@ package org.apache.solr.core;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.handler.StandardRequestHandler;
import org.apache.solr.request.SolrRequestHandler;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -49,8 +48,8 @@ public class RequestHandlersTest extends
@Test
public void testLazyLoading() {
SolrCore core = h.getCore();
- SolrRequestHandler handler = core.getRequestHandler( "lazy" );
- assertFalse( handler instanceof StandardRequestHandler );
+ PluginBag.PluginHolder<SolrRequestHandler> handler = core.getRequestHandlers().getRegistry().get("lazy");
+ assertFalse(handler.isLoaded());
assertU(adoc("id", "42",
"name", "Zapp Brannigan"));
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/TestDynamicLoading.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/TestDynamicLoading.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/TestDynamicLoading.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/TestDynamicLoading.java Mon Mar 9 16:29:08 2015
@@ -21,18 +21,19 @@ package org.apache.solr.core;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.handler.TestBlobHandler;
import org.apache.solr.util.RESTfulServerProvider;
import org.apache.solr.util.RestTestHarness;
import org.apache.solr.util.SimplePostTool;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -40,6 +41,9 @@ import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
+import static java.util.Arrays.asList;
+import static org.apache.solr.handler.TestSolrConfigHandlerCloud.compareValues;
+
public class TestDynamicLoading extends AbstractFullDistribZkTestBase {
static final Logger log = LoggerFactory.getLogger(TestDynamicLoading.class);
private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
@@ -56,6 +60,11 @@ public class TestDynamicLoading extends
}
}
+ @BeforeClass
+ public static void enableRuntimeLib() throws Exception {
+ System.setProperty("enable.runtime.lib", "true");
+ }
+
@Override
public void distribTearDown() throws Exception {
super.distribTearDown();
@@ -66,51 +75,56 @@ public class TestDynamicLoading extends
@Test
public void testDynamicLoading() throws Exception {
+ System.setProperty("enable.runtime.lib", "true");
setupHarnesses();
+
+ String blobName = "colltest";
+ boolean success = false;
+
+
+ HttpSolrClient randomClient = (HttpSolrClient) clients.get(random().nextInt(clients.size()));
+ String baseURL = randomClient.getBaseURL();
+ baseURL = baseURL.substring(0, baseURL.lastIndexOf('/'));
String payload = "{\n" +
- "'create-requesthandler' : { 'name' : '/test1', 'class': 'org.apache.solr.core.BlobStoreTestRequestHandler' , 'lib':'test','version':'1'}\n" +
+ "'add-runtimelib' : { 'name' : 'colltest' ,'version':1}\n" +
"}";
RestTestHarness client = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
+ TestSolrConfigHandler.runConfigCommand(client, "/config?wt=json", payload);
+ TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/config/overlay?wt=json",
+ null,
+ Arrays.asList("overlay", "runtimeLib", blobName, "version"),
+ 1l, 10);
+
+
+ payload = "{\n" +
+ "'create-requesthandler' : { 'name' : '/test1', 'class': 'org.apache.solr.core.BlobStoreTestRequestHandler' , 'runtimeLib' : true }\n" +
+ "}";
+
+ client = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
TestSolrConfigHandler.runConfigCommand(client,"/config?wt=json",payload);
TestSolrConfigHandler.testForResponseElement(client,
null,
"/config/overlay?wt=json",
null,
- Arrays.asList("overlay", "requestHandler", "/test1", "lib"),
- "test",10);
+ Arrays.asList("overlay", "requestHandler", "/test1", "class"),
+ "org.apache.solr.core.BlobStoreTestRequestHandler",10);
Map map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- assertNotNull(map = (Map) map.get("error"));
- assertEquals(".system collection not available", map.get("msg"));
+ assertNotNull(TestBlobHandler.getAsString(map), map = (Map) map.get("error"));
+ assertEquals(TestBlobHandler.getAsString(map), ".system collection not available", map.get("msg"));
+
- HttpSolrClient randomClient = (HttpSolrClient) clients.get(random().nextInt(clients.size()));
- String baseURL = randomClient.getBaseURL();
- baseURL = baseURL.substring(0, baseURL.lastIndexOf('/'));
TestBlobHandler.createSystemCollection(new HttpSolrClient(baseURL, randomClient.getHttpClient()));
waitForRecoveriesToFinish(".system", true);
map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- assertNotNull(map = (Map) map.get("error"));
- assertEquals("no such blob or version available: test/1", map.get("msg"));
- ByteBuffer jar = generateZip( TestDynamicLoading.class,BlobStoreTestRequestHandler.class);
- TestBlobHandler.postAndCheck(cloudClient, baseURL, jar,1);
-
- boolean success= false;
- for(int i=0;i<50;i++) {
- map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- if(BlobStoreTestRequestHandler.class.getName().equals(map.get("class"))){
- success = true;
- break;
- }
- Thread.sleep(100);
- }
- assertTrue(new String( ZkStateReader.toJSON(map) , StandardCharsets.UTF_8), success );
-
- jar = generateZip( TestDynamicLoading.class,BlobStoreTestRequestHandlerV2.class);
- TestBlobHandler.postAndCheck(cloudClient, baseURL, jar,2);
+ assertNotNull(map = (Map) map.get("error"));
+ assertEquals("full output " + TestBlobHandler.getAsString(map), "no such blob or version available: colltest/1" , map.get("msg"));
payload = " {\n" +
" 'set' : {'watched': {" +
" 'x':'X val',\n" +
@@ -129,39 +143,111 @@ public class TestDynamicLoading extends
10);
+
+
+ for(int i=0;i<100;i++) {
+ map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
+ if("X val".equals(map.get("x"))){
+ success = true;
+ break;
+ }
+ Thread.sleep(100);
+ }
+ ByteBuffer jar = null;
+
+// jar = persistZip("/tmp/runtimelibs.jar.bin", TestDynamicLoading.class, RuntimeLibReqHandler.class, RuntimeLibResponseWriter.class, RuntimeLibSearchComponent.class);
+// if(true) return;
+
+ jar = getFileContent("runtimecode/runtimelibs.jar.bin");
+ TestBlobHandler.postAndCheck(cloudClient, baseURL, blobName, jar, 1);
+
payload = "{\n" +
- "'update-requesthandler' : { 'name' : '/test1', 'class': 'org.apache.solr.core.BlobStoreTestRequestHandlerV2' , 'lib':'test','version':2}\n" +
+ "'create-requesthandler' : { 'name' : '/runtime', 'class': 'org.apache.solr.core.RuntimeLibReqHandler' , 'runtimeLib':true }," +
+ "'create-searchcomponent' : { 'name' : 'get', 'class': 'org.apache.solr.core.RuntimeLibSearchComponent' , 'runtimeLib':true }," +
+ "'create-queryResponseWriter' : { 'name' : 'json1', 'class': 'org.apache.solr.core.RuntimeLibResponseWriter' , 'runtimeLib':true }" +
"}";
+ client = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
+ TestSolrConfigHandler.runConfigCommand(client, "/config?wt=json", payload);
+
+ Map result = TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/config/overlay?wt=json",
+ null,
+ Arrays.asList("overlay", "requestHandler", "/runtime", "class"),
+ "org.apache.solr.core.RuntimeLibReqHandler", 10);
+ compareValues(result, "org.apache.solr.core.RuntimeLibResponseWriter", asList("overlay", "queryResponseWriter", "json1", "class"));
+ compareValues(result, "org.apache.solr.core.RuntimeLibSearchComponent", asList("overlay", "searchComponent", "get", "class"));
+
+ result = TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/runtime?wt=json",
+ null,
+ Arrays.asList("class"),
+ "org.apache.solr.core.RuntimeLibReqHandler", 10);
+ compareValues(result, MemClassLoader.class.getName(), asList( "loader"));
+
+ result = TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/runtime?wt=json1",
+ null,
+ Arrays.asList("wt"),
+ "org.apache.solr.core.RuntimeLibResponseWriter", 10);
+ compareValues(result, MemClassLoader.class.getName(), asList( "loader"));
+
+ result = TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/get?abc=xyz",
+ null,
+ Arrays.asList("get"),
+ "org.apache.solr.core.RuntimeLibSearchComponent", 10);
+ compareValues(result, MemClassLoader.class.getName(), asList( "loader"));
+ jar = getFileContent("runtimecode/runtimelibs_v2.jar.bin");
+ TestBlobHandler.postAndCheck(cloudClient, baseURL, blobName, jar, 2);
+ payload = "{\n" +
+ "'update-runtimelib' : { 'name' : 'colltest' ,'version':2}\n" +
+ "}";
client = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
- TestSolrConfigHandler.runConfigCommand(client,"/config?wt=json",payload);
+ TestSolrConfigHandler.runConfigCommand(client, "/config?wt=json", payload);
TestSolrConfigHandler.testForResponseElement(client,
null,
"/config/overlay?wt=json",
null,
- Arrays.asList("overlay", "requestHandler", "/test1", "version"),
- 2l,10);
+ Arrays.asList("overlay", "runtimeLib", blobName, "version"),
+ 2l, 10);
- success= false;
- for(int i=0;i<100;i++) {
- map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- if(BlobStoreTestRequestHandlerV2.class.getName().equals(map.get("class"))) {
- success = true;
- break;
- }
- Thread.sleep(100);
- }
+ result = TestSolrConfigHandler.testForResponseElement(client,
+ null,
+ "/get?abc=xyz",
+ null,
+ Arrays.asList("Version"),
+ "2", 10);
- assertTrue("New version of class is not loaded " + new String(ZkStateReader.toJSON(map), StandardCharsets.UTF_8), success);
- for(int i=0;i<100;i++) {
- map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- if("X val".equals(map.get("x"))){
- success = true;
- break;
- }
- Thread.sleep(100);
- }
+ payload = " {\n" +
+ " 'set' : {'watched': {" +
+ " 'x':'X val',\n" +
+ " 'y': 'Y val'}\n" +
+ " }\n" +
+ " }";
+
+ TestSolrConfigHandler.runConfigCommand(client,"/config/params?wt=json",payload);
+ TestSolrConfigHandler.testForResponseElement(
+ client,
+ null,
+ "/config/params?wt=json",
+ cloudClient,
+ Arrays.asList("response", "params", "watched", "x"),
+ "X val",
+ 10);
+ result = TestSolrConfigHandler.testForResponseElement(
+ client,
+ null,
+ "/test1?wt=json",
+ cloudClient,
+ Arrays.asList("x"),
+ "X val",
+ 10);
payload = " {\n" +
" 'set' : {'watched': {" +
@@ -171,17 +257,33 @@ public class TestDynamicLoading extends
" }";
TestSolrConfigHandler.runConfigCommand(client,"/config/params?wt=json",payload);
- for(int i=0;i<50;i++) {
- map = TestSolrConfigHandler.getRespMap("/test1?wt=json", client);
- if("X val changed".equals(map.get("x"))){
- success = true;
- break;
- }
- Thread.sleep(100);
- }
- assertTrue("listener did not get triggered" + new String(ZkStateReader.toJSON(map), StandardCharsets.UTF_8), success);
+ result = TestSolrConfigHandler.testForResponseElement(
+ client,
+ null,
+ "/test1?wt=json",
+ cloudClient,
+ Arrays.asList("x"),
+ "X val changed",
+ 10);
+ }
+ private ByteBuffer getFileContent(String f) throws IOException {
+ ByteBuffer jar;
+ try (FileInputStream fis = new FileInputStream(getFile(f))) {
+ byte[] buf = new byte[fis.available()];
+ fis.read(buf);
+ jar = ByteBuffer.wrap(buf);
+ }
+ return jar;
+ }
+ public static ByteBuffer persistZip(String loc, Class... classes) throws IOException {
+ ByteBuffer jar = generateZip(classes);
+ try (FileOutputStream fos = new FileOutputStream(loc)){
+ fos.write(jar.array(), 0, jar.limit());
+ fos.flush();
+ }
+ return jar;
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java?rev=1665295&r1=1665294&r2=1665295&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java Mon Mar 9 16:29:08 2015
@@ -86,8 +86,9 @@ public class TestBlobHandler extends Abs
for (int i = 0; i < bytarr.length; i++) bytarr[i]= (byte) (i % 127);
byte[] bytarr2 = new byte[2048];
for (int i = 0; i < bytarr2.length; i++) bytarr2[i]= (byte) (i % 127);
- postAndCheck(cloudClient, baseUrl, ByteBuffer.wrap( bytarr), 1);
- postAndCheck(cloudClient, baseUrl, ByteBuffer.wrap( bytarr2), 2);
+ String blobName = "test";
+ postAndCheck(cloudClient, baseUrl, blobName, ByteBuffer.wrap(bytarr), 1);
+ postAndCheck(cloudClient, baseUrl, blobName, ByteBuffer.wrap(bytarr2), 2);
url = baseUrl + "/.system/blob/test/1";
map = TestSolrConfigHandlerConcurrent.getAsMap(url,cloudClient);
@@ -123,8 +124,8 @@ public class TestBlobHandler extends Abs
DirectUpdateHandler2.commitOnClose = true;
}
- public static void postAndCheck(CloudSolrClient cloudClient, String baseUrl, ByteBuffer bytes, int count) throws Exception {
- postData(cloudClient, baseUrl, bytes);
+ public static void postAndCheck(CloudSolrClient cloudClient, String baseUrl, String blobName, ByteBuffer bytes, int count) throws Exception {
+ postData(cloudClient, baseUrl, blobName, bytes);
String url;
Map map = null;
@@ -132,7 +133,7 @@ public class TestBlobHandler extends Abs
long start = System.currentTimeMillis();
int i=0;
for(;i<150;i++) {//15 secs
- url = baseUrl + "/.system/blob/test";
+ url = baseUrl + "/.system/blob/" + blobName;
map = TestSolrConfigHandlerConcurrent.getAsMap(url, cloudClient);
String numFound = String.valueOf(ConfigOverlay.getObjectByPath(map, false, Arrays.asList("response", "numFound")));
if(!(""+count).equals(numFound)) {
@@ -171,12 +172,12 @@ public class TestBlobHandler extends Abs
}
- public static void postData(CloudSolrClient cloudClient, String baseUrl, ByteBuffer bytarr) throws IOException {
+ public static void postData(CloudSolrClient cloudClient, String baseUrl, String blobName, ByteBuffer bytarr) throws IOException {
HttpPost httpPost = null;
HttpEntity entity;
String response = null;
try {
- httpPost = new HttpPost(baseUrl+"/.system/blob/test");
+ httpPost = new HttpPost(baseUrl + "/.system/blob/" + blobName);
httpPost.setHeader("Content-Type","application/octet-stream");
httpPost.setEntity(new ByteArrayEntity(bytarr.array(), bytarr.arrayOffset(), bytarr.limit()));
entity = cloudClient.getLbClient().getHttpClient().execute(httpPost).getEntity();