/* * JBoss, Home of Professional Open Source * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. */ package org.jboss.elasticsearch.river.remote; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.Assert; import org.elasticsearch.Version; import org.elasticsearch.action.ListenableActionFuture; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.transport.DummyTransportAddress; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.river.RiverName; import org.elasticsearch.river.RiverSettings; import org.jboss.elasticsearch.river.remote.testtools.DataPreprocessorMock; import org.jboss.elasticsearch.river.remote.testtools.ESRealClientTestBase; import org.jboss.elasticsearch.river.remote.testtools.MockThread; import org.jboss.elasticsearch.river.remote.testtools.TestUtils; import org.jboss.elasticsearch.tools.content.StructuredContentPreprocessor; import org.junit.Test; import org.mockito.Mockito; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Unit test for {@link RemoteRiver}. * * @author Vlastimil Elias (velias at redhat dot com) */ public class RemoteRiverTest extends ESRealClientTestBase { /** * */ private static final String KEY_2 = "AAB"; /** * */ private static final String KEY_1 = "AAA"; private static final String RIVER_NAME = "my_remote_river"; @SuppressWarnings("unchecked") @Test public void constructor_config() throws Exception { // case - exception if no remote URL base is defined try { prepareRiverInstanceForTest(null, null, null, false); Assert.fail("No SettingsException thrown"); } catch (SettingsException e) { // OK } try { prepareRiverInstanceForTest(" ", null, null, false); Assert.fail("No SettingsException thrown"); } catch (SettingsException e) { // OK } Map<String, Object> remoteSettingsAdd = new HashMap<String, Object>(); Map<String, Object> toplevelSettingsAdd = new HashMap<String, Object>(); extendToplevelSettingsByMandatoryIndexSettings(toplevelSettingsAdd); // case - test default settings RemoteRiver tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.assertEquals(1, tested.maxIndexingThreads); Assert.assertEquals(5 * 60 * 1000, tested.indexUpdatePeriod); Assert.assertEquals(12 * 60 * 60 * 1000, tested.indexFullUpdatePeriod); Assert.assertNull(tested.indexFullUpdateCronExpression); Assert.assertEquals(RIVER_NAME, tested.indexName); Assert.assertEquals(RemoteRiver.INDEX_DOCUMENT_TYPE_NAME_DEFAULT, tested.typeName); Assert.assertEquals(tested.documentIndexStructureBuilder, tested.remoteSystemClient.getIndexStructureBuilder()); Assert.assertEquals(SpaceIndexingMode.UPDATE_TIMESTAMP, tested.spaceIndexingMode); // case - test river configuration reading remoteSettingsAdd.put("maxIndexingThreads", "5"); remoteSettingsAdd.put("indexUpdatePeriod", "20m"); remoteSettingsAdd.put("indexFullUpdatePeriod", "5h"); remoteSettingsAdd.put("indexFullUpdateCronExpression", "0 0 10 * * ?"); remoteSettingsAdd.put("maxIssuesPerRequest", 20); remoteSettingsAdd.put("timeout", "5s"); remoteSettingsAdd.put("jqlTimeZone", "Europe/Prague"); Map<String, Object> indexSettings = (Map<String, Object>) toplevelSettingsAdd.get("index"); indexSettings.put("index", "my_index_name"); indexSettings.put("type", "type_test"); tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.assertEquals(5, tested.maxIndexingThreads); Assert.assertEquals(20 * 60 * 1000, tested.indexUpdatePeriod); Assert.assertEquals(5 * 60 * 60 * 1000, tested.indexFullUpdatePeriod); Assert.assertEquals("0 0 10 * * ?", tested.indexFullUpdateCronExpression.toString()); Assert.assertEquals("my_index_name", tested.indexName); Assert.assertEquals("type_test", tested.typeName); Assert.assertEquals(SpaceIndexingMode.UPDATE_TIMESTAMP, tested.spaceIndexingMode); // assert index structure builder initialization Assert.assertEquals(tested.documentIndexStructureBuilder, tested.remoteSystemClient.getIndexStructureBuilder()); Assert.assertEquals(tested.indexName, ((DocumentWithCommentsIndexStructureBuilder) tested.documentIndexStructureBuilder).indexName); Assert.assertEquals(tested.typeName, ((DocumentWithCommentsIndexStructureBuilder) tested.documentIndexStructureBuilder).issueTypeName); Assert.assertEquals(tested.riverName().getName(), ((DocumentWithCommentsIndexStructureBuilder) tested.documentIndexStructureBuilder).riverName); remoteSettingsAdd.put("simpleGetDocuments", "true"); tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.assertEquals(SpaceIndexingMode.SIMPLE, tested.spaceIndexingMode); Assert.assertEquals(0, tested.indexUpdatePeriod); // case - #50 - listDocumentsMode config reading test remoteSettingsAdd.put("simpleGetDocuments", "true"); remoteSettingsAdd.put("listDocumentsMode", SpaceIndexingMode.PAGINATION.getConfigValue()); tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.assertEquals(SpaceIndexingMode.PAGINATION, tested.spaceIndexingMode); Assert.assertEquals(0, tested.indexUpdatePeriod); // case - #50 - listDocumentsMode config reading test, simple mode and backward compatibility of update period // config remoteSettingsAdd.remove("simpleGetDocuments"); remoteSettingsAdd.put("indexUpdatePeriod", "20m"); remoteSettingsAdd.put("indexFullUpdatePeriod", "0"); remoteSettingsAdd.remove("indexFullUpdateCronExpression"); remoteSettingsAdd.put("listDocumentsMode", SpaceIndexingMode.SIMPLE.getConfigValue()); tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.assertEquals(SpaceIndexingMode.SIMPLE, tested.spaceIndexingMode); Assert.assertEquals(20 * 60 * 1000, tested.indexUpdatePeriod); Assert.assertEquals(0, tested.indexFullUpdatePeriod); Assert.assertNull(tested.indexFullUpdateCronExpression); // case - #49 - invalid cron expression try { remoteSettingsAdd.put("indexFullUpdateCronExpression", "0 0 10 * ? ?"); tested = prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, toplevelSettingsAdd, false); Assert.fail("SettingsException expected"); } catch (SettingsException e) { Assert .assertEquals( "Cron expression in indexFullUpdateCronExpression is invalid: '?' can only be specfied for Day-of-Month or Day-of-Week.", e.getMessage()); } } @Test public void constructor_postprocessors() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest("https://issues.jboss.org", null, Utils.loadJSONFromJarPackagedFile("/river_configuration_test_preprocessors.json"), false); List<StructuredContentPreprocessor> preprocs = ((DocumentWithCommentsIndexStructureBuilder) tested.documentIndexStructureBuilder).issueDataPreprocessors; Assert.assertEquals(2, preprocs.size()); Assert.assertEquals("Status Normalizer", preprocs.get(0).getName()); Assert.assertEquals("value1", ((DataPreprocessorMock) preprocs.get(0)).settings.get("some_setting_1_1")); Assert.assertEquals("value2", ((DataPreprocessorMock) preprocs.get(0)).settings.get("some_setting_1_2")); Assert.assertEquals("Issue type Normalizer", preprocs.get(1).getName()); Assert.assertEquals("value1", ((DataPreprocessorMock) preprocs.get(1)).settings.get("some_setting_2_1")); Assert.assertEquals("value2", ((DataPreprocessorMock) preprocs.get(1)).settings.get("some_setting_2_2")); } @Test public void configure() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.closed = false; tested.configure(null); Assert.fail("IllegalStateException must be thrown"); } catch (IllegalStateException e) { // OK } // do not test configuration read here, it's tested in constructor tests } @Test public void start() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.closed = false; tested.start(); Assert.fail("IllegalStateException must be thrown"); } catch (IllegalStateException e) { // OK } // do not test real start here because it's hardly testable } @Test public void close() throws Exception { // case - close all correctly RemoteRiver tested = prepareRiverInstanceForTest(null); MockThread mockThread = new MockThread(); tested.coordinatorThread = mockThread; tested.coordinatorInstance = mock(ISpaceIndexerCoordinator.class); tested.closed = false; Assert.assertNotNull(tested.coordinatorThread); Assert.assertNotNull(tested.coordinatorInstance); RemoteRiver.riverInstances.put(tested.riverName().getName(), tested); Assert.assertTrue(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); tested.close(); Assert.assertTrue(tested.isClosed()); Assert.assertTrue(mockThread.interruptWasCalled); Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); Assert.assertFalse(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); // case - no exception when coordinatorThread and coordinatorInstance is null tested = prepareRiverInstanceForTest(null); RemoteRiver.riverInstances.put(tested.riverName().getName(), tested); tested.coordinatorThread = null; tested.coordinatorInstance = null; tested.closed = false; Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); tested.close(); Assert.assertTrue(tested.isClosed()); Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); Assert.assertFalse(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); } @Test public void stop() throws Exception { // case - close all correctly RemoteRiver tested = prepareRiverInstanceForTest(null); MockThread mockThread = new MockThread(); tested.coordinatorThread = mockThread; tested.coordinatorInstance = mock(ISpaceIndexerCoordinator.class); tested.closed = false; Assert.assertNotNull(tested.coordinatorThread); Assert.assertNotNull(tested.coordinatorInstance); RemoteRiver.riverInstances.put(tested.riverName().getName(), tested); Assert.assertTrue(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); tested.stop(false); Assert.assertTrue(tested.isClosed()); Assert.assertTrue(mockThread.interruptWasCalled); Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); Assert.assertTrue(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); // case - no exception when coordinatorThread and coordinatorInstance is null tested = prepareRiverInstanceForTest(null); RemoteRiver.riverInstances.put(tested.riverName().getName(), tested); tested.coordinatorThread = null; tested.coordinatorInstance = null; tested.closed = false; Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); tested.stop(false); Assert.assertTrue(tested.isClosed()); Assert.assertNull(tested.coordinatorThread); Assert.assertNull(tested.coordinatorInstance); Assert.assertTrue(RemoteRiver.riverInstances.containsKey(tested.riverName().getName())); } @Test public void stop_permanent() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.client = prepareESClientForUnitTest(); indexCreate(tested.getRiverIndexName()); // case - not permanent stop tested.closed = false; tested.stop(false); Assert.assertNull(tested.readDatetimeValue(null, RemoteRiver.PERMSTOREPROP_RIVER_STOPPED_PERMANENTLY)); Assert.assertTrue(tested.isClosed()); // case - permanent stop tested.closed = false; tested.stop(true); Assert.assertNotNull(tested.readDatetimeValue(null, RemoteRiver.PERMSTOREPROP_RIVER_STOPPED_PERMANENTLY)); Assert.assertTrue(tested.isClosed()); } finally { finalizeESClientForUnitTest(); } } @Test public void reconfigure() throws Exception { // case - exception when not stopped { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.closed = false; tested.reconfigure(); Assert.fail("IllegalStateException must be thrown"); } catch (IllegalStateException e) { // OK } } // case - config reload error because no document { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.client = prepareESClientForUnitTest(); tested.closed = true; indexCreate(tested.getRiverIndexName()); tested.reconfigure(); Assert.fail("IllegalStateException must be thrown"); } catch (IllegalStateException e) { // OK } finally { finalizeESClientForUnitTest(); } } // case - config reload performed { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.client = prepareESClientForUnitTest(); tested.closed = true; tested.client.prepareIndex(tested.getRiverIndexName(), tested.riverName().getName(), "_meta") .setSource(TestUtils.readStringFromClasspathFile("/river_reconfiguration_test.json")).execute().actionGet(); tested.reconfigure(); Assert.assertEquals("my_remote_index_test", tested.indexName); Assert.assertEquals("remote_doc_test", tested.typeName); Assert.assertEquals("remote_river_activity_test", tested.activityLogIndexName); Assert.assertEquals("remote_river_indexupdate_test", tested.activityLogTypeName); } finally { finalizeESClientForUnitTest(); } } } @Test public void restart() { // TODO unittest } @Test public void getAllIndexedSpacesKeys_FromStaticConfig() throws Exception { Map<String, Object> jiraSettings = new HashMap<String, Object>(); jiraSettings.put("spacesIndexed", "ORG, UUUU, PEM, SU07"); RemoteRiver tested = prepareRiverInstanceForTest(jiraSettings); IRemoteSystemClient jiraClientMock = tested.remoteSystemClient; List<String> r = tested.getAllIndexedSpaceKeys(); Assert.assertEquals(4, r.size()); Assert.assertEquals("ORG", r.get(0)); Assert.assertEquals("UUUU", r.get(1)); Assert.assertEquals("PEM", r.get(2)); Assert.assertEquals("SU07", r.get(3)); Assert.assertEquals(Long.MAX_VALUE, tested.allIndexedSpacesKeysNextRefresh); verify(jiraClientMock, times(0)).getAllSpaces(); } @Test public void getAllIndexedSpacesKeys_FromRemoteNoExcludes() throws Exception { Map<String, Object> jiraSettings = new HashMap<String, Object>(); jiraSettings.put("spaceKeysExcluded", ""); RemoteRiver tested = prepareRiverInstanceForTest(jiraSettings); IRemoteSystemClient jiraClientMock = tested.remoteSystemClient; List<String> pl = Utils.parseCsvString("ORG,UUUU,PEM,SU07"); when(jiraClientMock.getAllSpaces()).thenReturn(pl); List<String> r = tested.getAllIndexedSpaceKeys(); verify(jiraClientMock, times(1)).getAllSpaces(); Assert.assertEquals(4, r.size()); Assert.assertEquals("ORG", r.get(0)); Assert.assertEquals("UUUU", r.get(1)); Assert.assertEquals("PEM", r.get(2)); Assert.assertEquals("SU07", r.get(3)); Assert .assertTrue(tested.allIndexedSpacesKeysNextRefresh <= (System.currentTimeMillis() + RemoteRiver.SPACES_REFRESH_TIME)); } @Test public void getAllIndexedSpacesKeys_FromRemoteWithExcludes() throws Exception { Map<String, Object> jiraSettings = new HashMap<String, Object>(); jiraSettings.put("spaceKeysExcluded", "PEM,UUUU"); RemoteRiver tested = prepareRiverInstanceForTest(jiraSettings); IRemoteSystemClient jiraClientMock = tested.remoteSystemClient; List<String> pl = Utils.parseCsvString("ORG,UUUU,PEM,SU07"); when(jiraClientMock.getAllSpaces()).thenReturn(pl); List<String> r = tested.getAllIndexedSpaceKeys(); verify(jiraClientMock, times(1)).getAllSpaces(); Assert.assertEquals(2, r.size()); Assert.assertEquals("ORG", r.get(0)); Assert.assertEquals("SU07", r.get(1)); Assert .assertTrue(tested.allIndexedSpacesKeysNextRefresh <= (System.currentTimeMillis() + RemoteRiver.SPACES_REFRESH_TIME)); } @Test public void storeDatetimeValueBuildDocument() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); String dt = "2012-09-30T12:22:44.156Z"; Date d = DateTimeUtils.parseISODateTime(dt); { Map<String, Object> out = TestUtils.getJSONMapFromString(tested.storeDatetimeValueBuildDocument(null, "my_property", d).string()); Assert.assertEquals(2, out.size()); Assert.assertEquals("my_property", out.get("propertyName")); Assert.assertEquals(d.getTime(), DateTimeUtils.parseISODateTime((String) out.get("value")).getTime()); } { Map<String, Object> out = TestUtils.getJSONMapFromString(tested.storeDatetimeValueBuildDocument(KEY_1, "my_property", d).string()); Assert.assertEquals(3, out.size()); Assert.assertEquals(KEY_1, out.get("spaceKey")); Assert.assertEquals("my_property", out.get("propertyName")); Assert.assertEquals(d.getTime(), DateTimeUtils.parseISODateTime((String) out.get("value")).getTime()); } } @Test public void readAndStoreAndDeleteDatetimeValue() throws Exception { try { Client client = prepareESClientForUnitTest(); RemoteRiver tested = prepareRiverInstanceForTest(null); tested.client = client; indexCreate("_river"); Assert.assertFalse(tested.deleteDatetimeValue("ORG1", "testProperty_1_1")); tested .storeDatetimeValue("ORG1", "testProperty_1_1", DateTimeUtils.parseISODateTime("2012-09-03T18:12:45"), null); tested .storeDatetimeValue("ORG1", "testProperty_1_2", DateTimeUtils.parseISODateTime("2012-09-03T05:12:40"), null); tested .storeDatetimeValue("ORG2", "testProperty_1_1", DateTimeUtils.parseISODateTime("2012-09-02T08:12:30"), null); tested .storeDatetimeValue("ORG2", "testProperty_1_2", DateTimeUtils.parseISODateTime("2012-09-02T05:02:20"), null); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-03T18:12:45"), tested.readDatetimeValue("ORG1", "testProperty_1_1")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-03T05:12:40"), tested.readDatetimeValue("ORG1", "testProperty_1_2")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T08:12:30"), tested.readDatetimeValue("ORG2", "testProperty_1_1")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T05:02:20"), tested.readDatetimeValue("ORG2", "testProperty_1_2")); Assert.assertTrue(tested.deleteDatetimeValue("ORG1", "testProperty_1_1")); Assert.assertNull(tested.readDatetimeValue("ORG1", "testProperty_1_1")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-03T05:12:40"), tested.readDatetimeValue("ORG1", "testProperty_1_2")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T08:12:30"), tested.readDatetimeValue("ORG2", "testProperty_1_1")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T05:02:20"), tested.readDatetimeValue("ORG2", "testProperty_1_2")); Assert.assertTrue(tested.deleteDatetimeValue("ORG1", "testProperty_1_2")); Assert.assertNull(tested.readDatetimeValue("ORG1", "testProperty_1_2")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T08:12:30"), tested.readDatetimeValue("ORG2", "testProperty_1_1")); Assert.assertEquals(DateTimeUtils.parseISODateTime("2012-09-02T05:02:20"), tested.readDatetimeValue("ORG2", "testProperty_1_2")); } finally { finalizeESClientForUnitTest(); } } @Test public void storeDatetimeValue_Bulk() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); BulkRequestBuilder esBulk = new BulkRequestBuilder(tested.client); tested.storeDatetimeValue("ORG", "prop", new Date(), esBulk); tested.storeDatetimeValue("ORG", "prop2", new Date(), esBulk); tested.storeDatetimeValue("ORG", "prop3", new Date(), esBulk); Assert.assertEquals(3, esBulk.numberOfActions()); } @Test public void prepareValueStoreDocumentName() { Assert.assertEquals("_lastupdatedissue_ORG", RemoteRiver.prepareValueStoreDocumentName("ORG", "lastupdatedissue")); Assert.assertEquals("_lastupdatedissue", RemoteRiver.prepareValueStoreDocumentName(null, "lastupdatedissue")); } @Test public void prepareESBulkRequestBuilder() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); Client clientMock = tested.client; BulkRequestBuilder brb = new BulkRequestBuilder(clientMock); when(clientMock.prepareBulk()).thenReturn(brb); Assert.assertNotNull(tested.prepareESBulkRequestBuilder()); verify(clientMock, times(1)).prepareBulk(); } @Test public void reportIndexingFinished() throws Exception { ISpaceIndexerCoordinator coordMock = mock(ISpaceIndexerCoordinator.class); RemoteRiver tested = prepareRiverInstanceForTest(null); Client clientMock = tested.client; tested.coordinatorInstance = coordMock; // case - report correctly - no activity log { tested.reportIndexingFinished(new SpaceIndexingInfo("ORG", false, 10, 0, 0, null, true, 10, null)); verify(coordMock, times(1)).reportIndexingFinished("ORG", true, false); Mockito.verifyZeroInteractions(clientMock); } { reset(coordMock); tested.reportIndexingFinished(new SpaceIndexingInfo(KEY_1, true, 10, 0, 0, null, false, 10, null)); verify(coordMock, times(1)).reportIndexingFinished(KEY_1, false, true); Mockito.verifyZeroInteractions(clientMock); } // report correctly with activity log tested.activityLogIndexName = "alindex"; tested.activityLogTypeName = "altype"; { IndexRequestBuilder irb = Mockito.mock(IndexRequestBuilder.class); Mockito.when(irb.setSource(Mockito.any(XContentBuilder.class))).thenReturn(irb); @SuppressWarnings("unchecked") ListenableActionFuture<IndexResponse> laf = Mockito.mock(ListenableActionFuture.class); Mockito.when(irb.execute()).thenReturn(laf); when(clientMock.prepareIndex("alindex", "altype")).thenReturn(irb); tested.reportIndexingFinished(new SpaceIndexingInfo("ORG", false, 10, 0, 0, null, true, 10, null)); Mockito.verify(irb).setSource(Mockito.any(XContentBuilder.class)); Mockito.verify(irb).execute(); Mockito.verify(laf).actionGet(); } // case - no exception if coordinatorInstance is null tested = prepareRiverInstanceForTest(null); tested.reportIndexingFinished(new SpaceIndexingInfo("ORG", false, 10, 0, 0, null, true, 10, null)); } @Test public void prepareESScrollSearchRequestBuilder() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); Client clientMock = tested.client; SearchRequestBuilder srb = new SearchRequestBuilder(clientMock); when(clientMock.prepareSearch("myIndex")).thenReturn(srb); tested.prepareESScrollSearchRequestBuilder("myIndex"); Assert.assertNotNull(srb.request().scroll()); Assert.assertEquals(SearchType.SCAN, srb.request().searchType()); verify(clientMock).prepareSearch("myIndex"); } @Test public void getRiverOperationInfo_activityLogDisabled() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); ISpaceIndexerCoordinator coordMock = mock(ISpaceIndexerCoordinator.class); tested.coordinatorInstance = coordMock; List<SpaceIndexingInfo> currentIndexings = new ArrayList<SpaceIndexingInfo>(); currentIndexings.add(new SpaceIndexingInfo("ORG", true, 256, 10, 0, DateTimeUtils .parseISODateTime("2012-09-27T09:21:25.422Z"), false, 0, null)); currentIndexings.add(new SpaceIndexingInfo(KEY_1, false, 15, 0, 0, DateTimeUtils .parseISODateTime("2012-09-27T09:21:24.422Z"), false, 0, null)); when(coordMock.getCurrentSpaceIndexingInfo()).thenReturn(currentIndexings); tested.allIndexedSpacesKeysNextRefresh = Long.MAX_VALUE; tested.allIndexedSpacesKeys = new ArrayList<String>(); tested.allIndexedSpacesKeys.add("ORG"); tested.allIndexedSpacesKeys.add(KEY_1); tested.allIndexedSpacesKeys.add("JJJ"); tested.allIndexedSpacesKeys.add("FFF"); tested.lastSpaceIndexingInfo.put("ORG", new SpaceIndexingInfo("ORG", true, 125, 10, 0, DateTimeUtils.parseISODateTime("2012-09-27T09:15:25.422Z"), true, 1500, null)); tested.lastSpaceIndexingInfo.put("JJJ", new SpaceIndexingInfo("JJJ", false, 12, 0, 0, DateTimeUtils.parseISODateTime("2012-09-27T09:12:25.422Z"), false, 1800, "JIRA timeout")); // case - nothing stored in audit log index - no exception! String info = tested.getRiverOperationInfo(new DiscoveryNode("My Node", "fsdfsdfxzd", DummyTransportAddress.INSTANCE, new HashMap<String, String>(), Version.CURRENT), DateTimeUtils .parseISODateTime("2012-09-27T09:21:26.422Z")); TestUtils.assertStringFromClasspathFile("/asserts/RemoteRiver_getRiverOperationInfo_1.json", info); } @Test public void getRiverOperationInfo_activityLogEnabled() throws Exception { try { Client client = prepareESClientForUnitTest(); RemoteRiver tested = prepareRiverInstanceForTest(null); tested.client = client; tested.activityLogIndexName = "activity_log_index"; tested.activityLogTypeName = "remote_river_indexupdate"; ISpaceIndexerCoordinator coordMock = mock(ISpaceIndexerCoordinator.class); tested.coordinatorInstance = coordMock; List<SpaceIndexingInfo> currentIndexings = new ArrayList<SpaceIndexingInfo>(); currentIndexings.add(new SpaceIndexingInfo("ORG", true, 256, 10, 0, DateTimeUtils .parseISODateTime("2012-09-27T09:21:25.422Z"), false, 0, null)); currentIndexings.add(new SpaceIndexingInfo(KEY_1, false, 15, 0, 0, DateTimeUtils .parseISODateTime("2012-09-27T09:21:24.422Z"), false, 0, null)); when(coordMock.getCurrentSpaceIndexingInfo()).thenReturn(currentIndexings); tested.allIndexedSpacesKeysNextRefresh = Long.MAX_VALUE; tested.allIndexedSpacesKeys = new ArrayList<String>(); tested.allIndexedSpacesKeys.add("ORG"); tested.allIndexedSpacesKeys.add(KEY_1); tested.allIndexedSpacesKeys.add("JJJ"); tested.allIndexedSpacesKeys.add("FFF"); tested.lastSpaceIndexingInfo.put("ORG", new SpaceIndexingInfo("ORG", true, 125, 10, 0, DateTimeUtils.parseISODateTime("2012-09-27T09:15:25.422Z"), true, 1500, null)); tested.lastSpaceIndexingInfo.put("JJJ", new SpaceIndexingInfo("JJJ", false, 12, 0, 0, DateTimeUtils.parseISODateTime("2012-09-27T09:12:25.422Z"), false, 1800, "JIRA timeout")); // case - nothing stored in audit log index - no exception! String info = tested.getRiverOperationInfo(new DiscoveryNode("My Node", "fsdfsdfxzd", DummyTransportAddress.INSTANCE, new HashMap<String, String>(), Version.CURRENT), DateTimeUtils .parseISODateTime("2012-09-27T09:21:26.422Z")); TestUtils.assertStringFromClasspathFile("/asserts/RemoteRiver_getRiverOperationInfo_1.json", info); // case - last indexed record into ES index for FFF space found indexCreate(tested.activityLogIndexName); client.admin().indices().preparePutMapping(tested.activityLogIndexName).setType(tested.activityLogTypeName) .setSource(TestUtils.readStringFromClasspathFile("/examples/remote_river_indexupdate.json")).execute() .actionGet(); tested.writeActivityLogRecord(new SpaceIndexingInfo("FFF", false, 12, 0, 0, DateTimeUtils .parseISODateTime("2012-09-27T08:10:25.422Z"), true, 181, null)); tested.writeActivityLogRecord(new SpaceIndexingInfo("FFF", false, 125, 0, 0, DateTimeUtils .parseISODateTime("2012-09-27T08:11:25.422Z"), true, 1810, null)); tested.refreshSearchIndex(tested.activityLogIndexName); info = tested.getRiverOperationInfo(new DiscoveryNode("My Node", "fsdfsdfxzd", DummyTransportAddress.INSTANCE, new HashMap<String, String>(), Version.CURRENT), DateTimeUtils.parseISODateTime("2012-09-27T09:21:26.422Z")); TestUtils.assertStringFromClasspathFile("/asserts/RemoteRiver_getRiverOperationInfo_2.json", info); } finally { finalizeESClientForUnitTest(); } } @Test public void forceFullReindex() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); ISpaceIndexerCoordinator coordinatorMock = mock(ISpaceIndexerCoordinator.class); tested.coordinatorInstance = coordinatorMock; // case - all spaces but no any exists { tested.allIndexedSpacesKeys = null; Assert.assertEquals("", tested.forceFullReindex(null)); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - all spaces and some exists { reset(coordinatorMock); tested.allIndexedSpacesKeys = new ArrayList<String>(); tested.allIndexedSpacesKeys.add("ORG"); tested.allIndexedSpacesKeys.add(KEY_1); Assert.assertEquals("ORG,AAA", tested.forceFullReindex(null)); verify(coordinatorMock).forceFullReindex("ORG"); verify(coordinatorMock).forceFullReindex(KEY_1); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - one space not exists { reset(coordinatorMock); Assert.assertNull(tested.forceFullReindex("BBB")); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - one space which exists { reset(coordinatorMock); Assert.assertEquals("ORG", tested.forceFullReindex("ORG")); verify(coordinatorMock).forceFullReindex("ORG"); Mockito.verifyNoMoreInteractions(coordinatorMock); reset(coordinatorMock); Assert.assertEquals(KEY_1, tested.forceFullReindex(KEY_1)); verify(coordinatorMock).forceFullReindex(KEY_1); Mockito.verifyNoMoreInteractions(coordinatorMock); } } @Test public void forceIncrementalReindex() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); ISpaceIndexerCoordinator coordinatorMock = mock(ISpaceIndexerCoordinator.class); tested.coordinatorInstance = coordinatorMock; // case - all spaces but no any exists { tested.allIndexedSpacesKeys = null; Assert.assertEquals("", tested.forceIncrementalReindex(null)); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - all spaces and some exists { reset(coordinatorMock); tested.allIndexedSpacesKeys = new ArrayList<String>(); tested.allIndexedSpacesKeys.add("ORG"); tested.allIndexedSpacesKeys.add(KEY_1); Assert.assertEquals("ORG,AAA", tested.forceIncrementalReindex(null)); verify(coordinatorMock).forceIncrementalReindex("ORG"); verify(coordinatorMock).forceIncrementalReindex(KEY_1); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - one space not exists { reset(coordinatorMock); Assert.assertNull(tested.forceIncrementalReindex("BBB")); Mockito.verifyNoMoreInteractions(coordinatorMock); } // case - one space which exists { reset(coordinatorMock); Assert.assertEquals("ORG", tested.forceIncrementalReindex("ORG")); verify(coordinatorMock).forceIncrementalReindex("ORG"); Mockito.verifyNoMoreInteractions(coordinatorMock); reset(coordinatorMock); Assert.assertEquals(KEY_1, tested.forceIncrementalReindex(KEY_1)); verify(coordinatorMock).forceIncrementalReindex(KEY_1); Mockito.verifyNoMoreInteractions(coordinatorMock); } } @Test public void loadPassword() throws Exception { // case - password document not defined { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.client = prepareESClientForUnitTest(); indexCreate(tested.getRiverIndexName()); Assert.assertNull(tested.loadKey("")); } finally { finalizeESClientForUnitTest(); } } // case - password found { RemoteRiver tested = prepareRiverInstanceForTest(null); try { tested.client = prepareESClientForUnitTest(); tested.client.prepareIndex(tested.getRiverIndexName(), tested.riverName().getName(), "_pwd") .setSource("{ \"pwd\" : \"passwd\"}").execute().actionGet(); Assert.assertEquals("passwd", tested.loadKey("").get("pwd")); } finally { finalizeESClientForUnitTest(); } } } @Test public void createLogger() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); ESLogger logger = tested.createLogger(SpaceIndexerCoordinator.class); Assert.assertNotNull(logger); Assert.assertEquals("org.elasticsearch.org.jboss.elasticsearch.river.remote.SpaceIndexerCoordinator", logger.getName()); Assert.assertEquals(" [remote][" + RIVER_NAME + "] ", logger.getPrefix()); } @Test public void riverName() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); RiverName rn = tested.riverName(); Assert.assertEquals(RIVER_NAME, rn.getName()); Assert.assertEquals("remote", rn.getType()); } @Test public void writeActivityLogRecord_getLastSpaceIndexingInfo() throws Exception { RemoteRiver tested = prepareRiverInstanceForTest(null); tested.activityLogIndexName = "alindex"; tested.activityLogTypeName = "altype"; try { tested.client = prepareESClientForUnitTest(); indexCreate(tested.activityLogIndexName); indexCreateMapping(tested.activityLogIndexName, tested.activityLogTypeName, "{\n" + " \"" + tested.activityLogTypeName + "\" : {\n" + " \"properties\" : {\n" + " \"river_name\" : {\"type\" : \"string\", \"analyzer\" : \"keyword\"},\n" + " \"space_key\" : {\"type\" : \"string\", \"analyzer\" : \"keyword\"},\n" + " \"update_type\" : {\"type\" : \"string\", \"analyzer\" : \"keyword\"},\n" + " \"result\" : {\"type\" : \"string\", \"analyzer\" : \"keyword\"}\n" + " }\n" + " }\n" + " }"); // older record to be sure latest one is readed SpaceIndexingInfo indexingInfo1Older = new SpaceIndexingInfo(KEY_1, false, 5, 2, 1, DateTimeUtils.parseISODateTimeWithMinutePrecise("2014-12-22T12:53"), true, 60000, null); indexingInfo1Older.finishedOK = true; tested.writeActivityLogRecord(indexingInfo1Older); SpaceIndexingInfo indexingInfo1 = new SpaceIndexingInfo(KEY_1, false, 5, 2, 1, DateTimeUtils.parseISODateTimeWithMinutePrecise("2014-12-22T12:55"), true, 60000, null); indexingInfo1.finishedOK = true; tested.writeActivityLogRecord(indexingInfo1); // #56 - newer record from another river name to be sure correct one is readed SpaceIndexingInfo indexingInfo1OtherRiver = new SpaceIndexingInfo(KEY_1, false, 5, 2, 1, DateTimeUtils.parseISODateTimeWithMinutePrecise("2014-12-22T12:56"), true, 60000, null); indexingInfo1OtherRiver.finishedOK = true; tested.client.prepareIndex(tested.activityLogIndexName, tested.activityLogTypeName) .setSource(indexingInfo1OtherRiver.buildDocument(jsonBuilder(), "other_river", true, true)).execute() .actionGet(); SpaceIndexingInfo indexingInfo2 = new SpaceIndexingInfo(KEY_2, false, 8, 1, 0, DateTimeUtils.parseISODateTimeWithMinutePrecise("2014-12-22T12:56"), false, 60000, "error"); indexingInfo2.finishedOK = true; tested.writeActivityLogRecord(indexingInfo2); assertLastInfo(tested, indexingInfo1); assertLastInfo(tested, indexingInfo2); } finally { finalizeESClientForUnitTest(); } } private void assertLastInfo(RemoteRiver tested, SpaceIndexingInfo indexingInfoExpected) { SpaceIndexingInfo indexingInfoReal = tested.getLastSpaceIndexingInfo(indexingInfoExpected.spaceKey); Assert.assertNotNull(indexingInfoReal); Assert.assertEquals(indexingInfoExpected.startDate, indexingInfoReal.startDate); Assert.assertEquals(indexingInfoExpected.commentsDeleted, indexingInfoReal.commentsDeleted); Assert.assertEquals(indexingInfoExpected.documentsDeleted, indexingInfoReal.documentsDeleted); Assert.assertEquals(indexingInfoExpected.documentsUpdated, indexingInfoReal.documentsUpdated); Assert.assertEquals(indexingInfoExpected.documentsWithError, indexingInfoReal.documentsWithError); Assert.assertEquals(indexingInfoExpected.finishedOK, indexingInfoReal.finishedOK); Assert.assertEquals(indexingInfoExpected.fullUpdate, indexingInfoReal.fullUpdate); Assert.assertEquals(indexingInfoExpected.timeElapsed, indexingInfoReal.timeElapsed); Assert.assertEquals(indexingInfoExpected.getErrorMessage(), indexingInfoReal.getErrorMessage()); } /** * Prepare {@link RemoteRiver} instance for unit test, with Mockito moceked jiraClient and elasticSearchClient. * * @param remoteSettingsAdd additional/optional config properties to be added into <code>jira</code> configuration * node * @return instance for tests * @throws Exception from constructor */ protected RemoteRiver prepareRiverInstanceForTest(Map<String, Object> remoteSettingsAdd) throws Exception { Map<String, Object> topLevelSettings = new HashMap<String, Object>(); extendToplevelSettingsByMandatoryIndexSettings(topLevelSettings); return prepareRiverInstanceForTest("https://issues.jboss.org", remoteSettingsAdd, topLevelSettings, true); } @SuppressWarnings("unchecked") private void extendToplevelSettingsByMandatoryIndexSettings(Map<String, Object> topLevelSettings) { // fill some mandatory fields for index part not loaded from default Map<String, Object> settings = (Map<String, Object>) topLevelSettings.get("index"); if (settings == null) { settings = new HashMap<String, Object>(); topLevelSettings.put("index", settings); } settings.put(DocumentWithCommentsIndexStructureBuilder.CONFIG_FIELDS, new HashMap<String, Object>()); settings.put(DocumentWithCommentsIndexStructureBuilder.CONFIG_FILTERS, new HashMap<String, Object>()); settings.put(DocumentWithCommentsIndexStructureBuilder.CONFIG_REMOTEFIELD_DOCUMENTID, "docid"); settings.put(DocumentWithCommentsIndexStructureBuilder.CONFIG_REMOTEFIELD_UPDATED, "up"); } /** * Prepare {@link RemoteRiver} instance for unit test, with Mockito moceked jiraClient and elasticSearchClient. * * @param urlGetDocuments parameter for remote settings * @param remoteSettingsAdd additional/optional config properties to be added into <code>remote</code> configuration * node * @param toplevelSettingsAdd additional/optional config properties to be added into toplevel node. Do not add * <code>remote</code> here, will be ignored. * @param initRemoteClientMock if set to true then Mockito mock instance is created and set into * {@link RemoteRiver#remoteSystemClient} * @return instance for tests * @throws Exception from constructor */ public static RemoteRiver prepareRiverInstanceForTest(String urlGetDocuments, Map<String, Object> remoteSettingsAdd, Map<String, Object> toplevelSettingsAdd, boolean initRemoteClientMock) throws Exception { Map<String, Object> settings = new HashMap<String, Object>(); if (toplevelSettingsAdd != null) settings.putAll(toplevelSettingsAdd); if (urlGetDocuments != null || remoteSettingsAdd != null) { Map<String, Object> remoteSettings = new HashMap<String, Object>(); settings.put("remote", remoteSettings); if (remoteSettingsAdd != null) remoteSettings.putAll(remoteSettingsAdd); remoteSettings.put(GetJSONClient.CFG_URL_GET_DOCUMENTS, urlGetDocuments); remoteSettings.put(GetJSONClient.CFG_URL_GET_SPACES, urlGetDocuments); } Settings gs = mock(Settings.class); RiverSettings rs = new RiverSettings(gs, settings); Client clientMock = mock(Client.class); RemoteRiver tested = new RemoteRiver(new RiverName("remote", RIVER_NAME), rs, clientMock); if (initRemoteClientMock) { IRemoteSystemClient remoteClientMock = mock(IRemoteSystemClient.class); tested.remoteSystemClient = remoteClientMock; } return tested; } }