Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HSEARCH-3764 Allow disabling conversion in the ID predicate #2152

Merged
merged 3 commits into from Nov 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -8,15 +8,15 @@

import org.hibernate.search.util.common.reporting.EventContext;

public class ElasticsearchFailingCompatibilityChecker<T> implements ElasticsearchCompatibilityChecker {
public class ElasticsearchFailingFieldCompatibilityChecker<T> implements ElasticsearchCompatibilityChecker {

private final String absoluteFieldPath;
private final IndexSchemaFieldNodeComponentRetrievalStrategy<T> componentRetrievalStrategy;
private final T component1;
private final T component2;
private final EventContext eventContext;

public ElasticsearchFailingCompatibilityChecker(String absoluteFieldPath, T component1, T component2, EventContext eventContext,
public ElasticsearchFailingFieldCompatibilityChecker(String absoluteFieldPath, T component1, T component2, EventContext eventContext,
IndexSchemaFieldNodeComponentRetrievalStrategy<T> componentRetrievalStrategy) {
this.absoluteFieldPath = absoluteFieldPath;
this.component1 = component1;
Expand Down
@@ -0,0 +1,44 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.scope.model.impl;

import java.lang.invoke.MethodHandles;

import org.hibernate.search.backend.elasticsearch.logging.impl.Log;
import org.hibernate.search.engine.backend.types.converter.spi.ToDocumentIdentifierValueConverter;
import org.hibernate.search.util.common.logging.impl.LoggerFactory;
import org.hibernate.search.util.common.reporting.EventContext;

public class ElasticsearchFailingIdCompatibilityChecker implements ElasticsearchCompatibilityChecker {

private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );

private final ToDocumentIdentifierValueConverter<?> identifierValueConverter1;
private final ToDocumentIdentifierValueConverter<?> identifierValueConverter2;
private final EventContext eventContext;

ElasticsearchFailingIdCompatibilityChecker(ToDocumentIdentifierValueConverter<?> identifierValueConverter1,
ToDocumentIdentifierValueConverter<?> identifierValueConverter2,
EventContext eventContext) {
this.identifierValueConverter1 = identifierValueConverter1;
this.identifierValueConverter2 = identifierValueConverter2;
this.eventContext = eventContext;
}

@Override
public void failIfNotCompatible() {
throw log.conflictingIdentifierTypesForPredicate(
identifierValueConverter1, identifierValueConverter2, eventContext
);
}

@Override
public ElasticsearchCompatibilityChecker combine(ElasticsearchCompatibilityChecker other) {
// failing + any = failing
return this;
}
}
Expand Up @@ -57,26 +57,38 @@ public EventContext getIndexesEventContext() {
return EventContexts.fromIndexNames( hibernateSearchIndexNames );
}

public ToDocumentIdentifierValueConverter<?> getIdDslConverter() {
public ElasticsearchScopedIndexRootComponent<ToDocumentIdentifierValueConverter<?>> getIdDslConverter() {
Iterator<ElasticsearchIndexModel> iterator = indexModels.iterator();
ElasticsearchIndexModel indexModelForSelectedIdConverter = iterator.next();
ToDocumentIdentifierValueConverter<?> selectedIdConverter = indexModelForSelectedIdConverter.getIdDslConverter();
ElasticsearchIndexModel indexModelForSelectedIdConverter = null;
ToDocumentIdentifierValueConverter<?> selectedIdConverter = null;
ElasticsearchScopedIndexRootComponent<ToDocumentIdentifierValueConverter<?>> scopedIndexFieldComponent =
new ElasticsearchScopedIndexRootComponent<>();

while ( iterator.hasNext() ) {
ElasticsearchIndexModel indexModel = iterator.next();
ToDocumentIdentifierValueConverter<?> idConverter = indexModel.getIdDslConverter();

if ( selectedIdConverter == null ) {
indexModelForSelectedIdConverter = indexModel;
selectedIdConverter = idConverter;
scopedIndexFieldComponent.setComponent( selectedIdConverter );
continue;
}

if ( !selectedIdConverter.isCompatibleWith( idConverter ) ) {
throw log.conflictingIdentifierTypesForPredicate(
selectedIdConverter, idConverter,
EventContexts.fromIndexNames(
indexModelForSelectedIdConverter.getHibernateSearchIndexName(),
indexModel.getHibernateSearchIndexName()
)
);
ElasticsearchFailingIdCompatibilityChecker failingCompatibilityChecker =
new ElasticsearchFailingIdCompatibilityChecker(
selectedIdConverter, idConverter,
EventContexts.fromIndexNames(
indexModelForSelectedIdConverter.getHibernateSearchIndexName(),
indexModel.getHibernateSearchIndexName()
)
);
scopedIndexFieldComponent.setIdConverterCompatibilityChecker( failingCompatibilityChecker );
}
}

return selectedIdConverter;
return scopedIndexFieldComponent;
}

public <T> ElasticsearchScopedIndexFieldComponent<T> getSchemaNodeComponent(String absoluteFieldPath,
Expand Down Expand Up @@ -110,7 +122,7 @@ public <T> ElasticsearchScopedIndexFieldComponent<T> getSchemaNodeComponent(Stri
)
);
}
ElasticsearchFailingCompatibilityChecker<T> failingCompatibilityChecker = new ElasticsearchFailingCompatibilityChecker<>(
ElasticsearchFailingFieldCompatibilityChecker<T> failingCompatibilityChecker = new ElasticsearchFailingFieldCompatibilityChecker<>(
absoluteFieldPath, scopedIndexFieldComponent.getComponent(), component, EventContexts.fromIndexNames(
indexModelForSelectedSchemaNode.getHibernateSearchIndexName(), indexModel.getHibernateSearchIndexName()
), componentRetrievalStrategy );
Expand Down
@@ -0,0 +1,29 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.scope.model.impl;

public class ElasticsearchScopedIndexRootComponent<T> {

private T component;
private ElasticsearchCompatibilityChecker idConverterCompatibilityChecker = new ElasticsearchSucceedingCompatibilityChecker();

public T getComponent() {
return component;
}

public ElasticsearchCompatibilityChecker getIdConverterCompatibilityChecker() {
return idConverterCompatibilityChecker;
}

void setComponent(T component) {
this.component = component;
}

void setIdConverterCompatibilityChecker(ElasticsearchCompatibilityChecker idConverterCompatibilityChecker) {
this.idConverterCompatibilityChecker = idConverterCompatibilityChecker;
}
}
Expand Up @@ -11,9 +11,12 @@

import org.hibernate.search.backend.elasticsearch.gson.impl.JsonAccessor;
import org.hibernate.search.backend.elasticsearch.gson.impl.JsonObjectAccessor;
import org.hibernate.search.backend.elasticsearch.scope.model.impl.ElasticsearchCompatibilityChecker;
import org.hibernate.search.backend.elasticsearch.search.impl.ElasticsearchSearchContext;
import org.hibernate.search.engine.backend.types.converter.spi.StringToDocumentIdentifierValueConverter;
import org.hibernate.search.engine.backend.types.converter.spi.ToDocumentIdentifierValueConverter;
import org.hibernate.search.engine.backend.types.converter.runtime.spi.ToDocumentIdentifierValueConvertContext;
import org.hibernate.search.engine.search.common.ValueConvert;
import org.hibernate.search.engine.search.predicate.spi.MatchIdPredicateBuilder;

import com.google.gson.JsonArray;
Expand Down Expand Up @@ -42,25 +45,33 @@
public class ElasticsearchMatchIdPredicateBuilder extends AbstractElasticsearchSearchPredicateBuilder
implements MatchIdPredicateBuilder<ElasticsearchSearchPredicateBuilder> {

private static final StringToDocumentIdentifierValueConverter RAW_CONVERTER =
new StringToDocumentIdentifierValueConverter();

private static final JsonObjectAccessor IDS_ACCESSOR = JsonAccessor.root().property( "ids" ).asObject();
private static final JsonAccessor<JsonElement> VALUES_ACCESSOR = JsonAccessor.root().property( "values" );

private final ElasticsearchSearchContext searchContext;

private final ToDocumentIdentifierValueConverter<?> idDslConverter;
private final ElasticsearchCompatibilityChecker converterChecker;
private final ToDocumentIdentifierValueConverter<?> converter;

private final List<String> values = new ArrayList<>();

public ElasticsearchMatchIdPredicateBuilder(ElasticsearchSearchContext searchContext,
ToDocumentIdentifierValueConverter<?> idDslConverter) {
ElasticsearchMatchIdPredicateBuilder(ElasticsearchSearchContext searchContext,
ElasticsearchCompatibilityChecker converterChecker,
ToDocumentIdentifierValueConverter<?> converter) {
this.searchContext = searchContext;
this.idDslConverter = idDslConverter;
this.converterChecker = converterChecker;
this.converter = converter;
}

@Override
public void value(Object value) {
ToDocumentIdentifierValueConvertContext toDocumentIdentifierValueConvertContext = searchContext.getToDocumentIdentifierValueConvertContext();
values.add( idDslConverter.convertUnknown( value, toDocumentIdentifierValueConvertContext ) );
public void value(Object value, ValueConvert valueConvert) {
ToDocumentIdentifierValueConverter<?> dslToDocumentIdConverter =
getDslToDocumentIdentifierConverter( valueConvert );
ToDocumentIdentifierValueConvertContext toDocumentIdentifierValueConvertContext =
searchContext.getToDocumentIdentifierValueConvertContext();
values.add( dslToDocumentIdConverter.convertUnknown( value, toDocumentIdentifierValueConvertContext ) );
}

@Override
Expand All @@ -81,4 +92,15 @@ private JsonArray convert(List<String> list, String tenantId) {
}
return jsonArray;
}

private ToDocumentIdentifierValueConverter<?> getDslToDocumentIdentifierConverter(ValueConvert convert) {
switch ( convert ) {
case NO:
return RAW_CONVERTER;
case YES:
default:
converterChecker.failIfNotCompatible();
return converter;
}
}
}
Expand Up @@ -11,10 +11,12 @@
import org.hibernate.search.backend.elasticsearch.document.model.impl.ElasticsearchIndexSchemaFieldNode;
import org.hibernate.search.backend.elasticsearch.logging.impl.Log;
import org.hibernate.search.backend.elasticsearch.scope.model.impl.ElasticsearchScopedIndexFieldComponent;
import org.hibernate.search.backend.elasticsearch.scope.model.impl.ElasticsearchScopedIndexRootComponent;
import org.hibernate.search.backend.elasticsearch.search.impl.ElasticsearchSearchContext;
import org.hibernate.search.backend.elasticsearch.scope.model.impl.ElasticsearchScopeModel;
import org.hibernate.search.backend.elasticsearch.scope.model.impl.IndexSchemaFieldNodeComponentRetrievalStrategy;
import org.hibernate.search.backend.elasticsearch.types.predicate.impl.ElasticsearchFieldPredicateBuilderFactory;
import org.hibernate.search.engine.backend.types.converter.spi.ToDocumentIdentifierValueConverter;
import org.hibernate.search.engine.search.predicate.SearchPredicate;
import org.hibernate.search.engine.search.predicate.spi.BooleanPredicateBuilder;
import org.hibernate.search.engine.search.predicate.spi.ExistsPredicateBuilder;
Expand Down Expand Up @@ -83,7 +85,10 @@ public MatchAllPredicateBuilder<ElasticsearchSearchPredicateBuilder> matchAll()

@Override
public MatchIdPredicateBuilder<ElasticsearchSearchPredicateBuilder> id() {
return new ElasticsearchMatchIdPredicateBuilder( searchContext, scopeModel.getIdDslConverter() );
ElasticsearchScopedIndexRootComponent<ToDocumentIdentifierValueConverter<?>> component = scopeModel.getIdDslConverter();
return new ElasticsearchMatchIdPredicateBuilder(
searchContext, component.getIdConverterCompatibilityChecker(), component.getComponent()
);
}

@Override
Expand Down
Expand Up @@ -8,15 +8,15 @@

import org.hibernate.search.util.common.reporting.EventContext;

public class LuceneFailingCompatibilityChecker<T> implements LuceneCompatibilityChecker {
public class LuceneFailingFieldCompatibilityChecker<T> implements LuceneCompatibilityChecker {

private final String absoluteFieldPath;
private final IndexSchemaFieldNodeComponentRetrievalStrategy<T> componentRetrievalStrategy;
private final T component1;
private final T component2;
private final EventContext eventContext;

public LuceneFailingCompatibilityChecker(String absoluteFieldPath, T component1, T component2, EventContext eventContext,
public LuceneFailingFieldCompatibilityChecker(String absoluteFieldPath, T component1, T component2, EventContext eventContext,
IndexSchemaFieldNodeComponentRetrievalStrategy<T> componentRetrievalStrategy) {
this.absoluteFieldPath = absoluteFieldPath;
this.component1 = component1;
Expand Down
@@ -0,0 +1,44 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.lucene.scope.model.impl;

import java.lang.invoke.MethodHandles;

import org.hibernate.search.backend.lucene.logging.impl.Log;
import org.hibernate.search.engine.backend.types.converter.spi.ToDocumentIdentifierValueConverter;
import org.hibernate.search.util.common.logging.impl.LoggerFactory;
import org.hibernate.search.util.common.reporting.EventContext;

public class LuceneFailingIdCompatibilityChecker implements LuceneCompatibilityChecker {

private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );

private final ToDocumentIdentifierValueConverter<?> identifierValueConverter1;
private final ToDocumentIdentifierValueConverter<?> identifierValueConverter2;
private final EventContext eventContext;

public LuceneFailingIdCompatibilityChecker(ToDocumentIdentifierValueConverter<?> identifierValueConverter1,
ToDocumentIdentifierValueConverter<?> identifierValueConverter2,
EventContext eventContext) {
this.identifierValueConverter1 = identifierValueConverter1;
this.identifierValueConverter2 = identifierValueConverter2;
this.eventContext = eventContext;
}

@Override
public void failIfNotCompatible() {
throw log.conflictingIdentifierTypesForPredicate(
identifierValueConverter1, identifierValueConverter2, eventContext
);
}

@Override
public LuceneCompatibilityChecker combine(LuceneCompatibilityChecker other) {
// failing + any = failing
return this;
}
}
Expand Up @@ -54,26 +54,38 @@ public Set<LuceneScopeIndexManagerContext> getIndexManagerContexts() {
return indexManagerContexts;
}

public ToDocumentIdentifierValueConverter<?> getIdDslConverter() {
public LuceneScopedIndexRootComponent<ToDocumentIdentifierValueConverter<?>> getIdDslConverter() {
Iterator<LuceneIndexModel> iterator = indexModels.iterator();
LuceneIndexModel indexModelForSelectedIdConverter = iterator.next();
ToDocumentIdentifierValueConverter<?> selectedIdConverter = indexModelForSelectedIdConverter.getIdDslConverter();
LuceneIndexModel indexModelForSelectedIdConverter = null;
ToDocumentIdentifierValueConverter<?> selectedIdConverter = null;
LuceneScopedIndexRootComponent<ToDocumentIdentifierValueConverter<?>> scopedIndexFieldComponent =
new LuceneScopedIndexRootComponent<>();

while ( iterator.hasNext() ) {
LuceneIndexModel indexModel = iterator.next();
ToDocumentIdentifierValueConverter<?> idConverter = indexModel.getIdDslConverter();

if ( selectedIdConverter == null ) {
indexModelForSelectedIdConverter = indexModel;
selectedIdConverter = idConverter;
scopedIndexFieldComponent.setComponent( selectedIdConverter );
continue;
}

if ( !selectedIdConverter.isCompatibleWith( idConverter ) ) {
throw log.conflictingIdentifierTypesForPredicate(
selectedIdConverter, idConverter,
EventContexts.fromIndexNames(
indexModelForSelectedIdConverter.getIndexName(),
indexModel.getIndexName()
)
);
LuceneFailingIdCompatibilityChecker failingCompatibilityChecker =
new LuceneFailingIdCompatibilityChecker(
selectedIdConverter, idConverter,
EventContexts.fromIndexNames(
indexModelForSelectedIdConverter.getIndexName(),
indexModel.getIndexName()
)
);
scopedIndexFieldComponent.setIdConverterCompatibilityChecker( failingCompatibilityChecker );
}
}

return selectedIdConverter;
return scopedIndexFieldComponent;
}

public LuceneObjectPredicateBuilderFactory getObjectPredicateBuilderFactory(String absoluteFieldPath) {
Expand Down Expand Up @@ -159,7 +171,7 @@ public <T> LuceneScopedIndexFieldComponent<T> getSchemaNodeComponent(String abso
);
}

LuceneFailingCompatibilityChecker<T> failingCompatibilityChecker = new LuceneFailingCompatibilityChecker<>(
LuceneFailingFieldCompatibilityChecker<T> failingCompatibilityChecker = new LuceneFailingFieldCompatibilityChecker<>(
absoluteFieldPath, scopedIndexFieldComponent.getComponent(), component, EventContexts.fromIndexNames(
indexModelForSelectedSchemaNode.getIndexName(), indexModel.getIndexName()
), componentRetrievalStrategy );
Expand Down