diff --git a/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingAutomaticIndexingOutOfOrderIdsIT.java b/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingAutomaticIndexingOutOfOrderIdsIT.java index 4507c2f924d..4a94ff17b8b 100644 --- a/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingAutomaticIndexingOutOfOrderIdsIT.java +++ b/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingAutomaticIndexingOutOfOrderIdsIT.java @@ -122,7 +122,7 @@ public void processCreateUpdateDelete() { // that's because we don't trust events to tell us whether the document already exists in the index. // We don't trust the events for this because they can arrive in the wrong order // (and that's the case here). - backendMock.expectWorks( OutboxPollingAutomaticIndexingLifecycleIT.IndexedEntity.NAME ) + backendMock.expectWorks( IndexedEntity.INDEX ) .delete( "1" ); // The events were hidden until now, to ensure they were not processed in separate batches. diff --git a/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingCustomEntityMappingIT.java b/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingCustomEntityMappingIT.java new file mode 100644 index 00000000000..40e9b9a9c7a --- /dev/null +++ b/integrationtest/mapper/orm-coordination-outbox-polling/src/test/java/org/hibernate/search/integrationtest/mapper/orm/coordination/outboxpolling/automaticindexing/OutboxPollingCustomEntityMappingIT.java @@ -0,0 +1,229 @@ +/* + * 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 . + */ +package org.hibernate.search.integrationtest.mapper.orm.coordination.outboxpolling.automaticindexing; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.persistence.Basic; +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.MappingException; +import org.hibernate.resource.jdbc.spi.StatementInspector; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cluster.impl.OutboxPollingAgentAdditionalJaxbMappingProducer; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.event.impl.OutboxPollingOutboxEventAdditionalJaxbMappingProducer; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.util.impl.integrationtest.common.rule.BackendMock; +import org.hibernate.search.util.impl.integrationtest.mapper.orm.CoordinationStrategyExpectations; +import org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmSetupHelper; +import org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmUtils; + +import org.junit.Rule; +import org.junit.Test; + +public class OutboxPollingCustomEntityMappingIT { + + private static final String ORIGINAL_OUTBOX_EVENT_TABLE_NAME = OutboxPollingOutboxEventAdditionalJaxbMappingProducer.TABLE_NAME; + private static final String CUSTOM_OUTBOX_EVENT_TABLE_NAME = "CUSTOM_OUTBOX_EVENT"; + private static final String ORIGINAL_OUTBOX_EVENT_GENERATOR_NAME = ORIGINAL_OUTBOX_EVENT_TABLE_NAME + "_GENERATOR"; + private static final String CUSTOM_OUTBOX_EVENT_GENERATOR_NAME = CUSTOM_OUTBOX_EVENT_TABLE_NAME + "_GENERATOR"; + + private static final String ORIGINAL_AGENT_TABLE_NAME = OutboxPollingAgentAdditionalJaxbMappingProducer.TABLE_NAME; + private static final String CUSTOM_AGENT_TABLE_NAME = "CUSTOM_AGENT"; + private static final String ORIGINAL_AGENT_GENERATOR_NAME = ORIGINAL_AGENT_TABLE_NAME + "_GENERATOR"; + private static final String CUSTOM_AGENT_GENERATOR_NAME = CUSTOM_AGENT_TABLE_NAME + "_GENERATOR"; + + private static final String VALID_OUTBOX_EVENT_MAPPING; + private static final String VALID_AGENT_EVENT_MAPPING; + + private static final String[] SQL_KEYS; + + static { + VALID_OUTBOX_EVENT_MAPPING = OutboxPollingOutboxEventAdditionalJaxbMappingProducer.ENTITY_DEFINITION + .replace( ORIGINAL_OUTBOX_EVENT_TABLE_NAME, CUSTOM_OUTBOX_EVENT_TABLE_NAME ) + .replace( ORIGINAL_OUTBOX_EVENT_GENERATOR_NAME, CUSTOM_OUTBOX_EVENT_GENERATOR_NAME ); + + VALID_AGENT_EVENT_MAPPING = OutboxPollingAgentAdditionalJaxbMappingProducer.ENTITY_DEFINITION + .replace( ORIGINAL_AGENT_TABLE_NAME, CUSTOM_AGENT_TABLE_NAME ) + .replace( ORIGINAL_AGENT_GENERATOR_NAME, CUSTOM_AGENT_GENERATOR_NAME ); + + SQL_KEYS = new String[] { + ORIGINAL_OUTBOX_EVENT_TABLE_NAME, CUSTOM_OUTBOX_EVENT_TABLE_NAME, + ORIGINAL_OUTBOX_EVENT_GENERATOR_NAME, CUSTOM_OUTBOX_EVENT_GENERATOR_NAME, + ORIGINAL_AGENT_TABLE_NAME, CUSTOM_AGENT_TABLE_NAME, + ORIGINAL_AGENT_GENERATOR_NAME, CUSTOM_AGENT_GENERATOR_NAME + }; + } + + @Rule + public BackendMock backendMock = new BackendMock(); + + @Rule + public OrmSetupHelper ormSetupHelper = OrmSetupHelper.withBackendMock( backendMock ) + .coordinationStrategy( CoordinationStrategyExpectations.outboxPolling() ); + + private SessionFactory sessionFactory; + + @Test + public void wrongOutboxEventMapping() { + assertThatThrownBy( () -> ormSetupHelper.start() + .withProperty( "hibernate.search.coordination.outboxevent.entity.mapping", "" ) + .setup( IndexedEntity.class ) + ) + .isInstanceOf( MappingException.class ) + .hasMessageContainingAll( "Unable to perform unmarshalling", "unexpected element" ); + } + + @Test + public void wrongAgentMapping() { + assertThatThrownBy( () -> ormSetupHelper.start() + .withProperty( "hibernate.search.coordination.agent.entity.mapping", "" ) + .setup( IndexedEntity.class ) + ) + .isInstanceOf( MappingException.class ) + .hasMessageContainingAll( "Unable to perform unmarshalling", "unexpected element" ); + } + + @Test + public void validOutboxEventMapping() { + MostRecentStatementInspector statementInspector = new MostRecentStatementInspector(); + + backendMock.expectAnySchema( IndexedEntity.INDEX ); + sessionFactory = ormSetupHelper.start() + .withProperty( "hibernate.search.coordination.outboxevent.entity.mapping", VALID_OUTBOX_EVENT_MAPPING ) + .withProperty( "hibernate.session_factory.statement_inspector", statementInspector ) + .setup( IndexedEntity.class ); + backendMock.verifyExpectationsMet(); + + backendMock.expectWorks( IndexedEntity.INDEX ) + .add( "1", f -> f.field( "indexedField", "value for the field" ) ); + + int id = 1; + OrmUtils.withinTransaction( sessionFactory, session -> { + IndexedEntity entity = new IndexedEntity(); + entity.setId( id ); + entity.setIndexedField( "value for the field" ); + session.persist( entity ); + } ); + + backendMock.verifyExpectationsMet(); + + assertThat( statementInspector.countByKey( ORIGINAL_OUTBOX_EVENT_TABLE_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( CUSTOM_OUTBOX_EVENT_TABLE_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( ORIGINAL_OUTBOX_EVENT_GENERATOR_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( CUSTOM_OUTBOX_EVENT_GENERATOR_NAME ) ).isPositive(); + + assertThat( statementInspector.countByKey( ORIGINAL_AGENT_TABLE_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( CUSTOM_AGENT_TABLE_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( ORIGINAL_AGENT_GENERATOR_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( CUSTOM_AGENT_GENERATOR_NAME ) ).isZero(); + } + + @Test + public void validAgentMapping() { + MostRecentStatementInspector statementInspector = new MostRecentStatementInspector(); + + backendMock.expectAnySchema( IndexedEntity.INDEX ); + sessionFactory = ormSetupHelper.start() + .withProperty( "hibernate.search.coordination.agent.entity.mapping", VALID_AGENT_EVENT_MAPPING ) + .withProperty( "hibernate.session_factory.statement_inspector", statementInspector ) + .setup( IndexedEntity.class ); + backendMock.verifyExpectationsMet(); + + backendMock.expectWorks( IndexedEntity.INDEX ) + .add( "1", f -> f.field( "indexedField", "value for the field" ) ); + + int id = 1; + OrmUtils.withinTransaction( sessionFactory, session -> { + IndexedEntity entity = new IndexedEntity(); + entity.setId( id ); + entity.setIndexedField( "value for the field" ); + session.persist( entity ); + } ); + + backendMock.verifyExpectationsMet(); + + assertThat( statementInspector.countByKey( ORIGINAL_OUTBOX_EVENT_TABLE_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( CUSTOM_OUTBOX_EVENT_TABLE_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( ORIGINAL_OUTBOX_EVENT_GENERATOR_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( CUSTOM_OUTBOX_EVENT_GENERATOR_NAME ) ).isZero(); + + assertThat( statementInspector.countByKey( ORIGINAL_AGENT_TABLE_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( CUSTOM_AGENT_TABLE_NAME ) ).isPositive(); + assertThat( statementInspector.countByKey( ORIGINAL_AGENT_GENERATOR_NAME ) ).isZero(); + assertThat( statementInspector.countByKey( CUSTOM_AGENT_GENERATOR_NAME ) ).isPositive(); + } + + @Entity(name = IndexedEntity.INDEX) + @Indexed(index = IndexedEntity.INDEX) + public static class IndexedEntity { + static final String INDEX = "IndexedEntity"; + + @Id + private Integer id; + + @Basic + @GenericField + private String indexedField; + + public IndexedEntity() { + } + + public IndexedEntity(Integer id, String indexedField) { + this.id = id; + this.indexedField = indexedField; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getIndexedField() { + return indexedField; + } + + public void setIndexedField(String indexedField) { + this.indexedField = indexedField; + } + } + + public static class MostRecentStatementInspector implements StatementInspector { + + private Map> sqlByKey = new HashMap<>(); + + public MostRecentStatementInspector() { + for ( String key : SQL_KEYS ) { + sqlByKey.put( key, new ArrayList<>() ); + } + } + + @Override + public String inspect(String sql) { + for ( String key : SQL_KEYS ) { + if ( sql.contains( key ) ) { + sqlByKey.get( key ).add( sql ); + } + } + return sql; + } + + public int countByKey(String key) { + return sqlByKey.get( key ).size(); + } + } +} diff --git a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cfg/spi/HibernateOrmMapperOutboxPollingSpiSettings.java b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cfg/spi/HibernateOrmMapperOutboxPollingSpiSettings.java new file mode 100644 index 00000000000..6696c093085 --- /dev/null +++ b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cfg/spi/HibernateOrmMapperOutboxPollingSpiSettings.java @@ -0,0 +1,78 @@ +/* + * 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 . + */ +package org.hibernate.search.mapper.orm.coordination.outboxpolling.cfg.spi; + +import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cfg.HibernateOrmMapperOutboxPollingSettings; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cluster.impl.Agent; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cluster.impl.OutboxPollingAgentAdditionalJaxbMappingProducer; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.event.impl.OutboxEvent; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.event.impl.OutboxPollingOutboxEventAdditionalJaxbMappingProducer; +import org.hibernate.search.util.common.annotation.Incubating; + +/** + * SPI-related settings. + */ +@Incubating +public final class HibernateOrmMapperOutboxPollingSpiSettings { + + private HibernateOrmMapperOutboxPollingSpiSettings() { + } + + /** + * The prefix expected for the key of every Hibernate Search configuration property + * when using the Hibernate ORM mapper. + */ + public static final String PREFIX = HibernateOrmMapperSettings.PREFIX; + + /** + * Allows the user to define a specific Hibernate mapping for the {@link OutboxEvent} entity. + *

+ * Only available when {@link HibernateOrmMapperSettings#COORDINATION_STRATEGY} is + * {@value HibernateOrmMapperOutboxPollingSettings#COORDINATION_STRATEGY_NAME}. + *

+ * Expects a String value containing the xml expressing the Hibernate mapping for the entity. + *

+ * The default for this value is {@link OutboxPollingOutboxEventAdditionalJaxbMappingProducer#ENTITY_DEFINITION} + */ + public static final String OUTBOXEVENT_ENTITY_MAPPING = PREFIX + Radicals.OUTBOXEVENT_ENTITY_MAPPING; + + /** + * Allows the user to define a specific Hibernate mapping for the {@link Agent} entity. + *

+ * Only available when {@link HibernateOrmMapperSettings#COORDINATION_STRATEGY} is + * {@value HibernateOrmMapperOutboxPollingSettings#COORDINATION_STRATEGY_NAME}. + *

+ * Expects a String value containing the xml expressing the Hibernate mapping for the entity. + *

+ * The default for this value is {@link OutboxPollingAgentAdditionalJaxbMappingProducer#ENTITY_DEFINITION} + */ + public static final String AGENT_ENTITY_MAPPING = PREFIX + Radicals.AGENT_ENTITY_MAPPING; + + /** + * Configuration property keys without the {@link #PREFIX prefix}. + */ + public static final class Radicals { + + private Radicals() { + } + + public static final String COORDINATION_PREFIX = HibernateOrmMapperSettings.Radicals.COORDINATION_PREFIX; + public static final String OUTBOXEVENT_ENTITY_MAPPING = COORDINATION_PREFIX + CoordinationRadicals.OUTBOXEVENT_ENTITY_MAPPING; + public static final String AGENT_ENTITY_MAPPING = COORDINATION_PREFIX + CoordinationRadicals.AGENT_ENTITY_MAPPING; + } + + public static final class CoordinationRadicals { + + private CoordinationRadicals() { + } + + public static final String OUTBOXEVENT_ENTITY_MAPPING = "outboxevent.entity.mapping"; + public static final String AGENT_ENTITY_MAPPING = "agent.entity.mapping"; + } + +} diff --git a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cluster/impl/OutboxPollingAgentAdditionalJaxbMappingProducer.java b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cluster/impl/OutboxPollingAgentAdditionalJaxbMappingProducer.java index eb25beb7cad..6e505af6d28 100644 --- a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cluster/impl/OutboxPollingAgentAdditionalJaxbMappingProducer.java +++ b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/cluster/impl/OutboxPollingAgentAdditionalJaxbMappingProducer.java @@ -19,16 +19,16 @@ import org.hibernate.boot.jaxb.spi.Binding; import org.hibernate.boot.model.source.internal.hbm.MappingDocument; import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.search.engine.cfg.ConfigurationPropertySource; +import org.hibernate.search.engine.cfg.spi.ConfigurationProperty; +import org.hibernate.search.mapper.orm.bootstrap.spi.HibernateSearchOrmMappingProducer; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cfg.spi.HibernateOrmMapperOutboxPollingSpiSettings; import org.hibernate.search.mapper.orm.coordination.outboxpolling.logging.impl.Log; import org.hibernate.search.util.common.annotation.impl.SuppressForbiddenApis; import org.hibernate.search.util.common.logging.impl.LoggerFactory; -import org.jboss.jandex.IndexView; - -@SuppressWarnings("deprecation") public class OutboxPollingAgentAdditionalJaxbMappingProducer - implements org.hibernate.boot.spi.AdditionalJaxbMappingProducer { + implements HibernateSearchOrmMappingProducer { private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); @@ -37,7 +37,7 @@ public class OutboxPollingAgentAdditionalJaxbMappingProducer public static final String HSEARCH_PREFIX = "HSEARCH_"; // Must not be longer than 20 characters, so that the generator does not exceed the 30 characters for Oracle11g - private static final String TABLE_NAME = HSEARCH_PREFIX + "AGENT"; + public static final String TABLE_NAME = HSEARCH_PREFIX + "AGENT"; private static final String CLASS_NAME = Agent.class.getName(); @@ -48,7 +48,7 @@ public class OutboxPollingAgentAdditionalJaxbMappingProducer // because our override actually matches the default for the native entity name. public static final String ENTITY_NAME = CLASS_NAME; - private static final String ENTITY_DEFINITION = "\n" + + public static final String ENTITY_DEFINITION = "\n" + "\n" + " \n" + " \n" + @@ -70,15 +70,23 @@ public class OutboxPollingAgentAdditionalJaxbMappingProducer " \n" + "\n"; + private static final ConfigurationProperty AGENT_ENTITY_MAPPING = + ConfigurationProperty.forKey( HibernateOrmMapperOutboxPollingSpiSettings.CoordinationRadicals.AGENT_ENTITY_MAPPING ) + .asString() + .withDefault( ENTITY_DEFINITION ) + .build(); + @Override @SuppressForbiddenApis(reason = "Strangely, this SPI involves the internal MappingBinder class," + " and there's nothing we can do about it") - public Collection produceAdditionalMappings(final MetadataImplementor metadata, - IndexView jandexIndex, final MappingBinder mappingBinder, final MetadataBuildingContext buildingContext) { - log.applicationNodeGeneratedEntityMapping( ENTITY_DEFINITION ); + public Collection produceMappings(ConfigurationPropertySource propertySource, + MappingBinder mappingBinder, MetadataBuildingContext buildingContext) { + String entityDefinition = AGENT_ENTITY_MAPPING.get( propertySource ); + + log.agentGeneratedEntityMapping( entityDefinition ); Origin origin = new Origin( SourceType.OTHER, "search" ); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( ENTITY_DEFINITION.getBytes() ); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( entityDefinition.getBytes() ); BufferedInputStream bufferedInputStream = new BufferedInputStream( byteArrayInputStream ); Binding binding = mappingBinder.bind( bufferedInputStream, origin ); diff --git a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/event/impl/OutboxPollingOutboxEventAdditionalJaxbMappingProducer.java b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/event/impl/OutboxPollingOutboxEventAdditionalJaxbMappingProducer.java index de8b0362f46..296bd96e807 100644 --- a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/event/impl/OutboxPollingOutboxEventAdditionalJaxbMappingProducer.java +++ b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/event/impl/OutboxPollingOutboxEventAdditionalJaxbMappingProducer.java @@ -19,24 +19,24 @@ import org.hibernate.boot.jaxb.spi.Binding; import org.hibernate.boot.model.source.internal.hbm.MappingDocument; import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.search.engine.cfg.ConfigurationPropertySource; +import org.hibernate.search.engine.cfg.spi.ConfigurationProperty; +import org.hibernate.search.mapper.orm.bootstrap.spi.HibernateSearchOrmMappingProducer; +import org.hibernate.search.mapper.orm.coordination.outboxpolling.cfg.spi.HibernateOrmMapperOutboxPollingSpiSettings; import org.hibernate.search.mapper.orm.coordination.outboxpolling.cluster.impl.OutboxPollingAgentAdditionalJaxbMappingProducer; import org.hibernate.search.mapper.orm.coordination.outboxpolling.logging.impl.Log; import org.hibernate.search.util.common.annotation.impl.SuppressForbiddenApis; import org.hibernate.search.util.common.logging.impl.LoggerFactory; -import org.jboss.jandex.IndexView; - -@SuppressWarnings("deprecation") public final class OutboxPollingOutboxEventAdditionalJaxbMappingProducer - implements org.hibernate.boot.spi.AdditionalJaxbMappingProducer { + implements HibernateSearchOrmMappingProducer { private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); private static final String HSEARCH_PREFIX = OutboxPollingAgentAdditionalJaxbMappingProducer.HSEARCH_PREFIX; // Must not be longer than 20 characters, so that the generator does not exceed the 30 characters for Oracle11g - private static final String TABLE_NAME = HSEARCH_PREFIX + "OUTBOX_EVENT"; + public static final String TABLE_NAME = HSEARCH_PREFIX + "OUTBOX_EVENT"; private static final String CLASS_NAME = OutboxEvent.class.getName(); @@ -47,7 +47,7 @@ public final class OutboxPollingOutboxEventAdditionalJaxbMappingProducer // because our override actually matches the default for the native entity name. public static final String ENTITY_NAME = CLASS_NAME; - private static final String ENTITY_DEFINITION = "\n" + + public static final String ENTITY_DEFINITION = "\n" + "\n" + " \n" + " \n" + @@ -68,15 +68,23 @@ public final class OutboxPollingOutboxEventAdditionalJaxbMappingProducer " \n" + "\n"; + private static final ConfigurationProperty OUTBOXEVENT_ENTITY_MAPPING = + ConfigurationProperty.forKey( HibernateOrmMapperOutboxPollingSpiSettings.CoordinationRadicals.OUTBOXEVENT_ENTITY_MAPPING ) + .asString() + .withDefault( ENTITY_DEFINITION ) + .build(); + @Override @SuppressForbiddenApis(reason = "Strangely, this SPI involves the internal MappingBinder class," + " and there's nothing we can do about it") - public Collection produceAdditionalMappings(final MetadataImplementor metadata, - IndexView jandexIndex, final MappingBinder mappingBinder, final MetadataBuildingContext buildingContext) { - log.outboxEventGeneratedEntityMapping( ENTITY_DEFINITION ); + public Collection produceMappings(ConfigurationPropertySource propertySource, + MappingBinder mappingBinder, MetadataBuildingContext buildingContext) { + String entityDefinition = OUTBOXEVENT_ENTITY_MAPPING.get( propertySource ); + + log.outboxEventGeneratedEntityMapping( entityDefinition ); Origin origin = new Origin( SourceType.OTHER, "search" ); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( ENTITY_DEFINITION.getBytes() ); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( entityDefinition.getBytes() ); BufferedInputStream bufferedInputStream = new BufferedInputStream( byteArrayInputStream ); Binding binding = mappingBinder.bind( bufferedInputStream, origin ); diff --git a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/logging/impl/Log.java b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/logging/impl/Log.java index 358788e4403..0a51a19f639 100644 --- a/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/logging/impl/Log.java +++ b/mapper/orm-coordination-outbox-polling/src/main/java/org/hibernate/search/mapper/orm/coordination/outboxpolling/logging/impl/Log.java @@ -88,7 +88,7 @@ public interface Log extends BasicLogger { @LogMessage(level = DEBUG) @Message(id = ID_OFFSET + 14, value = "Generated entity mapping for agents used in the outbox-polling coordination strategy: %1$s") - void applicationNodeGeneratedEntityMapping(String xmlMappingDefinition); + void agentGeneratedEntityMapping(String xmlMappingDefinition); @Message(id = ID_OFFSET + 15, value = "The pulse interval must be greater than or equal to the polling interval" + " i.e. in this case at least %s") diff --git a/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchAdditionalJaxbMappingProducer.java b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchCompositeMappingProducer.java similarity index 63% rename from mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchAdditionalJaxbMappingProducer.java rename to mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchCompositeMappingProducer.java index 57db3375559..34518242a45 100644 --- a/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchAdditionalJaxbMappingProducer.java +++ b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/impl/HibernateSearchCompositeMappingProducer.java @@ -16,30 +16,39 @@ import org.hibernate.boot.model.source.internal.hbm.MappingDocument; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.search.engine.cfg.ConfigurationPropertySource; +import org.hibernate.search.engine.common.spi.SearchIntegrationEnvironment; +import org.hibernate.search.mapper.orm.bootstrap.spi.HibernateSearchOrmMappingProducer; +import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; import org.hibernate.search.mapper.orm.common.impl.HibernateOrmUtils; import org.hibernate.search.util.common.annotation.impl.SuppressForbiddenApis; import org.jboss.jandex.IndexView; @SuppressWarnings("deprecation") -public class HibernateSearchAdditionalJaxbMappingProducer implements org.hibernate.boot.spi.AdditionalJaxbMappingProducer { +public class HibernateSearchCompositeMappingProducer implements org.hibernate.boot.spi.AdditionalJaxbMappingProducer { @Override @SuppressForbiddenApis(reason = "Strangely, this SPI involves the internal MappingBinder class," + " and there's nothing we can do about it") public Collection produceAdditionalMappings(final MetadataImplementor metadata, IndexView jandexIndex, final MappingBinder mappingBinder, final MetadataBuildingContext buildingContext) { - Optional preIntegrationService = + Optional preIntegrationServiceOptional = HibernateOrmUtils.getServiceOrEmpty( buildingContext.getBootstrapContext().getServiceRegistry(), HibernateSearchPreIntegrationService.class ); - if ( !preIntegrationService.isPresent() ) { + if ( !preIntegrationServiceOptional.isPresent() ) { // Hibernate Search is disabled return Collections.emptyList(); } + + HibernateSearchPreIntegrationService preIntegrationService = preIntegrationServiceOptional.get(); List mappings = new ArrayList<>(); - for ( org.hibernate.boot.spi.AdditionalJaxbMappingProducer mappingProducer : preIntegrationService.get() + ConfigurationPropertySource propertySource = preIntegrationService.propertySource() + .withMask( SearchIntegrationEnvironment.CONFIGURATION_PROPERTIES_MASK ) + .withMask( HibernateOrmMapperSettings.Radicals.COORDINATION ); + for ( HibernateSearchOrmMappingProducer mappingProducer : preIntegrationService .coordinationStrategyConfiguration().mappingProducers() ) { - mappings.addAll( mappingProducer.produceAdditionalMappings( metadata, jandexIndex, mappingBinder, + mappings.addAll( mappingProducer.produceMappings( propertySource, mappingBinder, buildingContext ) ); } return mappings; diff --git a/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/spi/HibernateSearchOrmMappingProducer.java b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/spi/HibernateSearchOrmMappingProducer.java new file mode 100644 index 00000000000..62757c2cded --- /dev/null +++ b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/bootstrap/spi/HibernateSearchOrmMappingProducer.java @@ -0,0 +1,24 @@ +/* + * 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 . + */ +package org.hibernate.search.mapper.orm.bootstrap.spi; + +import java.util.Collection; + +import org.hibernate.boot.jaxb.internal.MappingBinder; +import org.hibernate.boot.model.source.internal.hbm.MappingDocument; +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.search.engine.cfg.ConfigurationPropertySource; +import org.hibernate.search.util.common.annotation.impl.SuppressForbiddenApis; + +public interface HibernateSearchOrmMappingProducer { + + @SuppressForbiddenApis(reason = "Strangely, this SPI involves the internal MappingBinder class," + + " and there's nothing we can do about it") + Collection produceMappings(ConfigurationPropertySource propertySource, + MappingBinder mappingBinder, MetadataBuildingContext buildingContext); + +} diff --git a/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/coordination/common/spi/CoordinationConfigurationContext.java b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/coordination/common/spi/CoordinationConfigurationContext.java index b2cb42d4aa2..a6251efa1dd 100644 --- a/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/coordination/common/spi/CoordinationConfigurationContext.java +++ b/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/coordination/common/spi/CoordinationConfigurationContext.java @@ -10,6 +10,7 @@ import org.hibernate.search.mapper.orm.automaticindexing.spi.AutomaticIndexingEventSendingSessionContext; import org.hibernate.search.mapper.orm.automaticindexing.spi.AutomaticIndexingQueueEventSendingPlan; +import org.hibernate.search.mapper.orm.bootstrap.spi.HibernateSearchOrmMappingProducer; public interface CoordinationConfigurationContext { @@ -36,7 +37,6 @@ void sendIndexingEventsTo(Function strategyHolder; - @SuppressWarnings("deprecation") - private final List mappingProducers = new ArrayList<>(); + private final List mappingProducers = new ArrayList<>(); private Function senderFactory; private boolean enlistsInTransaction = false; @@ -76,9 +76,8 @@ public void sendIndexingEventsTo( this.enlistsInTransaction = enlistsInTransaction; } - @SuppressWarnings("deprecation") @Override - public void mappingProducer(org.hibernate.boot.spi.AdditionalJaxbMappingProducer producer) { + public void mappingProducer(HibernateSearchOrmMappingProducer producer) { mappingProducers.add( producer ); } @@ -90,8 +89,7 @@ public ConfiguredAutomaticIndexingStrategy createAutomaticIndexingStrategy() { return new ConfiguredAutomaticIndexingStrategy( senderFactory, enlistsInTransaction ); } - @SuppressWarnings("deprecation") - public List mappingProducers() { + public List mappingProducers() { return mappingProducers; } } diff --git a/mapper/orm/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalJaxbMappingProducer b/mapper/orm/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalJaxbMappingProducer index ca66e0432b5..0189e5b24b6 100644 --- a/mapper/orm/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalJaxbMappingProducer +++ b/mapper/orm/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalJaxbMappingProducer @@ -1 +1 @@ -org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchAdditionalJaxbMappingProducer \ No newline at end of file +org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchCompositeMappingProducer \ No newline at end of file