package alien4cloud.component.dao; import static org.junit.Assert.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.mapping.MappingBuilder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import alien4cloud.dao.ElasticSearchDAO; import alien4cloud.dao.IGenericSearchDAO; import alien4cloud.dao.model.FacetedSearchFacet; import alien4cloud.dao.model.FacetedSearchResult; import alien4cloud.dao.model.GetMultipleDataResult; import alien4cloud.exception.IndexingServiceException; import alien4cloud.model.common.Tag; import org.alien4cloud.tosca.model.definitions.CapabilityDefinition; import org.alien4cloud.tosca.model.types.NodeType; import org.alien4cloud.tosca.model.definitions.RequirementDefinition; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; /** * * Test class for Search operation on ElasticSearch * * @author 'Igor Ngouagna' * */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application-context-test.xml") @Slf4j public class EsDaoSearchTest extends AbstractDAOTest { private final ObjectMapper jsonMapper = new ObjectMapper(); @Resource(name = "alien-es-dao") IGenericSearchDAO dao; List<NodeType> dataTest = new ArrayList<>(); NodeType indexedNodeTypeTest = null; NodeType indexedNodeTypeTest2 = null; NodeType indexedNodeTypeTest3 = null; NodeType indexedNodeTypeTest4 = null; private List<Tag> threeTags = Lists.newArrayList(new Tag("icon", "my-icon.png"), new Tag("tag1", "My free tag with my free content (tag-0)"), new Tag( "tag2", "Tag2 content")); @Before public void before() throws Exception { super.before(); prepareToscaElement(); saveDataToES(true); } @Test public void simpleSearchTest() throws IndexingServiceException, InterruptedException, IOException { // test simple find all search GetMultipleDataResult searchResp = dao.find(NodeType.class, null, 10); assertNotNull(searchResp); assertEquals(4, searchResp.getTypes().length); assertEquals(4, searchResp.getData().length); // test simple find with filters Map<String, String[]> filters = new HashMap<String, String[]>(); filters.put("capabilities.type", new String[] { "container" }); searchResp = dao.find(NodeType.class, filters, 10); assertNotNull(searchResp); assertNotNull(searchResp.getTypes()); assertNotNull(searchResp.getData()); assertEquals(2, searchResp.getTypes().length); assertEquals(2, searchResp.getData().length); } @Test public void searchInTagsTest() throws IndexingServiceException, InterruptedException, IOException { // test simple find all search GetMultipleDataResult searchResp = dao.find(NodeType.class, null, 10); assertNotNull(searchResp); assertEquals(4, searchResp.getTypes().length); assertEquals(4, searchResp.getData().length); // test simple find with filters Map<String, String[]> filters = new HashMap<String, String[]>(); filters.put("tags", new String[] { "My" }); searchResp = dao.find(NodeType.class, filters, 10); assertNotNull(searchResp); assertNotNull(searchResp.getTypes()); assertNotNull(searchResp.getData()); assertEquals(4, searchResp.getTypes().length); assertEquals(4, searchResp.getData().length); } @Test public void textBasedSearch() throws IndexingServiceException, JsonParseException, JsonMappingException, IOException, InterruptedException { // text search based String searchText = "positive"; GetMultipleDataResult searchResp = dao.search(NodeType.class, searchText, null, 10); assertNotNull(searchResp); assertEquals(2, searchResp.getTypes().length); assertEquals(2, searchResp.getData().length); String[] ids = new String[] { indexedNodeTypeTest.getId(), indexedNodeTypeTest4.getId() }; for (int i = 0; i < searchResp.getData().length; i++) { NodeType idnt = (NodeType) searchResp.getData()[i]; assertElementIn(idnt.getId(), ids); } // text search based with filters Map<String, String[]> filters = new HashMap<String, String[]>(); filters.put("capabilities.type", new String[] { "container" }); searchResp = dao.search(NodeType.class, searchText, filters, 10); assertNotNull(searchResp); assertNotNull(searchResp.getTypes()); assertNotNull(searchResp.getData()); assertEquals(1, searchResp.getTypes().length); assertEquals(1, searchResp.getData().length); NodeType idnt = (NodeType) searchResp.getData()[0]; assertElementIn(idnt.getElementId(), new String[] { "1" }); // test nothing found searchText = "pacpac"; searchResp = dao.search(NodeType.class, searchText, null, 10); assertNotNull(searchResp); assertNotNull(searchResp.getData()); assertNotNull(searchResp.getTypes()); assertEquals(0, searchResp.getData().length); assertEquals(0, searchResp.getTypes().length); } @Test public void facetedSearchTest() throws IndexingServiceException, JsonParseException, JsonMappingException, IOException, InterruptedException { String searchText = "positive"; FacetedSearchResult searchResp = dao.facetedSearch(NodeType.class, searchText, null, 10); assertNotNull(searchResp); assertEquals(2, searchResp.getTotalResults()); assertEquals(2, searchResp.getTypes().length); assertEquals(2, searchResp.getData().length); String[] ids = new String[] { indexedNodeTypeTest.getId(), indexedNodeTypeTest4.getId() }; for (int i = 0; i < searchResp.getData().length; i++) { NodeType idnt = (NodeType) searchResp.getData()[i]; assertElementIn(idnt.getId(), ids); } // test facets Map<String, FacetedSearchFacet[]> mapp = searchResp.getFacets(); FacetedSearchFacet[] capaFacets = mapp.get("capabilities.type"); assertNotNull(capaFacets); boolean warExist = false; long warCount = 0; for (int i = 0; i < capaFacets.length; i++) { if (capaFacets[i].getFacetValue().equals("war")) { warExist = true; warCount = capaFacets[i].getCount(); } } assertTrue(warExist); assertEquals(2, warCount); // faceted search with filters Map<String, String[]> filters = new HashMap<String, String[]>(); filters.put("capabilities.type", new String[] { "container" }); searchResp = dao.facetedSearch(NodeType.class, searchText, filters, 10); assertNotNull(searchResp); assertEquals(1, searchResp.getTotalResults()); assertEquals(1, searchResp.getTypes().length); assertEquals(1, searchResp.getData().length); NodeType idnt = (NodeType) searchResp.getData()[0]; assertElementIn(idnt.getElementId(), new String[] { "1" }); // test nothing found searchText = "pacpac"; searchResp = dao.facetedSearch(NodeType.class, searchText, null, 10); assertNotNull(searchResp); assertNotNull(searchResp.getData()); assertNotNull(searchResp.getTypes()); assertEquals(0, searchResp.getData().length); assertEquals(0, searchResp.getTypes().length); } private void assertElementIn(Object element, Object[] elements) { assertTrue(Arrays.asList(elements).contains(element)); } private void prepareToscaElement() { List<CapabilityDefinition> capa = Arrays.asList(new CapabilityDefinition("container", "container", 1), new CapabilityDefinition("container1", "container1", 1), new CapabilityDefinition("container2", "container2", 1), new CapabilityDefinition("container3", "container3", 1), new CapabilityDefinition("war", "war", 1)); List<RequirementDefinition> req = Arrays.asList(new RequirementDefinition("Runtime", "Runtime"), new RequirementDefinition("server", "server"), new RequirementDefinition("blob", "blob")); List<String> der = Arrays.asList("Parent1", "Parent2"); indexedNodeTypeTest = TestModelUtil.createIndexedNodeType("1", "positive", "1.0", "", capa, req, der, new ArrayList<String>(), threeTags, new Date(), new Date()); dataTest.add(indexedNodeTypeTest); capa = Arrays.asList(new CapabilityDefinition("banana", "banana", 1), new CapabilityDefinition("banana1", "banana1", 1), new CapabilityDefinition( "container", "container", 1), new CapabilityDefinition("banana3", "banana3", 1), new CapabilityDefinition("zar", "zar", 1)); req = Arrays.asList(new RequirementDefinition("Pant", "Pant"), new RequirementDefinition("DBZ", "DBZ"), new RequirementDefinition("Animes", "Animes")); der = Arrays.asList("Songoku", "Kami"); indexedNodeTypeTest2 = TestModelUtil.createIndexedNodeType("2", "pokerFace", "1.0", "", capa, req, der, new ArrayList<String>(), threeTags, new Date(), new Date()); dataTest.add(indexedNodeTypeTest2); capa = Arrays.asList(new CapabilityDefinition("potatoe", "potatoe", 1), new CapabilityDefinition("potatoe2", "potatoe2", 1), new CapabilityDefinition( "potatoe3", "potatoe3", 1), new CapabilityDefinition("potatoe4", "potatoe4", 1), new CapabilityDefinition("zor", "zor", 1)); req = Arrays.asList(new RequirementDefinition("OnePiece", "OnePiece"), new RequirementDefinition("beelzebub", "beelzebub"), new RequirementDefinition( "DBGT", "DBGT")); der = Arrays.asList("Jerome", "Sandrini"); indexedNodeTypeTest3 = TestModelUtil.createIndexedNodeType("3", "nagative", "1.5", "", capa, req, der, new ArrayList<String>(), threeTags, new Date(), new Date()); dataTest.add(indexedNodeTypeTest3); capa = Arrays.asList(new CapabilityDefinition("yams", "yams", 1), new CapabilityDefinition("yams1", "yams1", 1), new CapabilityDefinition( "positiveYes", "positiveYes", 1), new CapabilityDefinition("yams3", "yams3", 1), new CapabilityDefinition("war world", "war world", 1)); req = Arrays .asList(new RequirementDefinition("Naruto", "Naruto"), new RequirementDefinition("FT", "FT"), new RequirementDefinition("Bleach", "Bleach")); der = Arrays.asList("Luc", "Boutier"); indexedNodeTypeTest4 = TestModelUtil.createIndexedNodeType("4", "pokerFace", "2.0", "", capa, req, der, new ArrayList<String>(), threeTags, new Date(), new Date()); dataTest.add(indexedNodeTypeTest4); } private void saveDataToES(boolean refresh) throws JsonProcessingException { for (NodeType datum : dataTest) { String json = jsonMapper.writeValueAsString(datum); String typeName = MappingBuilder.indexTypeFromClass(datum.getClass()); nodeClient.prepareIndex(ElasticSearchDAO.TOSCA_ELEMENT_INDEX, typeName).setSource(json).setRefresh(refresh).execute().actionGet(); assertDocumentExisit(ElasticSearchDAO.TOSCA_ELEMENT_INDEX, typeName, datum.getId(), true); } refresh(); } private void assertDocumentExisit(String indexName, String typeName, String id, boolean expected) { GetResponse response = getDocument(indexName, typeName, id); assertEquals(expected, response.isExists()); assertEquals(expected, !response.isSourceEmpty()); } private GetResponse getDocument(String indexName, String typeName, String id) { return nodeClient.prepareGet(indexName, typeName, id).execute().actionGet(); } }