content: /**
   * 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
   * <p>
   * http://www.apache.org/licenses/LICENSE-2.0
   * <p>
   * 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.batch;
  
  import monty.solr.util.MontySolrQueryTestCase;
  import monty.solr.util.MontySolrSetup;
  import monty.solr.util.SolrTestSetup;
  import org.adsabs.solr.AdsConfig.F;
  import org.apache.lucene.tests.util.LuceneTestCase.SuppressCodecs;
  import org.apache.solr.common.SolrException;
  import org.apache.solr.common.SolrException.ErrorCode;
  import org.apache.solr.common.params.ModifiableSolrParams;
  import org.apache.solr.common.params.SolrParams;
  import org.apache.solr.common.util.ContentStream;
  import org.apache.solr.common.util.ContentStreamBase;
  import org.apache.solr.common.util.NamedList;
  import org.apache.solr.core.SolrCore;
  import org.apache.solr.request.LocalSolrQueryRequest;
  import org.apache.solr.request.SolrQueryRequest;
  import org.apache.solr.response.QueryResponseWriter;
  import org.apache.solr.response.SolrQueryResponse;
  import org.junit.BeforeClass;
  
  import java.io.*;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Scanner;
  
  @SuppressCodecs({"Lucene3x", "SimpleText"})
  public class TestBatchRequestHandler extends MontySolrQueryTestCase {
  
      private File generatedTransliterations;
      private BatchHandler handler;
  
      @BeforeClass
      public static void beforeClass() throws Exception {
          schemaString = "schema.xml";
  
          configString = "solrconfig.xml";
  
          SolrTestSetup.initCore(configString, schemaString);
      }
  
  
      public void test() throws Exception {
  
          // now index some data
          assertU(adoc(F.ID, "1", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk,", F.TYPE_ADS_TEXT, "what ever comes under"));
          assertU(adoc(F.ID, "2", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, M.", F.TYPE_ADS_TEXT, "my head is not what"));
          assertU(adoc(F.ID, "3", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, Marel", F.TYPE_ADS_TEXT, "goes in yours"));
          assertU(adoc(F.ID, "4", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, Molja", F.TYPE_ADS_TEXT, "the old warrior angels of angels"));
          assertU(adoc(F.ID, "5", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, Molja Karel", F.TYPE_ADS_TEXT, "great war, with horses"));
          assertU(commit());
  
          assertU(adoc(F.ID, "7", F.BIBCODE, "xxxxxxxxxxxx7", F.AUTHOR, "Adamčuk, Molja K", F.TYPE_ADS_TEXT, "and heavy horses"));
          assertU(adoc(F.ID, "8", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, M K", F.TYPE_ADS_TEXT, "cutting down machine and by the machine"));
          assertU(adoc(F.ID, "9", F.BIBCODE, "xxxxxxxxxxxx9", F.AUTHOR, "Adamčuk, Karel Molja", F.TYPE_ADS_TEXT, "guns, from different angels"));
          assertU(adoc(F.ID, "10", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, Karel M", F.TYPE_ADS_TEXT, "but still, British insisted"));
          assertU(adoc(F.ID, "11", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "Adamčuk, K Molja", F.TYPE_ADS_TEXT, "as well as Germans did"));
          assertU(adoc(F.ID, "12", F.BIBCODE, "xxxxxxxxxxxxx", F.AUTHOR, "ǎguşan, Adrian, , Dr", F.TYPE_ADS_TEXT, "words are too weak..."));
          assertU(commit());
  
  
          //if (true) {
          String workDir = createTempDir() + "/batch-handler";
          handler = new BatchHandler();
          NamedList<Object> defaults = new NamedList<Object>();
          defaults.add("allowed", ".*");
          defaults.add("asynchronous", true);
          defaults.add("workdir", workDir);
  
          NamedList<Object> providers = new NamedList<Object>();
  	    /*
  	    providers.add("dump-index", "org.apache.solr.handler.batch.BatchProviderDumpIndexFields");
  	    providers.add("dump-index-use-bibcodes", "org.apache.solr.handler.batch.BatchProviderDumpBibcodes");
  	    providers.add("dump-freqs", "org.apache.solr.handler.batch.BatchProviderDumpTermFreqs");
  	    providers.add("dump-docs", "org.apache.solr.handler.batch.BatchProviderDumpIndex");
  	    providers.add("dump-citation-index", "org.apache.solr.handler.batch.BatchProviderDumpCitationCache");
  	    providers.add("find-freq-phrases", "org.apache.solr.handler.batch.BatchProviderFindWordGroups");
  	    */
          providers.add("_test-params", "org.apache.solr.handler.batch.TestBatchRequestHandler$TestProvider");
          providers.add("_fail", "org.apache.solr.handler.batch.TestBatchRequestHandler$TestProviderFail");
  
          NamedList<Object> nl = new NamedList<Object>();
          nl.add("defaults", defaults);
          nl.add("providers", providers);
          handler.init(nl); // default
          //}
          //else {
          //	handler = (BatchHandler) h.getCore().getRequestHandler("/batch");
          //}
          //handler = (BatchHandler) h.getCore().getRequestHandler("/batch");
  
          //while (true) {
  
          // ========================================
  
  
          String jobid;
  
          jobid = run(req("command", "_test-params",
                          "q", "{!aqp} lang:(german OR english) AND *:*",
                          "fields", "bibcode,title,author"),
                  "foo\nzooo\nščř");
  
  
          BatchHandlerRequestQueue thisQueue = queue.remove(0);
          SolrParams thisParams = params.remove(0);
  
          assertEquals("{!aqp} lang:(german OR english) AND *:*", thisParams.get("q"));
          assertEquals(true, thisParams.getBool("asynchronous"));
          assertEquals(workDir, thisParams.get("workdir"));
          assertEquals("bibcode,title,author", thisParams.get("fields"));
          assertEquals(jobid, thisParams.get("jobid"));
          assertEquals("foo\nzooo\nščř", thisParams.get("#data"));
  
          assert !thisQueue.isJobidFailed(jobid);
          assert thisQueue.isJobidFinished(jobid);
          assert thisQueue.isJobidRegistered(jobid);
          assert !thisQueue.isJobidRunning(jobid);
  
          String data = getResponse(req("command", "get-results", "jobid", jobid));
          assert data.contains("test-handler jobid:" + jobid);
  
          // ========================================
  
          // make it fail
  
          jobid = run(req("command", "_fail",
                  "q", "{!aqp} lang:(german OR english) AND *:*",
                  "fields", "bibcode,title,author"));
          data = getResponse(req("command", "status",
                  "jobid", jobid, "wt", "json", "indent", "true"));
  
          assert thisQueue.isJobidFailed(jobid);
          assert !thisQueue.isJobidFinished(jobid);
          assert thisQueue.isJobidRegistered(jobid);
          assert !thisQueue.isJobidRunning(jobid);
  
          assert data.contains("Woooot!");
          assert data.contains("org.apache.solr.handler.batch.TestBatchRequestHandler$TestProviderFail.run");
  
  
      }
  
  
      private String getResponse(SolrQueryRequest req) throws IOException, InterruptedException {
          SolrQueryResponse rsp = new SolrQueryResponse();
          try {
              h.getCore().execute(handler, req, rsp);
              while (handler.isBusy()) {
                  Thread.sleep(100);
              }
  
              StringWriter sw = new StringWriter(32000);
              QueryResponseWriter responseWriter = h.getCore().getQueryResponseWriter(req);
              responseWriter.write(sw, req, rsp);
              return sw.toString();
          } finally {
              req.close();
          }
      }
  
      private String run(SolrQueryRequest req) throws InterruptedException {
          return run(req, null);
      }
  
      private String run(SolrQueryRequest req, String data) throws InterruptedException {
          SolrQueryResponse rsp = new SolrQueryResponse();
          try {
              SolrCore core = h.getCore();
              core.execute(handler, req, rsp);
              req.close();
  
              String jobid = (String) rsp.getValues().get("jobid");
              assert jobid != null;
  
              if (data != null) {
                  // now send data to be used for dumping
                  req = req("command", "receive-data", "jobid", jobid);
                  rsp = new SolrQueryResponse();
                  List<ContentStream> cs = new ArrayList<ContentStream>(1);
                  ContentStreamBase f = new ContentStreamBase.StringStream(data);
                  cs.add(f);
                  ((LocalSolrQueryRequest) req).setContentStreams(cs);
                  core.execute(handler, req, rsp);
                  while (handler.isBusy()) {
                      Thread.sleep(100);
                  }
                  req.close();
              }
  
  
              req = req("command", "start");
              rsp = new SolrQueryResponse();
              core.execute(handler, req, rsp);
              while (handler.isBusy()) {
                  Thread.sleep(100);
              }
              req.close();
              return jobid;
          } finally {
              req.close();
          }
      }
  
      private void checkFile(String... expected) throws IOException {
          List<String> lines = h.getCore().getResourceLoader().getLines(generatedTransliterations.getAbsolutePath());
          for (String t : expected) {
              if (t.charAt(0) == '!') {
                  assertFalse("Present: " + t, lines.contains(t.substring(1)));
              } else {
                  assertTrue("Missing: " + t, lines.contains(t));
              }
          }
      }
  
  
      private static final List<BatchHandlerRequestQueue> queue = new ArrayList<BatchHandlerRequestQueue>();
      private static final List<SolrParams> params = new ArrayList<SolrParams>();
  
      public static class TestProvider extends BatchProvider {
  
          @Override
          public void run(SolrQueryRequest locReq, BatchHandlerRequestQueue q)
                  throws Exception {
              ModifiableSolrParams pars = new ModifiableSolrParams(locReq.getParams());
  
              String jobid = pars.get("jobid");
              String workDir = pars.get("#workdir");
  
              File input = new File(workDir + "/" + jobid + ".input");
              if (input.canRead()) {
                  pars.set("#file", input.toString());
                  pars.set("#data", new Scanner(input, "UTF-8").useDelimiter("\\A").next());
  
                  File jobFile = new File(workDir + "/" + jobid);
                  BufferedWriter out = new BufferedWriter(new FileWriter(jobFile), 1024 * 256);
                  out.write("test-handler jobid:" + jobid);
                  out.close();
              }
  
              params.add(pars);
              queue.add(q);
          }
  
          @Override
          public String getDescription() {
              return "Test provider";
          }
  
      }
  
      public static class TestProviderFail extends BatchProvider {
  
          @Override
          public void run(SolrQueryRequest locReq, BatchHandlerRequestQueue q)
                  throws Exception {
              throw new SolrException(ErrorCode.BAD_REQUEST, "Woooot!");
          }
  
          @Override
          public String getDescription() {
              return "Failing provider";
          }
  
      }
  
      // Uniquely for Junit 3
      public static junit.framework.Test suite() {
          return new junit.framework.JUnit4TestAdapter(TestBatchRequestHandler.class);
      }
  }
  