blob: 6ee2432d085ff405a339c3effbca85b6223df45e [file] [log] [blame]
/*
* 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.dataimport;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.handler.dataimport.config.DIHConfiguration;
import org.apache.solr.handler.dataimport.config.Entity;
import org.junit.After;
import org.junit.Test;
import java.util.*;
/**
* <p>
* Test for DocBuilder
* </p>
*
*
* @since solr 1.3
*/
// See: https://issues.apache.org/jira/browse/SOLR-12028 Tests cannot remove files on Windows machines occasionally
public class TestDocBuilder extends AbstractDataImportHandlerTestCase {
@Override
@After
public void tearDown() throws Exception {
MockDataSource.clearCache();
MockStringDataSource.clearCache();
super.tearDown();
}
@Test
public void loadClass() throws Exception {
@SuppressWarnings("unchecked")
Class<Transformer> clz = DocBuilder.loadClass("RegexTransformer", null);
assertNotNull(clz);
}
@Test
@SuppressWarnings({"unchecked"})
public void singleEntityNoRows() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_singleEntity);
DIHConfiguration cfg = di.getConfig();
Entity ent = cfg.getEntities().get(0);
MockDataSource.setIterator("select * from x", new ArrayList<Map<String, Object>>().iterator());
RequestInfo rp = new RequestInfo(null, createMap("command", "full-import"), null);
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.TRUE, swi.deleteAllCalled);
assertEquals(Boolean.TRUE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(0, swi.docs.size());
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(0, di.getDocBuilder().importStatistics.docCount.get());
assertEquals(0, di.getDocBuilder().importStatistics.rowsCount.get());
}
@Test
@SuppressWarnings({"unchecked"})
public void testDeltaImportNoRows_MustNotCommit() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_deltaConfig);
redirectTempProperties(di);
DIHConfiguration cfg = di.getConfig();
Entity ent = cfg.getEntities().get(0);
MockDataSource.setIterator("select * from x", new ArrayList<Map<String, Object>>().iterator());
MockDataSource.setIterator("select id from x", new ArrayList<Map<String, Object>>().iterator());
RequestInfo rp = new RequestInfo(null, createMap("command", "delta-import"), null);
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.FALSE, swi.deleteAllCalled);
assertEquals(Boolean.FALSE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(0, swi.docs.size());
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(0, di.getDocBuilder().importStatistics.docCount.get());
assertEquals(0, di.getDocBuilder().importStatistics.rowsCount.get());
}
@Test
@SuppressWarnings({"unchecked"})
public void singleEntityOneRow() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_singleEntity);
DIHConfiguration cfg = di.getConfig();
Entity ent = cfg.getEntities().get(0);
List<Map<String, Object>> l = new ArrayList<>();
l.add(createMap("id", 1, "desc", "one"));
MockDataSource.setIterator("select * from x", l.iterator());
RequestInfo rp = new RequestInfo(null, createMap("command", "full-import"), null);
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.TRUE, swi.deleteAllCalled);
assertEquals(Boolean.TRUE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(1, swi.docs.size());
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(1, di.getDocBuilder().importStatistics.docCount.get());
assertEquals(1, di.getDocBuilder().importStatistics.rowsCount.get());
for (int i = 0; i < l.size(); i++) {
Map<String, Object> map = l.get(i);
SolrInputDocument doc = swi.docs.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
assertEquals(entry.getValue(), doc.getFieldValue(entry.getKey()));
}
}
}
@Test
@SuppressWarnings({"unchecked"})
public void testImportCommand() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_singleEntity);
DIHConfiguration cfg = di.getConfig();
Entity ent = cfg.getEntities().get(0);
List<Map<String, Object>> l = new ArrayList<>();
l.add(createMap("id", 1, "desc", "one"));
MockDataSource.setIterator("select * from x", l.iterator());
RequestInfo rp = new RequestInfo(null, createMap("command", "import"), null);
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.FALSE, swi.deleteAllCalled);
assertEquals(Boolean.TRUE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(1, swi.docs.size());
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(1, di.getDocBuilder().importStatistics.docCount.get());
assertEquals(1, di.getDocBuilder().importStatistics.rowsCount.get());
for (int i = 0; i < l.size(); i++) {
Map<String, Object> map = l.get(i);
SolrInputDocument doc = swi.docs.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
assertEquals(entry.getValue(), doc.getFieldValue(entry.getKey()));
}
}
}
@Test
@SuppressWarnings({"unchecked"})
public void singleEntityMultipleRows() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_singleEntity);
DIHConfiguration cfg = di.getConfig();
Entity ent = cfg.getEntities().get(0);
RequestInfo rp = new RequestInfo(null, createMap("command", "full-import"), null);
List<Map<String, Object>> l = new ArrayList<>();
l.add(createMap("id", 1, "desc", "one"));
l.add(createMap("id", 2, "desc", "two"));
l.add(createMap("id", 3, "desc", "three"));
MockDataSource.setIterator("select * from x", l.iterator());
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.TRUE, swi.deleteAllCalled);
assertEquals(Boolean.TRUE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(3, swi.docs.size());
for (int i = 0; i < l.size(); i++) {
Map<String, Object> map = l.get(i);
SolrInputDocument doc = swi.docs.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
assertEquals(entry.getValue(), doc.getFieldValue(entry.getKey()));
}
assertEquals(map.get("desc"), doc.getFieldValue("desc_s"));
}
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(3, di.getDocBuilder().importStatistics.docCount.get());
assertEquals(3, di.getDocBuilder().importStatistics.rowsCount.get());
}
@Test
@SuppressWarnings({"unchecked"})
public void templateXPath() {
DataImporter di = new DataImporter();
di.loadAndInit(dc_variableXpath);
DIHConfiguration cfg = di.getConfig();
RequestInfo rp = new RequestInfo(null, createMap("command", "full-import"), null);
List<Map<String, Object>> l = new ArrayList<>();
l.add(createMap("id", 1, "name", "iphone", "manufacturer", "Apple"));
l.add(createMap("id", 2, "name", "ipad", "manufacturer", "Apple"));
l.add(createMap("id", 3, "name", "pixel", "manufacturer", "Google"));
MockDataSource.setIterator("select * from x", l.iterator());
List<Map<String,Object>> nestedData = new ArrayList<>();
nestedData.add(createMap("founded", "Cupertino, California, U.S", "year", "1976", "year2", "1976"));
nestedData.add(createMap("founded", "Cupertino, California, U.S", "year", "1976", "year2", "1976"));
nestedData.add(createMap("founded", "Menlo Park, California, U.S", "year", "1998", "year2", "1998"));
MockStringDataSource.setData("companies.xml", xml_attrVariableXpath);
MockStringDataSource.setData("companies2.xml", xml_variableXpath);
MockStringDataSource.setData("companies3.xml", xml_variableForEach);
SolrWriterImpl swi = new SolrWriterImpl();
di.runCmd(rp, swi);
assertEquals(Boolean.TRUE, swi.deleteAllCalled);
assertEquals(Boolean.TRUE, swi.commitCalled);
assertEquals(Boolean.TRUE, swi.finishCalled);
assertEquals(3, swi.docs.size());
for (int i = 0; i < l.size(); i++) {
SolrInputDocument doc = swi.docs.get(i);
Map<String, Object> map = l.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
assertEquals(entry.getValue(), doc.getFieldValue(entry.getKey()));
}
map = nestedData.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
assertEquals(entry.getValue(), doc.getFieldValue(entry.getKey()));
}
}
assertEquals(1, di.getDocBuilder().importStatistics.queryCount.get());
assertEquals(3, di.getDocBuilder().importStatistics.docCount.get());
}
static class SolrWriterImpl extends SolrWriter {
List<SolrInputDocument> docs = new ArrayList<>();
Boolean deleteAllCalled = Boolean.FALSE;
Boolean commitCalled = Boolean.FALSE;
Boolean finishCalled = Boolean.FALSE;
public SolrWriterImpl() {
super(null, null);
}
@Override
public boolean upload(SolrInputDocument doc) {
return docs.add(doc);
}
@Override
public void doDeleteAll() {
deleteAllCalled = Boolean.TRUE;
}
@Override
public void commit(boolean b) {
commitCalled = Boolean.TRUE;
}
@Override
public void close() {
finishCalled = Boolean.TRUE;
}
}
public static final String dc_singleEntity = "<dataConfig>\n"
+ "<dataSource type=\"MockDataSource\"/>\n"
+ " <document name=\"X\" >\n"
+ " <entity name=\"x\" query=\"select * from x\">\n"
+ " <field column=\"id\"/>\n"
+ " <field column=\"desc\"/>\n"
+ " <field column=\"desc\" name=\"desc_s\" />" + " </entity>\n"
+ " </document>\n" + "</dataConfig>";
public static final String dc_deltaConfig = "<dataConfig>\n"
+ "<dataSource type=\"MockDataSource\"/>\n"
+ " <document name=\"X\" >\n"
+ " <entity name=\"x\" query=\"select * from x\" deltaQuery=\"select id from x\">\n"
+ " <field column=\"id\"/>\n"
+ " <field column=\"desc\"/>\n"
+ " <field column=\"desc\" name=\"desc_s\" />" + " </entity>\n"
+ " </document>\n" + "</dataConfig>";
public static final String dc_variableXpath = "<dataConfig>\n"
+ "<dataSource type=\"MockDataSource\"/>\n"
+ "<dataSource name=\"xml\" type=\"MockStringDataSource\"/>\n"
+ " <document name=\"X\" >\n"
+ " <entity name=\"x\" query=\"select * from x\">\n"
+ " <field column=\"id\"/>\n"
+ " <field column=\"name\"/>\n"
+ " <field column=\"manufacturer\"/>"
+ " <entity name=\"c1\" url=\"companies.xml\" dataSource=\"xml\" forEach=\"/companies/company\" processor=\"XPathEntityProcessor\">"
+ " <field column=\"year\" xpath=\"/companies/company/year[@name='p_${x.manufacturer}_s']\" />"
+ " </entity>"
+ " <entity name=\"c2\" url=\"companies2.xml\" dataSource=\"xml\" forEach=\"/companies/company\" processor=\"XPathEntityProcessor\">"
+ " <field column=\"founded\" xpath=\"/companies/company/p_${x.manufacturer}_s/founded\" />"
+ " </entity>"
+ " <entity name=\"c3\" url=\"companies3.xml\" dataSource=\"xml\" forEach=\"/companies/${x.manufacturer}\" processor=\"XPathEntityProcessor\">"
+ " <field column=\"year2\" xpath=\"/companies/${x.manufacturer}/year\" />"
+ " </entity>"
+ " </entity>\n"
+ " </document>\n" + "</dataConfig>";
public static final String xml_variableForEach = "<companies>\n" +
"\t<Apple>\n" +
"\t\t<year>1976</year>\n" +
"\t</Apple>\n" +
"\t<Google>\n" +
"\t\t<year>1998</year>\n" +
"\t</Google>\n" +
"</companies>";
public static final String xml_variableXpath = "<companies>\n" +
"\t<company>\n" +
"\t\t<p_Apple_s>\n" +
"\t\t\t<founded>Cupertino, California, U.S</founded>\n" +
"\t\t</p_Apple_s>\t\t\n" +
"\t</company>\n" +
"\t<company>\n" +
"\t\t<p_Google_s>\n" +
"\t\t\t<founded>Menlo Park, California, U.S</founded>\n" +
"\t\t</p_Google_s>\n" +
"\t</company>\n" +
"</companies>";
public static final String xml_attrVariableXpath = "<companies>\n" +
"\t<company>\n" +
"\t\t<year name='p_Apple_s'>1976</year>\n" +
"\t</company>\n" +
"\t<company>\n" +
"\t\t<year name='p_Google_s'>1998</year>\t\t\n" +
"\t</company>\n" +
"</companies>";
}