package com.lucidworks.storm.solr; import backtype.storm.tuple.Tuple; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.lucidworks.storm.spring.SpringBolt; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import java.util.Random; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * Tests the SolrJsonBoltAction */ public class SolrJsonBoltActionTest extends SolrBoltActionTest { @Override protected void doBoltActionTest() throws Exception { SolrJsonBoltAction sba = new SolrJsonBoltAction(cloudSolrClient); sba.setUpdateRequestStrategy(new DefaultUpdateRequestStrategy()); sba.setDocumentAssignmentStrategy(new DefaultDocumentAssignmentStrategy()); sba.setMaxBufferSize(1); // to avoid buffering docs // Mock the Storm tuple String docId = "1"; String testDoc = "{" + "'id':'1'," + "'text':'foo'," + "'number':10" + "}"; testDoc = testDoc.replace('\'', '"'); Tuple mockTuple = mock(Tuple.class); when(mockTuple.size()).thenReturn(2); when(mockTuple.getString(0)).thenReturn(docId); when(mockTuple.getValue(1)).thenReturn(testDoc); SpringBolt.ExecuteResult result = sba.execute(mockTuple, null); assertTrue(result == SpringBolt.ExecuteResult.ACK); cloudSolrClient.commit(); // verify the object to Solr mapping worked correctly using reflection and dynamic fields SolrQuery query = new SolrQuery("id:" + docId); QueryResponse qr = cloudSolrClient.query(query); SolrDocumentList results = qr.getResults(); assertTrue(results.getNumFound() == 1); SolrDocument doc = results.get(0); assertNotNull(doc); assertEquals("foo", doc.getFirstValue("text")); assertEquals("10", String.valueOf(doc.getFirstValue("number"))); // gen a big JSON object now ... one that gets streamed out to Solr String[] vocab = new String[]{ "quick","red","fox","jumped","over","the","lazy","big","dog" }; Random rand = new Random(5150); docId = "2"; JsonNodeFactory factory = JsonNodeFactory.instance; ObjectNode root = factory.objectNode(); root.put("id", docId); for (int i=0; i < 200; i++) { root.put("f"+i+"_s", randomString(vocab, rand)); } mockTuple = mock(Tuple.class); when(mockTuple.size()).thenReturn(2); when(mockTuple.getString(0)).thenReturn(docId); when(mockTuple.getValue(1)).thenReturn(root); result = sba.execute(mockTuple, null); assertTrue(result == SpringBolt.ExecuteResult.ACK); cloudSolrClient.commit(); query = new SolrQuery("id:" + docId); qr = cloudSolrClient.query(query); results = qr.getResults(); assertTrue(results.getNumFound() == 1); assertNotNull(results.get(0)); } protected String randomString(final String[] vocab, final Random rand) { int numWords = rand.nextInt(1000)+1; StringBuilder sb = new StringBuilder(); for (int w=0; w < numWords; w++) { if (w > 0) sb.append(" "); sb.append(vocab[rand.nextInt(vocab.length)]); } return sb.toString(); } }