コード例 #1
0
  /**
   * For example:
   *
   * <p>String json = solr.request( "/select?qt=dismax&wt=json&q=...", null ); String xml =
   * solr.request( "/update", "&lt;add><doc><field ..." );
   */
  public String request(String pathAndParams, String body) throws Exception {
    String path = null;
    SolrParams params = null;
    int idx = pathAndParams.indexOf('?');
    if (idx > 0) {
      path = pathAndParams.substring(0, idx);
      params = SolrRequestParsers.parseQueryString(pathAndParams.substring(idx + 1));
    } else {
      path = pathAndParams;
      params = new MapSolrParams(new HashMap<String, String>());
    }

    // Extract the handler from the path or params
    SolrRequestHandler handler = core.getRequestHandler(path);
    if (handler == null) {
      if ("/select".equals(path) || "/select/".equalsIgnoreCase(path)) {
        String qt = params.get(CommonParams.QT);
        handler = core.getRequestHandler(qt);
        if (handler == null) {
          throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "unknown handler: " + qt);
        }
      }
    }
    if (handler == null) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "unknown handler: " + path);
    }

    // Make a stream for the 'body' content
    List<ContentStream> streams = new ArrayList<ContentStream>(1);
    if (body != null && body.length() > 0) {
      streams.add(new ContentStreamBase.StringStream(body));
    }

    SolrQueryRequest req = null;
    try {
      req = parser.buildRequestFrom(core, params, streams);
      SolrQueryResponse rsp = new SolrQueryResponse();
      core.execute(handler, req, rsp);
      if (rsp.getException() != null) {
        throw rsp.getException();
      }

      // Now write it out
      QueryResponseWriter responseWriter = core.getQueryResponseWriter(req);
      StringWriter out = new StringWriter();
      responseWriter.write(out, req, rsp);
      return out.toString();
    } finally {
      if (req != null) {
        req.close();
      }
    }
  }
コード例 #2
0
  @Test
  public void testStreamURL() throws Exception {
    boolean ok = false;
    String url = "http://www.apache.org/dist/lucene/solr/";
    String txt = null;
    try {
      URLConnection connection = new URL(url).openConnection();
      connection.setConnectTimeout(5000);
      connection.setReadTimeout(5000);
      connection.connect();
      txt = IOUtils.toString(connection.getInputStream());
    } catch (Exception ex) {
      // TODO - should it fail/skip?
      fail("this test only works if you have a network connection.");
      return;
    }

    SolrCore core = h.getCore();

    Map<String, String[]> args = new HashMap<String, String[]>();
    args.put(CommonParams.STREAM_URL, new String[] {url});

    // Make sure it got a single stream in and out ok
    List<ContentStream> streams = new ArrayList<ContentStream>();
    parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
    assertEquals(1, streams.size());
    assertEquals(txt, IOUtils.toString(streams.get(0).getStream()));
  }
コード例 #3
0
  /** Extract handler from the URL path if not set. This returns true if the action is set. */
  private void extractHandlerFromURLPath(SolrRequestParsers parser) throws Exception {
    if (handler == null && path.length() > 1) { // don't match "" or "/" as valid path
      handler = core.getRequestHandler(path);

      if (handler == null) {
        // may be a restlet path
        // Handle /schema/* paths via Restlet
        if (path.equals("/schema") || path.startsWith("/schema/")) {
          solrReq = parser.parse(core, path, req);
          SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));
          if (path.equals(req.getServletPath())) {
            // avoid endless loop - pass through to Restlet via webapp
            action = PASSTHROUGH;
            return;
          } else {
            // forward rewritten URI (without path prefix and core/collection name) to Restlet
            action = FORWARD;
            return;
          }
        }
      }
      // no handler yet but allowed to handle select; let's check

      if (handler == null && parser.isHandleSelect()) {
        if ("/select".equals(path) || "/select/".equals(path)) {
          solrReq = parser.parse(core, path, req);
          invalidStates = checkStateIsValid(solrReq.getParams().get(CloudSolrClient.STATE_VERSION));
          String qt = solrReq.getParams().get(CommonParams.QT);
          handler = core.getRequestHandler(qt);
          if (handler == null) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "unknown handler: " + qt);
          }
          if (qt != null && qt.startsWith("/") && (handler instanceof ContentStreamHandlerBase)) {
            // For security reasons it's a bad idea to allow a leading '/', ex: /select?qt=/update
            // see SOLR-3161
            // There was no restriction from Solr 1.4 thru 3.5 and it's not supported for update
            // handlers.
            throw new SolrException(
                SolrException.ErrorCode.BAD_REQUEST,
                "Invalid Request Handler ('qt').  Do not use /select to access: " + qt);
          }
        }
      }
    }
  }
