Skip to content

Commit

Permalink
ISPN-7714 Test full-text queries in server mode
Browse files Browse the repository at this point in the history
  • Loading branch information
anistor committed Oct 25, 2017
1 parent 0e0b6b4 commit 75a4f80
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 7 deletions.
1 change: 1 addition & 0 deletions server/integration/testsuite/build-testsuite.xml
Expand Up @@ -237,6 +237,7 @@
<transform in="standalone.xml" out="testsuite/standalone-customcs.xml" modifyInfinispan="${infinispan.parts}/customcs.xml" filtering="true"/>
<transform in="standalone.xml" out="testsuite/standalone-customtask.xml" modifyInfinispan="${infinispan.parts}/customtask.xml" filtering="true"/>
<transform in="standalone.xml" out="testsuite/standalone-custom-compat-marshaller.xml" modifyInfinispan="${infinispan.parts}/custom-compat-marshaller.xml" filtering="true"/>
<transform in="standalone.xml" out="testsuite/standalone-query-programmatic-search-mapping-provider.xml" modifyInfinispan="${infinispan.parts}/query-programmatic-search-mapping-provider.xml" filtering="true"/>
<transform in="standalone.xml" out="testsuite/standalone-off-heap.xml" modifyInfinispan="${infinispan.parts}/off-heap.xml"/>
<transform in="clustered.xml" out="testsuite/clustered-expiration.xml" modifyInfinispan="${infinispan.parts}/expiration.xml"/>
<transform in="standalone.xml" out="testsuite/standalone-cachecontainer.xml"
Expand Down
Expand Up @@ -43,22 +43,22 @@ public class RemoteQueryCompatModeIT {

private static RemoteCacheManager remoteCacheManager;

@InfinispanResource("standalone-custom-compat-marshaller")
@InfinispanResource("custom-compat-marshaller")
RemoteInfinispanServer server1;

@BeforeClass
public static void before() throws Exception {
// We put the entity class in one jar and the marshaller in another jar, just to make things more interesting.
JavaArchive entityArchive = ShrinkWrap.create(JavaArchive.class)
.addClasses(TestEntity.class)
.add(new StringAsset("Dependencies: org.hibernate.search.engine"), "META-INF/MANIFEST.MF"); // we need the HS annotations
.add(new StringAsset("Dependencies: org.hibernate.search.engine"), "META-INF/MANIFEST.MF"); // we need the Hibernate Search annotations

JavaArchive marshallerArchive = ShrinkWrap.create(JavaArchive.class)
.addClasses(CustomCompatModeMarshaller.class)
.add(new StringAsset("Dependencies: org.jboss.marshalling, " +
"org.infinispan.commons, " +
"org.infinispan.remote-query.client, " +
"deployment.custom-test-entity.jar"), // We depend on the jar containing the entity, so we can instantiate it.
"org.infinispan.commons, " +
"org.infinispan.remote-query.client, " +
"deployment.custom-test-entity.jar"), // We depend on the jar containing the entity, so we can instantiate it.
"META-INF/MANIFEST.MF")
.addAsServiceProvider(Marshaller.class, CustomCompatModeMarshaller.class);

Expand All @@ -75,7 +75,7 @@ public static void release() {
}

@Test
@WithRunningServer(@RunningServer(name = "standalone-custom-compat-marshaller"))
@WithRunningServer(@RunningServer(name = "custom-compat-marshaller"))
public void testCompatQuery() throws Exception {
remoteCacheManager = ITestUtils.createCacheManager(server1);
RemoteCache<Integer, TestEntity> remoteCache = remoteCacheManager.getCache();
Expand Down
@@ -0,0 +1,145 @@
package org.infinispan.server.test.query;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.util.Date;
import java.util.List;

import org.apache.lucene.analysis.core.LowerCaseFilterFactory;
import org.apache.lucene.analysis.core.StopFilterFactory;
import org.apache.lucene.analysis.standard.StandardFilterFactory;
import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
import org.hibernate.search.cfg.SearchMapping;
import org.infinispan.Cache;
import org.infinispan.arquillian.core.InfinispanResource;
import org.infinispan.arquillian.core.RemoteInfinispanServer;
import org.infinispan.arquillian.core.RunningServer;
import org.infinispan.arquillian.core.WithRunningServer;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.Search;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
import org.infinispan.commons.util.Util;
import org.infinispan.protostream.sampledomain.Transaction;
import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
import org.infinispan.query.dsl.Query;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.remote.client.ProtobufMetadataManagerConstants;
import org.infinispan.query.spi.ProgrammaticSearchMappingProvider;
import org.infinispan.server.test.category.Queries;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

/**
* Test for full-text remote queries over HotRod. A ProgrammaticSearchMappingProvider is used to define the analyzers.
*
* @author anistor@redhat.com
* @since 9.2
*/
@RunWith(Arquillian.class)
@Category(Queries.class)
public class RemoteQueryStringIT {

private static RemoteCacheManager remoteCacheManager;

@InfinispanResource("query-programmatic-search-mapping-provider")
RemoteInfinispanServer server1;

@BeforeClass
public static void before() throws Exception {
JavaArchive programmaticSearchMappingProviderArchive = ShrinkWrap.create(JavaArchive.class)
.addClass(TestAnalyzerProvider.class)
.addClass(TestSearchMappingFactory.class)
.addClass(TestSearchMappingFactory.MySearchableEntity.class)
.add(new StringAsset("Dependencies: org.infinispan.query, org.hibernate.search.engine"), "META-INF/MANIFEST.MF")
.addAsServiceProvider(ProgrammaticSearchMappingProvider.class, TestAnalyzerProvider.class);

String serverDir = System.getProperty("server1.dist");
programmaticSearchMappingProviderArchive.as(ZipExporter.class)
.exportTo(new File(serverDir, "/standalone/deployments/test-ProgrammaticSearchMappingProvider.jar"), true);
}

@AfterClass
public static void release() {
if (remoteCacheManager != null) {
remoteCacheManager.stop();
}
}

@Test
@WithRunningServer(@RunningServer(name = "query-programmatic-search-mapping-provider"))
public void testFullTextTermRightOperandAnalyzed() throws Exception {
ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
clientBuilder.addServer()
.host(server1.getHotrodEndpoint().getInetAddress().getHostName())
.port(server1.getHotrodEndpoint().getPort())
.marshaller(new ProtoStreamMarshaller());
remoteCacheManager = new RemoteCacheManager(clientBuilder.build());

//initialize server-side serialization context
RemoteCache<String, String> metadataCache = remoteCacheManager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
metadataCache.put("sample_bank_account/bank.proto", Util.read(getClass().getResourceAsStream("/sample_bank_account/bank.proto")));
assertFalse(metadataCache.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));

//initialize client-side serialization context
MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));

RemoteCache<Integer, Transaction> remoteCache = remoteCacheManager.getCache();
remoteCache.clear();

remoteCache.put(1, createTransaction1());

QueryFactory qf = Search.getQueryFactory(remoteCache);
Query q = qf.create("from sample_bank_account.Transaction where longDescription:'RENT'");

List<Transaction> list = q.list();
assertNotNull(list);
assertEquals(1, list.size());
assertEquals(Transaction.class, list.get(0).getClass());
assertTransaction1(list.get(0));
}

