/* * 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.update.processor; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.StringJoiner; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.request.LocalSolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.update.AddUpdateCommand; import org.junit.BeforeClass; /** * test class for @see AtomicUpdateProcessorFactory */ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 { @BeforeClass public static void beforeClass() throws Exception { System.setProperty("enable.update.log","true"); initCore("solrconfig.xml", "schema.xml"); } public void testWrongAtomicOpPassed() throws Exception { AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), new ModifiableSolrParams() .add("processor", "Atomic") .add("Atomic.cat", "delete") .add("commit","true") )); try { AtomicUpdateProcessorFactory factory = new AtomicUpdateProcessorFactory(); factory.inform(h.getCore()); factory.getInstance(cmd.getReq(), new SolrQueryResponse(), null).processAdd(cmd); } catch (SolrException e) { assertEquals("Unexpected param(s) for AtomicUpdateProcessor, invalid atomic op passed: 'delete'", e.getMessage()); } } public void testNoUniqueIdPassed() throws Exception { //TODO AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), new ModifiableSolrParams() .add("processor", "Atomic") .add("Atomic.cat", "add") .add("commit","true") )); cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc.addField("title", 1); try { AtomicUpdateProcessorFactory factory = new AtomicUpdateProcessorFactory(); factory.inform(h.getCore()); factory.getInstance(cmd.getReq(), new SolrQueryResponse(), null).processAdd(cmd); } catch (SolrException e) { assertEquals("Document passed with no unique field: 'id'", e.getMessage()); } } public void testBasics() throws Exception { AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), new ModifiableSolrParams() .add("processor", "Atomic") .add("Atomic.cat", "add") .add("Atomic.title", "set") .add("Atomic.count_i", "set") .add("Atomic.name_s", "set") .add("Atomic.multiDefault", "set") .add("commit","true") )); cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc.addField("id", 1); cmd.solrDoc.addField("cat", "human"); cmd.solrDoc.addField("title", "Mr"); cmd.solrDoc.addField("count_i", 20); cmd.solrDoc.addField("name_s", "Virat"); cmd.solrDoc.addField("multiDefault", "Delhi"); AtomicUpdateProcessorFactory factory = new AtomicUpdateProcessorFactory(); factory.inform(h.getCore()); factory.getInstance(cmd.getReq(), new SolrQueryResponse(), new DistributedUpdateProcessor(cmd.getReq(), new SolrQueryResponse(), new RunUpdateProcessor(cmd.getReq(), null))).processAdd(cmd); assertU(commit()); assertQ("Check the total number of docs", req("q", "id:1") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "cat:human") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "title:Mr") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "count_i:20") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "name_s:Virat") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "multiDefault:Delhi") , "//result[@numFound=1]"); cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), new ModifiableSolrParams() .add("processor", "Atomic") .add("Atomic.cat", "add") .add("Atomic.title", "set") .add("Atomic.count_i", "inc") .add("Atomic.name_s", "remove") .add("Atomic.multiDefault", "removeregex") .add("commit","true") )); cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc.addField("id", 1); cmd.solrDoc.addField("cat", "animal"); cmd.solrDoc.addField("title", "Dr"); cmd.solrDoc.addField("count_i", 20); cmd.solrDoc.addField("name_s", "Virat"); cmd.solrDoc.addField("multiDefault", ".elh."); factory = new AtomicUpdateProcessorFactory(); factory.inform(h.getCore()); factory.getInstance(cmd.getReq(), new SolrQueryResponse(), new DistributedUpdateProcessor(cmd.getReq(), new SolrQueryResponse(), new RunUpdateProcessor(cmd.getReq(), null))).processAdd(cmd); assertU(commit()); assertQ("Check the total number of docs", req("q", "id:1") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "cat:human") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "cat:animal") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "title:Mr") , "//result[@numFound=0]"); assertQ("Check the total number of docs", req("q", "title:Dr") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "count_i:20") , "//result[@numFound=0]"); assertQ("Check the total number of docs", req("q", "count_i:40") , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "name_s:Virat") , "//result[@numFound=0]"); assertQ("Check the total number of docs", req("q", "multiDefault:Delhi") , "//result[@numFound=0]"); } public void testMultipleThreads() throws Exception { clearIndex(); String[] strings = new String[5]; for (int i=0; i<5; i++) { strings[i] = generateRandomString(); } List<Thread> threads = new ArrayList<>(100); int finalCount = 0; //int_i for (int i = 0; i < 100; i++) { int index = random().nextInt(5); Thread t = new Thread() { @Override public void run() { AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), new ModifiableSolrParams() .add("processor", "Atomic") .add("Atomic.cat", "add") .add("Atomic.int_i", "inc") .add("commit","true") )); cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc.addField("id", 10); //hardcoded id=2 cmd.solrDoc.addField("cat", strings[index]); cmd.solrDoc.addField("int_i", index); try { AtomicUpdateProcessorFactory factory = new AtomicUpdateProcessorFactory(); factory.inform(h.getCore()); factory.getInstance(cmd.getReq(), new SolrQueryResponse(), new DistributedUpdateProcessor(cmd.getReq(), new SolrQueryResponse(), new RunUpdateProcessor(cmd.getReq(), null))).processAdd(cmd); } catch (IOException e) { } } }; t.run(); threads.add(t); finalCount += index; //int_i } for (Thread thread: threads) { thread.join(); } assertU(commit()); assertQ("Check the total number of docs", req("q", "id:10"), "//result[@numFound=1]"); StringJoiner queryString = new StringJoiner(" "); for(String string: strings) { queryString.add(string); } assertQ("Check the total number of docs", req("q", "cat:" + queryString.toString()) , "//result[@numFound=1]"); assertQ("Check the total number of docs", req("q", "int_i:" + finalCount) , "//result[@numFound=1]"); } private String generateRandomString() { char[] chars = "abcdefghijklmnopqrstuvwxyz0123456789".toCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 20; i++) { char c = chars[random().nextInt(chars.length)]; sb.append(c); } return sb.toString(); } }