package org.infinispan.query.backend; import static org.testng.AssertJUnit.assertEquals; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.apache.lucene.search.MatchAllDocsQuery; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.backend.spi.Work; import org.hibernate.search.backend.spi.WorkType; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.Index; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.query.Search; import org.infinispan.query.impl.ComponentRegistryUtils; import org.infinispan.query.impl.DefaultSearchWorkCreator; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.annotations.Test; /** * Verifies ADD, DELETE and UPDATE behaviour under a custom {@link org.infinispan.query.backend.SearchWorkCreator} that * creates extra entities in the index */ @Test(groups = "functional", testName = "query.backend.ExtendedSearchWorkCreatorTest") public class ExtendedSearchWorkCreatorTest extends SingleCacheManagerTest { private static class ExtraValuesSearchWorkCreator extends DefaultSearchWorkCreator<Object> implements ExtendedSearchWorkCreator<Object> { @Override public Collection<Work> createPerEntityWorks(Object value, Serializable id, WorkType workType) { // Will generate extra entities based on the items List<Work> works = new LinkedList<>(super.createPerEntityWorks(value, id, workType)); Entity e = (Entity) value; for (String item : e.getItems()) { Entity newEntity = new Entity(item); works.add(new Work(newEntity, "item-" + item, workType)); } return works; } @Override public boolean shouldRemove(SearchWorkCreatorContext context) { // Always perform a remove return true; } } @Test public void testExtendedSearchCreatorForAdd() throws Exception { addCustomSearchWorkCreator(); cache.put(1, new Entity("value", "item-a", "item-b", "item-c")); assertEquals(4, numberOfIndexedEntities(Entity.class)); } @Test public void testExtendedSearchCreatorForDelete() throws Exception { addCustomSearchWorkCreator(); cache.put(1, new Entity("value", "item-a", "item-b", "item-c")); cache.remove(1); assertEquals(0, numberOfIndexedEntities(Entity.class)); } @Test public void testExtendedSearchCreatorForUpdates() throws Exception { addCustomSearchWorkCreator(); cache.put(1, new Entity("value", "item-a", "item-b", "item-c")); assertEquals(4, numberOfIndexedEntities(Entity.class)); cache.put(1, new Entity("value", "item-a")); assertEquals(2, numberOfIndexedEntities(Entity.class)); } private void addCustomSearchWorkCreator() { QueryInterceptor queryInterceptor = ComponentRegistryUtils.getQueryInterceptor(cache); queryInterceptor.setSearchWorkCreator(new ExtraValuesSearchWorkCreator()); } private int numberOfIndexedEntities(Class<?> clazz) { return Search.getSearchManager(cache).getQuery(new MatchAllDocsQuery(), clazz).getResultSize(); } @Override protected EmbeddedCacheManager createCacheManager() throws Exception { ConfigurationBuilder cfg = getDefaultStandaloneCacheConfig(false); cfg.indexing().index(Index.ALL) .addIndexedEntity(Entity.class) .addProperty("default.directory_provider", "ram") .addProperty("lucene_version", "LUCENE_CURRENT"); return TestCacheManagerFactory.createCacheManager(cfg); } @Indexed private static class Entity { @Field private String name; public String getName() { return name; } private Set<String> items = new HashSet<>(); public Set<String> getItems() { return items; } public Entity(String name, String... values) { this.name = name; Collections.addAll(items, values); } } }