private Transaction createTransaction1() {
Transaction tx = new Transaction();
tx.setId(1);
tx.setAccountId(777);
tx.setAmount(500);
tx.setDate(new Date(1));
tx.setDescription("February rent");
tx.setLongDescription("February rent");
return tx;
}

private void assertTransaction1(Transaction tx) {
assertNotNull(tx);
assertEquals(1, tx.getId());
assertEquals(777, tx.getAccountId());
assertEquals(500, tx.getAmount(), 0);
assertEquals(new Date(1), tx.getDate());
assertNotNull("February rent", tx.getDescription());
assertNotNull("february rent", tx.getLongDescription());
}

public static final class TestAnalyzerProvider implements ProgrammaticSearchMappingProvider {

@Override
public void defineMappings(Cache cache, SearchMapping searchMapping) {
searchMapping.analyzerDef("standard", StandardTokenizerFactory.class)
.filter(StandardFilterFactory.class)
.filter(LowerCaseFilterFactory.class)
.filter(StopFilterFactory.class);
}
}
}
@@ -0,0 +1,41 @@
package org.infinispan.server.test.query;

import org.hibernate.search.annotations.Factory;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.cfg.SearchMapping;

/**
* A factory for {@link SearchMapping}s for testing.
*
* @author anistor@redhat.com
*/
public class TestSearchMappingFactory {

public TestSearchMappingFactory() {
}

@SuppressWarnings("unused")
@Factory
public SearchMapping buildSearchMapping() {
SearchMapping searchMapping = new SearchMapping();
searchMapping.entity(MySearchableEntity.class);
return searchMapping;
}

@Indexed
public static class MySearchableEntity {

@Field
public int i;

public MySearchableEntity(int i) {
this.i = i;
}

@Override
public String toString() {
return "MySearchableEntity{i=" + i + '}';
}
}
}
17 changes: 16 additions & 1 deletion server/integration/testsuite/src/test/resources/arquillian.xml
Expand Up @@ -1335,7 +1335,7 @@
<property name="jmxDomain">${server.jmx.domain}</property>
</configuration>
</container>
<container qualifier="standalone-custom-compat-marshaller" mode="manual">
<container qualifier="custom-compat-marshaller" mode="manual">
<configuration>
<property name="javaHome">${server.jvm}</property>
<property name="jbossHome">${server1.dist}</property>
Expand All @@ -1350,6 +1350,21 @@
<property name="jmxDomain">${server.jmx.domain}</property>
</configuration>
</container>
<container qualifier="query-programmatic-search-mapping-provider" mode="manual">
<configuration>
<property name="javaHome">${server.jvm}</property>
<property name="jbossHome">${server1.dist}</property>
<property name="managementAddress">${node0.ip}</property>
<property name="serverConfig">testsuite/standalone-query-programmatic-search-mapping-provider.xml</property>
<property name="javaVmArguments">${server.jvm.args} -Djboss.node.name=node0
-Djboss.bind.address.management=${node0.ip} -Djboss.bind.address=${node0.ip}
-Djboss.socket.binding.port-offset=400 -Djgroups.join_timeout=2000
</property>
<property name="managementPort">10390</property>
<property name="waitForPorts">11622 8480</property>
<property name="jmxDomain">${server.jmx.domain}</property>
</configuration>
</container>
</group>