コード例 #4
0
  @Test
  public void testStreamBody() throws Exception {
    String body1 = "AMANAPLANPANAMA";
    String body2 = "qwertasdfgzxcvb";
    String body3 = "1234567890";

    SolrCore core = h.getCore();

    Map<String, String[]> args = new HashMap<String, String[]>();
    args.put(CommonParams.STREAM_BODY, new String[] {body1});

    // Make sure it got a single stream in and out ok
    List<ContentStream> streams = new ArrayList<ContentStream>();
    parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
    assertEquals(1, streams.size());
    assertEquals(body1, IOUtils.toString(streams.get(0).getStream()));

    // Now add three and make sure they come out ok
    streams = new ArrayList<ContentStream>();
    args.put(CommonParams.STREAM_BODY, new String[] {body1, body2, body3});
    parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
    assertEquals(3, streams.size());
    ArrayList<String> input = new ArrayList<String>();
    ArrayList<String> output = new ArrayList<String>();
    input.add(body1);
    input.add(body2);
    input.add(body3);
    output.add(IOUtils.toString(streams.get(0).getStream()));
    output.add(IOUtils.toString(streams.get(1).getStream()));
    output.add(IOUtils.toString(streams.get(2).getStream()));
    // sort them so the output is consistent
    Collections.sort(input);
    Collections.sort(output);
    assertEquals(input.toString(), output.toString());

    // set the contentType and make sure tat gets set
    String ctype = "text/xxx";
    streams = new ArrayList<ContentStream>();
    args.put(CommonParams.STREAM_CONTENTTYPE, new String[] {ctype});
    parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
    for (ContentStream s : streams) {
      assertEquals(ctype, s.getContentType());
    }
  }
コード例 #5
0
 public HttpSolrCall(
     SolrDispatchFilter solrDispatchFilter,
     CoreContainer cores,
     HttpServletRequest request,
     HttpServletResponse response,
     boolean retry) {
   this.solrDispatchFilter = solrDispatchFilter;
   this.cores = cores;
   this.req = request;
   this.response = response;
   this.retry = retry;
   this.requestType = RequestType.UNKNOWN;
   queryParams = SolrRequestParsers.parseQueryString(req.getQueryString());
 }
コード例 #6
0
  @Test
  public void testUrlParamParsing() {
    String[][] teststr =
        new String[][] {
          {"this is simple", "this%20is%20simple"},
          {"this is simple", "this+is+simple"},
          {"\u00FC", "%C3%BC"}, // lower-case "u" with diaeresis/umlaut
          {"\u0026", "%26"}, // &
          {"\u20AC", "%E2%82%AC"} // euro
        };

    for (String[] tst : teststr) {
      MultiMapSolrParams params = SolrRequestParsers.parseQueryString("val=" + tst[1]);
      assertEquals(tst[0], params.get("val"));
    }
  }
コード例 #7
0
 protected void sendError(Throwable ex) throws IOException {
   Exception exp = null;
   SolrCore localCore = null;
   try {
     SolrQueryResponse solrResp = new SolrQueryResponse();
     if (ex instanceof Exception) {
       solrResp.setException((Exception) ex);
     } else {
       solrResp.setException(new RuntimeException(ex));
     }
     localCore = core;
     if (solrReq == null) {
       final SolrParams solrParams;
       if (req != null) {
         // use GET parameters if available:
         solrParams = SolrRequestParsers.parseQueryString(req.getQueryString());
       } else {
         // we have no params at all, use empty ones:
         solrParams = new MapSolrParams(Collections.<String, String>emptyMap());
       }
       solrReq = new SolrQueryRequestBase(core, solrParams) {};
     }
     QueryResponseWriter writer = core.getQueryResponseWriter(solrReq);
     writeResponse(solrResp, writer, Method.GET);
   } catch (Exception e) { // This error really does not matter
     exp = e;
   } finally {
     try {
       if (exp != null) {
         SimpleOrderedMap info = new SimpleOrderedMap();
         int code = ResponseUtils.getErrorInfo(ex, info, log);
         sendError(code, info.toString());
       }
     } finally {
       if (core == null && localCore != null) {
         localCore.close();
       }
     }
   }
 }
