package org.infinispan.query.remote.impl;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.Index;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.protostream.DescriptorParserException;
import org.infinispan.protostream.FileDescriptorSource;
import org.infinispan.protostream.SerializationContext;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.transaction.TransactionMode;
import org.testng.annotations.Test;
/**
* Test that ProtobufIndexedFieldProvider correctly identifies indexed fields based on the protostream annotations
* applied in the test model (bank.proto).
*
* @author anistor@redhat.com
* @since 9.0
*/
@Test(groups = "functional", testName = "query.remote.impl.ProtobufFieldIndexingMetadataTest")
public class ProtobufFieldIndexingMetadataTest extends SingleCacheManagerTest {
private static final String PROTO_DEFINITIONS =
"/** @Indexed */ message User {\n" +
"\n" +
" /** @IndexedField */ required string name = 1;\n" +
"\n" +
" required string surname = 2;\n" +
"\n" +
" /** @Indexed(true) */" +
" message Address {\n" +
" /** @IndexedField */ required string street = 10;\n" +
" required string postCode = 20;\n" +
" }\n" +
"\n" +
" /** @IndexedField */ repeated Address indexedAddresses = 3;\n" +
"\n" +
" /** @IndexedField(index=false, store=false) */ repeated Address unindexedAddresses = 4;\n" +
"}";
protected EmbeddedCacheManager createCacheManager() throws Exception {
ConfigurationBuilder cfg = getDefaultStandaloneCacheConfig(true);
cfg.transaction().transactionMode(TransactionMode.TRANSACTIONAL)
.indexing().index(Index.ALL)
.addProperty("default.directory_provider", "ram")
.addProperty("lucene_version", "LUCENE_CURRENT");
return TestCacheManagerFactory.createCacheManager(cfg);
}
public void testProtobufFieldIndexingMetadata() throws Exception {
SerializationContext serCtx = ProtobufMetadataManagerImpl.getSerializationContextInternal(cacheManager);
serCtx.registerProtoFiles(FileDescriptorSource.fromString("user_definition.proto", PROTO_DEFINITIONS));
ProtobufFieldIndexingMetadata userIndexedFieldProvider = new ProtobufFieldIndexingMetadata(serCtx.getMessageDescriptor("User"));
ProtobufFieldIndexingMetadata addressIndexedFieldProvider = new ProtobufFieldIndexingMetadata(serCtx.getMessageDescriptor("User.Address"));
// try top level attributes
assertTrue(userIndexedFieldProvider.isIndexed(new String[]{"name"}));
assertFalse(userIndexedFieldProvider.isIndexed(new String[]{"surname"}));
assertTrue(addressIndexedFieldProvider.isIndexed(new String[]{"street"}));
assertFalse(addressIndexedFieldProvider.isIndexed(new String[]{"postCode"}));
// try nested attributes
assertTrue(userIndexedFieldProvider.isIndexed(new String[]{"indexedAddresses", "street"}));
assertFalse(userIndexedFieldProvider.isIndexed(new String[]{"indexedAddresses", "postCode"}));
assertFalse(userIndexedFieldProvider.isIndexed(new String[]{"unindexedAddresses", "street"}));
assertFalse(userIndexedFieldProvider.isIndexed(new String[]{"unindexedAddresses", "postCode"}));
}
@Test(expectedExceptions = DescriptorParserException.class, expectedExceptionsMessageRegExp = "java.lang.IllegalStateException: Annotation 'IndexedField' cannot be used together with 'Field' on field test.User.age")
public void testIndexedFieldAndField() throws Exception {
String testProto = "package test;\n" +
"/* @Indexed */ message User {\n" +
" /* @IndexedField(index=false, store=false) @Field(store=Store.NO, index=Index.NO) */ " +
" required int32 age = 1;\n" +
"}";
SerializationContext serCtx = ProtobufMetadataManagerImpl.getSerializationContextInternal(cacheManager);
serCtx.registerProtoFiles(FileDescriptorSource.fromString("test.proto", testProto));
}
@Test(expectedExceptions = DescriptorParserException.class, expectedExceptionsMessageRegExp = "java.lang.IllegalStateException: Annotation 'IndexedField' cannot be used together with 'SortableField' on field test.User1.age")
public void testIndexedFieldAndSortableField() throws Exception {
String testProto = "package test;\n" +
"/* @Indexed */ message User1 {\n" +
" /* @IndexedField(index=false, store=false) @SortableField */ " +
" required int32 age = 1;\n" +
"}";
SerializationContext serCtx = ProtobufMetadataManagerImpl.getSerializationContextInternal(cacheManager);
serCtx.registerProtoFiles(FileDescriptorSource.fromString("test1.proto", testProto));
}
@Test(expectedExceptions = DescriptorParserException.class, expectedExceptionsMessageRegExp = "java.lang.IllegalStateException: Annotation 'IndexedField' cannot be used together with 'Analyzer' on field test.User2.name")
public void testIndexedFieldAndAnalyzer() throws Exception {
String testProto = "package test;\n" +
"/* @Indexed */" +
"message User2 {\n" +
" /* @IndexedField(index=false, store=false) @Analyzer(definition=\"standard\") */" +
" required string name = 1;\n" +
"}";
SerializationContext serCtx = ProtobufMetadataManagerImpl.getSerializationContextInternal(cacheManager);
serCtx.registerProtoFiles(FileDescriptorSource.fromString("test1.proto", testProto));
}
@Test(expectedExceptions = DescriptorParserException.class, expectedExceptionsMessageRegExp = "java.lang.IllegalStateException: Cannot specify an analyzer for field test.User3.name unless the field is analyzed.")
public void testAnalyzerForNotAnalyzedField() throws Exception {
String testProto = "package test;\n" +
"/* @Indexed */ message User3 {\n" +
" /* @Field(store=Store.NO, index=Index.YES, analyze=Analyze.NO, analyzer=@Analyzer(definition=\"standard\")) */" +
" required string name = 1;\n" +
"}";
SerializationContext serCtx = ProtobufMetadataManagerImpl.getSerializationContextInternal(cacheManager);
serCtx.registerProtoFiles(FileDescriptorSource.fromString("test2.proto", testProto));
}
}