<group qualifier="suite-client-local">
Expand Down
@@ -1,5 +1,43 @@
<subsystem xmlns="urn:infinispan:server:core:9.2">
<cache-container name="local" default-cache="default">
<modules>
<module name="deployment.custom-test-entity.jar"/>
</modules>
<local-cache name="default">
<compatibility enabled="true" marshaller="deployment.custom-compat-marshaller.jar:main:org.infinispan.server.test.query.RemoteQueryCompatModeIT$CustomCompatModeMarshaller"/>
<indexing index="ALL">
<indexed-entities>
<indexed-entity>org.infinispan.server.test.query.TestEntity</indexed-entity>
<!-- Alternatively, this could have been configured using a fully qualified class name -->
<!-- including the module spec (if the module was not listed in the global list). -->
<!-- <indexed-entity>deployment.custom-test-entity.jar:main:org.infinispan.server.test.query.TestEntity</indexed-entity> -->
</indexed-entities>
<property name="default.directory_provider">local-heap</property>
</indexing>
</local-cache>
<local-cache name="memcachedCache"/>
</cache-container>

<!-- Test parsing of alternative config-->
<cache-container name="local_2" default-cache="default">
<modules>
<module name="deployment.custom-test-entity.jar"/>
<module name="deployment.custom-compat-marshaller.jar"/>
</modules>
<local-cache name="default">
<compatibility enabled="true" marshaller="org.infinispan.server.test.query.RemoteQueryCompatModeIT$CustomCompatModeMarshaller"/>
<indexing index="ALL">
<indexed-entities>
<indexed-entity>org.infinispan.server.test.query.TestEntity</indexed-entity>
</indexed-entities>
<property name="default.directory_provider">local-heap</property>
</indexing>
</local-cache>
<local-cache name="memcachedCache"/>
</cache-container>

<!-- Test parsing of alternative config-->
<cache-container name="local_3" default-cache="default">
<local-cache name="default">
<compatibility enabled="true" marshaller="deployment.custom-compat-marshaller.jar:main:org.infinispan.server.test.query.RemoteQueryCompatModeIT$CustomCompatModeMarshaller"/>
<indexing index="ALL">
Expand Down
@@ -0,0 +1,15 @@
<subsystem xmlns="urn:infinispan:server:core:9.2">
<cache-container name="local" default-cache="default">
<modules>
<module name="deployment.test-ProgrammaticSearchMappingProvider.jar"/>
</modules>
<local-cache name="default">
<indexing index="ALL">
<property name="default.directory_provider">local-heap</property>
<!-- Demonstrate that Hibernate Search is able to load a model mapping from global classloader -->
<property name="hibernate.search.model_mapping">org.infinispan.server.test.query.TestSearchMappingFactory</property>
</indexing>
</local-cache>
<local-cache name="memcachedCache"/>
</cache-container>
</subsystem>

0 comments on commit 75a4f80

Please sign in to comment.