/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.solr.handler; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrInfoMBean; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.search.DocSet; import org.apache.solr.util.SolrPluginUtils; import org.apache.lucene.queryParser.ParseException; import java.net.URL; /** * */ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfoMBean { // statistics // TODO: should we bother synchronizing these, or is an off-by-one error // acceptable every million requests or so? volatile long numRequests; volatile long numErrors; volatile long numTimeouts; protected NamedList initArgs = null; protected SolrParams defaults; protected SolrParams appends; protected SolrParams invariants; volatile long totalTime = 0; long handlerStart = System.currentTimeMillis(); protected boolean httpCaching = true; /** * Initializes the {@link org.apache.solr.request.SolrRequestHandler} by creating three {@link org.apache.solr.common.params.SolrParams} named. * <table border="1"> * <tr><th>Name</th><th>Description</th></tr> * <tr><td>defaults</td><td>Contains all of the named arguments contained within the list element named "defaults".</td></tr> * <tr><td>appends</td><td>Contains all of the named arguments contained within the list element named "appends".</td></tr> * <tr><td>invariants</td><td>Contains all of the named arguments contained within the list element named "invariants".</td></tr> * </table> * * Example: * <pre> * <lst name="defaults"> * <str name="echoParams">explicit</str> * <str name="qf">text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0</str> * <str name="mm">2<-1 5<-2 6<90%</str> * <str name="bq">incubationdate_dt:[* TO NOW/DAY-1MONTH]^2.2</str> * </lst> * <lst name="appends"> * <str name="fq">inStock:true</str> * </lst> * * <lst name="invariants"> * <str name="facet.field">cat</str> * <str name="facet.field">manu_exact</str> * <str name="facet.query">price:[* TO 500]</str> * <str name="facet.query">price:[500 TO *]</str> * </lst> * </pre> * * * @param args The {@link org.apache.solr.common.util.NamedList} to initialize from * * @see #handleRequest(org.apache.solr.request.SolrQueryRequest, org.apache.solr.response.SolrQueryResponse) * @see #handleRequestBody(org.apache.solr.request.SolrQueryRequest, org.apache.solr.response.SolrQueryResponse) * @see org.apache.solr.util.SolrPluginUtils#setDefaults(org.apache.solr.request.SolrQueryRequest, org.apache.solr.common.params.SolrParams, org.apache.solr.common.params.SolrParams, org.apache.solr.common.params.SolrParams) * @see SolrParams#toSolrParams(org.apache.solr.common.util.NamedList) * * See also the example solrconfig.xml located in the Solr codebase (example/solr/conf). */ public void init(NamedList args) { initArgs = args; // Copied from StandardRequestHandler if( args != null ) { Object o = args.get("defaults"); if (o != null && o instanceof NamedList) { defaults = SolrParams.toSolrParams((NamedList)o); } o = args.get("appends"); if (o != null && o instanceof NamedList) { appends = SolrParams.toSolrParams((NamedList)o); } o = args.get("invariants"); if (o != null && o instanceof NamedList) { invariants = SolrParams.toSolrParams((NamedList)o); } } if (initArgs != null) { Object caching = initArgs.get("httpCaching"); httpCaching = caching != null ? Boolean.parseBoolean(caching.toString()) : true; } } public NamedList getInitArgs() { return initArgs; } public abstract void handleRequestBody( SolrQueryRequest req, SolrQueryResponse rsp ) throws Exception; public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp) { numRequests++; try { SolrPluginUtils.setDefaults(req,defaults,appends,invariants); rsp.setHttpCaching(httpCaching); handleRequestBody( req, rsp ); // count timeouts NamedList header = rsp.getResponseHeader(); if(header != null) { Object partialResults = header.get("partialResults"); boolean timedOut = partialResults == null ? false : (Boolean)partialResults; if( timedOut ) { numTimeouts++; rsp.setHttpCaching(false); } } } catch (Exception e) { SolrException.log(SolrCore.log,e); if (e instanceof ParseException) { e = new SolrException(SolrException.ErrorCode.BAD_REQUEST, e); } rsp.setException(e); numErrors++; } totalTime += rsp.getEndTime() - req.getStartTime(); } //////////////////////// SolrInfoMBeans methods ////////////////////// public String getName() { return this.getClass().getName(); } public abstract String getDescription(); public abstract String getSourceId(); public abstract String getSource(); public abstract String getVersion(); public Category getCategory() { return Category.QUERYHANDLER; } public URL[] getDocs() { return null; // this can be overridden, but not required } public NamedList getStatistics() { NamedList lst = new SimpleOrderedMap(); lst.add("handlerStart",handlerStart); lst.add("requests", numRequests); lst.add("errors", numErrors); lst.add("timeouts", numTimeouts); lst.add("totalTime",totalTime); lst.add("avgTimePerRequest", (float) totalTime / (float) this.numRequests); lst.add("avgRequestsPerSecond", (float) numRequests*1000 / (float)(System.currentTimeMillis()-handlerStart)); return lst; } }