/* * JBoss, Home of Professional Open Source * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. */ package org.searchisko.api.reindexer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.indices.IndexMissingException; import org.elasticsearch.search.SearchHit; import org.jboss.elasticsearch.tools.content.InvalidDataException; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.searchisko.api.ContentObjectFields; import org.searchisko.api.rest.exception.PreprocessorInvalidDataException; import org.searchisko.api.service.ProviderService; import org.searchisko.api.service.ProviderServiceTest; import org.searchisko.api.service.SearchClientService; import org.searchisko.api.tasker.TaskExecutionContext; import org.searchisko.api.testtools.ESRealClientTestBase; /** * Unit test for {@link RenormalizeByEsValueTask} * * @author Vlastimil Elias (velias at redhat dot com) */ public class RenormalizeByEsValueTaskTest extends ESRealClientTestBase { String contributorCode = "project 1"; String contributorCode2 = "project 2"; String sysContentType = "tt"; String indexName = "myindex"; String typeName = "mytype"; @SuppressWarnings("unchecked") @Test public void performHitProcessing_PreprocessorInvalidDataException() throws Exception { RenormalizeByEsValueTask tested = new RenormalizeByEsValueTask(); tested.providerService = Mockito.mock(ProviderService.class); TaskExecutionContext context = Mockito.mock(TaskExecutionContext.class); tested.setExecutionContext("tid", context); List<Map<String, Object>> preprocessorsDef = new ArrayList<Map<String, Object>>(); configProviderServiceMock(tested, preprocessorsDef); SearchHit hit = Mockito.mock(SearchHit.class); BulkRequestBuilder brb = Mockito.mock(BulkRequestBuilder.class); Client client = Mockito.mock(Client.class); Mockito.when(hit.getId()).thenReturn("hitid"); Map<String, Object> content = new HashMap<String, Object>(); content.put(ContentObjectFields.SYS_CONTENT_TYPE, sysContentType); Mockito.when(hit.getSource()).thenReturn(content); Mockito.when( tested.providerService.runPreprocessors(Mockito.eq(sysContentType), Mockito.anyList(), Mockito.anyMap())) .thenThrow(new PreprocessorInvalidDataException(new InvalidDataException("data error"))); tested.performHitProcessing(client, brb, hit); Mockito.verify(context).writeTaskLog("tid", "ERROR: Data error from preprocessors execution so document hitid is skipped: data error"); Mockito.verifyNoMoreInteractions(context, brb, client); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public synchronized void performTask_ok() throws Exception { try { RenormalizeByEsValueTask tested = new RenormalizeByEsValueTask(); tested.searchClientService = Mockito.mock(SearchClientService.class); Mockito.when(tested.searchClientService.getClient()).thenReturn(prepareESClientForUnitTest("RenormalizeByEsValueTaskTest")); tested.esField = ContentObjectFields.SYS_CONTRIBUTORS; tested.esValues = new String[] { contributorCode }; tested.providerService = Mockito.mock(ProviderService.class); TaskExecutionContext contextMock = Mockito.mock(TaskExecutionContext.class); tested.setExecutionContext("tid", contextMock); List<Map<String, Object>> preprocessorsDef = new ArrayList<Map<String, Object>>(); // case - run on nonexisting index indexDelete(indexName); try { configProviderServiceMock(tested, preprocessorsDef); tested.performTask(); Assert.fail("IndexMissingException expected"); } catch (IndexMissingException e) { Mockito.verify(tested.providerService, Mockito.times(0)).runPreprocessors(Mockito.eq(sysContentType), Mockito.eq(preprocessorsDef), Mockito.anyMap()); } indexCreate(indexName); indexMappingCreate(indexName, typeName, "{ \"" + typeName + "\" : {\"properties\": {\"sys_contributors\" : {\"type\" : \"string\", \"analyzer\" : \"keyword\"}}}}"); // case - run on empty index { Mockito.reset(tested.providerService); configProviderServiceMock(tested, preprocessorsDef); tested.performTask(); indexFlushAndRefresh(indexName); Mockito.verify(tested.providerService, Mockito.times(0)).runPreprocessors(Mockito.eq(sysContentType), Mockito.eq(preprocessorsDef), Mockito.anyMap()); Mockito.verify(contextMock).writeTaskLog(Mockito.anyString(), Mockito.eq("Processed 0 documents.")); } // case - run on non empty index, for one project { indexInsertDocument(indexName, typeName, "tt-1", "{\"id\" : \"tt1\", \"sys_contributors\" : [\"project 3\",\"project 1\"], \"sys_content_type\" : \"tt\"}"); indexInsertDocument(indexName, typeName, "tt-2", "{\"id\" : \"tt2\", \"sys_contributors\" : \"project 1\", \"sys_content_type\" : \"tt\"}"); indexInsertDocument(indexName, typeName, "tt-3", "{\"id\" : \"tt3\", \"sys_contributors\" : \"project 1\", \"sys_content_type\" : \"tt\"}"); indexInsertDocument(indexName, typeName, "tt-4", "{\"id\" : \"tt4\", \"sys_contributors\" : \"project 2\", \"sys_content_type\" : \"tt\"}"); indexInsertDocument(indexName, typeName, "tt-5", "{\"id\" : \"tt5\", \"sys_contributors\" : [\"project 1\",\"project 2\"], \"sys_content_type\" : \"tt\"}"); indexInsertDocument(indexName, typeName, "tt-6", "{\"id\" : \"tt6\", \"sys_contributors\" : \"project 2\", \"sys_content_type\" : \"tt\"}"); // next must be skipped due nonexisting type definition indexInsertDocument(indexName, typeName, "tt-7", "{\"id\" : \"tt7\", \"sys_contributors\" : \"project 1\", \"sys_content_type\" : \"tt2\"}"); indexInsertDocument(indexName, typeName, "tt-8", "{\"id\" : \"tt8\", \"sys_contributors\" : \"project 3\", \"sys_content_type\" : \"tt\"}"); indexFlushAndRefresh(indexName); Mockito.reset(tested.providerService, contextMock); configProviderServiceMock(tested, preprocessorsDef); Mockito.doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Map<String, Object> m = (Map<String, Object>) invocation.getArguments()[2]; m.put("called", "yes"); return null; } }).when(tested.providerService) .runPreprocessors(Mockito.eq(sysContentType), Mockito.anyList(), Mockito.anyMap()); tested.performTask(); indexFlushAndRefresh(indexName); // check preprocessors was called for all documents in index Assert.assertEquals("yes", indexGetDocument(indexName, typeName, "tt-1").get("called")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-2").get("called")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-3").get("called")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-4").get("called")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-5").get("called")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-6").get("called")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-7").get("called")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-8").get("called")); Mockito.verify(tested.providerService, Mockito.times(4)).runPreprocessors(Mockito.eq(sysContentType), Mockito.eq(preprocessorsDef), Mockito.anyMap()); Mockito.verify(contextMock).writeTaskLog(Mockito.anyString(), Mockito.eq("No type definition found for document id=tt-7 so is skipped")); Mockito.verify(contextMock).writeTaskLog(Mockito.anyString(), Mockito.eq("Processed 5 documents.")); } // case - run on non empty index, for more projects { tested.esValues = new String[] { contributorCode, contributorCode2 }; Mockito.reset(tested.providerService, contextMock); configProviderServiceMock(tested, preprocessorsDef); Mockito.doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Map<String, Object> m = (Map<String, Object>) invocation.getArguments()[2]; m.put("called2", "yes"); return null; } }).when(tested.providerService) .runPreprocessors(Mockito.eq(sysContentType), Mockito.anyList(), Mockito.anyMap()); tested.performTask(); indexFlushAndRefresh(indexName); // check preprocessors was called for all documents in index Assert.assertEquals("yes", indexGetDocument(indexName, typeName, "tt-1").get("called2")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-2").get("called2")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-3").get("called2")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-4").get("called2")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-5").get("called2")); Assert.assertNotNull(indexGetDocument(indexName, typeName, "tt-6").get("called2")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-7").get("called2")); Assert.assertNull(indexGetDocument(indexName, typeName, "tt-8").get("called2")); Mockito.verify(tested.providerService, Mockito.times(6)).runPreprocessors(Mockito.eq(sysContentType), Mockito.eq(preprocessorsDef), Mockito.anyMap()); Mockito.verify(contextMock).writeTaskLog(Mockito.anyString(), Mockito.eq("No type definition found for document id=tt-7 so is skipped")); Mockito.verify(contextMock).writeTaskLog(Mockito.anyString(), Mockito.eq("Processed 7 documents.")); } } finally { finalizeESClientForUnitTest(); } } private void configProviderServiceMock(RenormalizeByEsValueTask tested, List<Map<String, Object>> preprocessorsDef) { Map<String, Object> typeDef = new HashMap<String, Object>(); typeDef.put(ProviderService.INPUT_PREPROCESSORS, preprocessorsDef); Map<String, Object> index = new HashMap<String, Object>(); typeDef.put(ProviderService.INDEX, index); index.put(ProviderService.NAME, indexName); index.put(ProviderService.TYPE, typeName); Mockito.when(tested.providerService.findContentType(sysContentType)).thenReturn( ProviderServiceTest.createProviderContentTypeInfo(typeDef)); Mockito.when(tested.providerService.findContentType("tt2")).thenReturn(null); Map<String, Object> providerDef = new HashMap<String, Object>(); Map<String, Object> typesDef = new HashMap<String, Object>(); providerDef.put(ProviderService.TYPE, typesDef); typesDef.put(sysContentType, typeDef); List<Map<String, Object>> providers = new ArrayList<Map<String, Object>>(); providers.add(providerDef); Mockito.when(tested.providerService.getAll()).thenReturn(providers); } }