/* * Copyright 2015 herd contributors * * Licensed 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.finra.herd.service.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.sql.Timestamp; import java.util.concurrent.Future; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.shard.DocsStats; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.finra.herd.core.helper.ConfigurationHelper; import org.finra.herd.dao.BusinessObjectDefinitionDao; import org.finra.herd.dao.SearchIndexDao; import org.finra.herd.dao.TagDao; import org.finra.herd.model.api.xml.SearchIndex; import org.finra.herd.model.api.xml.SearchIndexCreateRequest; import org.finra.herd.model.api.xml.SearchIndexKey; import org.finra.herd.model.api.xml.SearchIndexStatistics; import org.finra.herd.model.dto.ConfigurationValue; import org.finra.herd.model.jpa.SearchIndexEntity; import org.finra.herd.model.jpa.SearchIndexStatusEntity; import org.finra.herd.model.jpa.SearchIndexTypeEntity; import org.finra.herd.service.AbstractServiceTest; import org.finra.herd.service.SearchIndexHelperService; import org.finra.herd.service.functional.SearchFunctions; import org.finra.herd.service.helper.AlternateKeyHelper; import org.finra.herd.service.helper.BusinessObjectDefinitionHelper; import org.finra.herd.service.helper.ConfigurationDaoHelper; import org.finra.herd.service.helper.SearchIndexDaoHelper; import org.finra.herd.service.helper.SearchIndexStatusDaoHelper; import org.finra.herd.service.helper.SearchIndexTypeDaoHelper; /** * This class tests functionality within the search index service implementation. */ public class SearchIndexServiceImplTest extends AbstractServiceTest { @Mock private AlternateKeyHelper alternateKeyHelper; @Mock private BusinessObjectDefinitionDao businessObjectDefinitionDao; @Mock private BusinessObjectDefinitionHelper businessObjectDefinitionHelper; @Mock private ConfigurationDaoHelper configurationDaoHelper; @Mock private ConfigurationHelper configurationHelper; @Mock private SearchFunctions searchFunctions; @Mock private SearchIndexDao searchIndexDao; @Mock private SearchIndexDaoHelper searchIndexDaoHelper; @Mock private SearchIndexHelperService searchIndexHelperService; @InjectMocks private SearchIndexServiceImpl searchIndexServiceImpl; @Mock private SearchIndexStatusDaoHelper searchIndexStatusDaoHelper; @Mock private SearchIndexTypeDaoHelper searchIndexTypeDaoHelper; @Mock private TagDao tagDao; @Before public void before() { MockitoAnnotations.initMocks(this); } @Test public void testCreateSearchIndexEntity() { // Create a search index key. SearchIndexKey searchIndexKey = new SearchIndexKey(SEARCH_INDEX_NAME); // Create a search index create request. SearchIndexCreateRequest searchIndexCreateRequest = new SearchIndexCreateRequest(searchIndexKey, SEARCH_INDEX_TYPE); // Creates a test search index type entity. SearchIndexTypeEntity searchIndexTypeEntity = new SearchIndexTypeEntity(); searchIndexTypeEntity.setCode(SEARCH_INDEX_TYPE); // Creates a test search index status entity. SearchIndexStatusEntity searchIndexStatusEntity = new SearchIndexStatusEntity(); searchIndexStatusEntity.setCode(SEARCH_INDEX_STATUS); // Create a search index entity from the search index create request. SearchIndexEntity searchIndexEntity = searchIndexServiceImpl.createSearchIndexEntity(searchIndexCreateRequest, searchIndexTypeEntity, searchIndexStatusEntity); // Verify the external calls. verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); // Validate the returned object. assertNotNull(searchIndexEntity); assertEquals(SEARCH_INDEX_NAME, searchIndexEntity.getName()); assertNotNull(searchIndexEntity.getType()); assertEquals(SEARCH_INDEX_TYPE, searchIndexEntity.getType().getCode()); assertNotNull(searchIndexEntity.getStatus()); assertEquals(SEARCH_INDEX_STATUS, searchIndexEntity.getStatus().getCode()); assertNull(searchIndexEntity.getCreatedBy()); assertNull(searchIndexEntity.getCreatedOn()); assertNull(searchIndexEntity.getUpdatedBy()); assertNull(searchIndexEntity.getUpdatedOn()); } @Test public void testCreateSearchIndexFromEntity() { // Create a search index key. SearchIndexKey searchIndexKey = new SearchIndexKey(SEARCH_INDEX_NAME); // Creates a test search index type entity. SearchIndexTypeEntity searchIndexTypeEntity = new SearchIndexTypeEntity(); searchIndexTypeEntity.setCode(SEARCH_INDEX_TYPE); // Creates a test search index status entity. SearchIndexStatusEntity searchIndexStatusEntity = new SearchIndexStatusEntity(); searchIndexStatusEntity.setCode(SEARCH_INDEX_STATUS); // Create a test search index entity. SearchIndexEntity searchIndexEntity = new SearchIndexEntity(); searchIndexEntity.setName(SEARCH_INDEX_NAME); searchIndexEntity.setType(searchIndexTypeEntity); searchIndexEntity.setStatus(searchIndexStatusEntity); searchIndexEntity.setCreatedBy(USER_ID); searchIndexEntity.setCreatedOn(new Timestamp(CREATED_ON.toGregorianCalendar().getTimeInMillis())); searchIndexEntity.setUpdatedOn(new Timestamp(UPDATED_ON.toGregorianCalendar().getTimeInMillis())); // Create a search index object from the search index entity. SearchIndex searchIndex = searchIndexServiceImpl.createSearchIndexFromEntity(searchIndexEntity); // Verify the external calls. verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); // Validate the returned object. assertEquals(new SearchIndex(searchIndexKey, SEARCH_INDEX_TYPE, SEARCH_INDEX_STATUS, NO_SEARCH_INDEX_STATISTICS, USER_ID, CREATED_ON, UPDATED_ON), searchIndex); } @Test public void testCreateSearchIndexHelper() { // Create a search index key. SearchIndexKey searchIndexKey = new SearchIndexKey(SEARCH_INDEX_NAME); // Get the search index type value. String searchIndexType = SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name(); // Mock some of the external call responses. @SuppressWarnings("unchecked") Future<Void> mockedFuture = mock(Future.class); // Mock the external calls. when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_BDEF_DOCUMENT_TYPE, String.class)).thenReturn(SEARCH_INDEX_DOCUMENT_TYPE); when(configurationDaoHelper.getClobProperty(ConfigurationValue.ELASTICSEARCH_BDEF_MAPPINGS_JSON.getKey())).thenReturn(SEARCH_INDEX_MAPPING); when(configurationDaoHelper.getClobProperty(ConfigurationValue.ELASTICSEARCH_BDEF_SETTINGS_JSON.getKey())).thenReturn(SEARCH_INDEX_SETTINGS); when(searchFunctions.getIndexExistsFunction()).thenReturn(indexName -> true); when(searchFunctions.getDeleteIndexFunction()).thenReturn(indexName -> { }); when(searchFunctions.getCreateIndexFunction()).thenReturn((indexName, documentType, mapping, settings) -> { }); when(searchIndexHelperService.indexAllBusinessObjectDefinitions(searchIndexKey, SEARCH_INDEX_DOCUMENT_TYPE)).thenReturn(mockedFuture); // Create a search index. searchIndexServiceImpl.createSearchIndexHelper(searchIndexKey, searchIndexType); // Verify the external calls. verify(configurationHelper).getProperty(ConfigurationValue.ELASTICSEARCH_BDEF_DOCUMENT_TYPE, String.class); verify(configurationDaoHelper).getClobProperty(ConfigurationValue.ELASTICSEARCH_BDEF_MAPPINGS_JSON.getKey()); verify(configurationDaoHelper).getClobProperty(ConfigurationValue.ELASTICSEARCH_BDEF_SETTINGS_JSON.getKey()); verify(searchFunctions).getIndexExistsFunction(); verify(searchFunctions).getDeleteIndexFunction(); verify(searchFunctions).getCreateIndexFunction(); verify(searchIndexHelperService).indexAllBusinessObjectDefinitions(searchIndexKey, SEARCH_INDEX_DOCUMENT_TYPE); verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); } @Test public void testCreateSearchIndexHelperInvalidSearchIndexType() { // Try to create a search index using an invalid search index type. try { searchIndexServiceImpl.createSearchIndexHelper(new SearchIndexKey(SEARCH_INDEX_NAME), SEARCH_INDEX_TYPE); fail(); } catch (IllegalArgumentException e) { assertEquals(String.format("Search index type with code \"%s\" is not supported.", SEARCH_INDEX_TYPE), e.getMessage()); } // Verify the external calls. verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); } @Test public void testCreateSearchIndexStatisticsNoIndexCreationDate() { // Create a search index get settings response without the index creation date setting. ImmutableOpenMap<String, Settings> getIndexResponseSettings = ImmutableOpenMap.<String, Settings>builder() .fPut(SEARCH_INDEX_NAME, Settings.builder().put(IndexMetaData.SETTING_INDEX_UUID, SEARCH_INDEX_STATISTICS_INDEX_UUID).build()).build(); // Mock an index docs stats object. DocsStats mockedDocsStats = mock(DocsStats.class); when(mockedDocsStats.getCount()).thenReturn(SEARCH_INDEX_STATISTICS_NUMBER_OF_ACTIVE_DOCUMENTS); when(mockedDocsStats.getDeleted()).thenReturn(SEARCH_INDEX_STATISTICS_NUMBER_OF_DELETED_DOCUMENTS); // Get a search index settings created. SearchIndexStatistics response = searchIndexServiceImpl.createSearchIndexStatistics(getIndexResponseSettings.get(SEARCH_INDEX_NAME), mockedDocsStats); // Verify the external calls. verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); // Validate the returned object. assertEquals(new SearchIndexStatistics(NO_SEARCH_INDEX_STATISTICS_CREATION_DATE, SEARCH_INDEX_STATISTICS_NUMBER_OF_ACTIVE_DOCUMENTS, SEARCH_INDEX_STATISTICS_NUMBER_OF_DELETED_DOCUMENTS, SEARCH_INDEX_STATISTICS_INDEX_UUID), response); } @Test public void testDeleteSearchIndexHelperIndexAlreadyExists() { // Mock the external calls. when(searchFunctions.getIndexExistsFunction()).thenReturn(indexName -> true); when(searchFunctions.getDeleteIndexFunction()).thenReturn(indexName -> { }); // Call a delete index method when a search index exists. searchIndexServiceImpl.deleteSearchIndexHelper(SEARCH_INDEX_NAME); verify(searchFunctions).getIndexExistsFunction(); verify(searchFunctions).getDeleteIndexFunction(); verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); } @Test public void testDeleteSearchIndexHelperIndexNoExists() { // Mock the external calls. when(searchFunctions.getIndexExistsFunction()).thenReturn(indexName -> false); // Call a delete index method when a search index does not exists. searchIndexServiceImpl.deleteSearchIndexHelper(SEARCH_INDEX_NAME); verify(searchFunctions).getIndexExistsFunction(); verifyNoMoreInteractions(alternateKeyHelper, businessObjectDefinitionDao, businessObjectDefinitionHelper, configurationDaoHelper, configurationHelper, searchFunctions, searchIndexDao, searchIndexDaoHelper, searchIndexHelperService, searchIndexStatusDaoHelper, searchIndexTypeDaoHelper); } }