コード例 #8
0
  private void init() throws Exception {
    // The states of client that is invalid in this request
    Aliases aliases = null;
    String corename = "";
    String origCorename = null;
    // set a request timer which can be reused by requests if needed
    req.setAttribute(SolrRequestParsers.REQUEST_TIMER_SERVLET_ATTRIBUTE, new RTimerTree());
    // put the core container in request attribute
    req.setAttribute("org.apache.solr.CoreContainer", cores);
    path = req.getServletPath();
    if (req.getPathInfo() != null) {
      // this lets you handle /update/commit when /update is a servlet
      path += req.getPathInfo();
    }
    // check for management path
    String alternate = cores.getManagementPath();
    if (alternate != null && path.startsWith(alternate)) {
      path = path.substring(0, alternate.length());
    }
    // unused feature ?
    int idx = path.indexOf(':');
    if (idx > 0) {
      // save the portion after the ':' for a 'handler' path parameter
      path = path.substring(0, idx);
    }

    boolean usingAliases = false;

    // Check for container handlers
    handler = cores.getRequestHandler(path);
    if (handler != null) {
      solrReq = SolrRequestParsers.DEFAULT.parse(null, path, req);
      solrReq.getContext().put(CoreContainer.class.getName(), cores);
      requestType = RequestType.ADMIN;
      action = ADMIN;
      return;
    } else {
      // otherwise, we should find a core from the path
      idx = path.indexOf("/", 1);
      if (idx > 1) {
        // try to get the corename as a request parameter first
        corename = path.substring(1, idx);

        // look at aliases
        if (cores.isZooKeeperAware()) {
          origCorename = corename;
          ZkStateReader reader = cores.getZkController().getZkStateReader();
          aliases = reader.getAliases();
          if (aliases != null && aliases.collectionAliasSize() > 0) {
            usingAliases = true;
            String alias = aliases.getCollectionAlias(corename);
            if (alias != null) {
              collectionsList = StrUtils.splitSmart(alias, ",", true);
              corename = collectionsList.get(0);
            }
          }
        }

        core = cores.getCore(corename);
        if (core != null) {
          path = path.substring(idx);
        } else if (cores.isCoreLoading(
            corename)) { // extra mem barriers, so don't look at this before trying to get core
          throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "SolrCore is loading");
        } else {
          // the core may have just finished loading
          core = cores.getCore(corename);
          if (core != null) {
            path = path.substring(idx);
          }
        }
      }
      if (core == null) {
        if (!cores.isZooKeeperAware()) {
          core = cores.getCore("");
        }
      }
    }

    if (core == null && cores.isZooKeeperAware()) {
      // we couldn't find the core - lets make sure a collection was not specified instead
      core = getCoreByCollection(corename);
      if (core != null) {
        // we found a core, update the path
        path = path.substring(idx);
        if (collectionsList == null) collectionsList = new ArrayList<>();
        collectionsList.add(corename);
      }

      // if we couldn't find it locally, look on other nodes
      extractRemotePath(corename, origCorename, idx);
      if (action != null) return;
    }

    // With a valid core...
    if (core != null) {
      MDCLoggingContext.setCore(core);
      config = core.getSolrConfig();
      // get or create/cache the parser for the core
      SolrRequestParsers parser = config.getRequestParsers();

      // Determine the handler from the url path if not set
      // (we might already have selected the cores handler)
      extractHandlerFromURLPath(parser);
      if (action != null) return;

      // With a valid handler and a valid core...
      if (handler != null) {
        // if not a /select, create the request
        if (solrReq == null) {
          solrReq = parser.parse(core, path, req);
        }

        if (usingAliases) {
          processAliases(aliases, collectionsList);
        }

        action = PROCESS;
        return; // we are done with a valid handler
      }
    }
    log.debug("no handler or core retrieved for " + path + ", follow through...");

    action = PASSTHROUGH;
  }