/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * 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.ogm.massindex.impl; import java.util.concurrent.CountDownLatch; import org.hibernate.CacheMode; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.ogm.dialect.spi.GridDialect; import org.hibernate.ogm.model.impl.DefaultEntityKeyMetadata; import org.hibernate.ogm.model.key.spi.EntityKeyMetadata; import org.hibernate.ogm.persister.impl.OgmEntityPersister; import org.hibernate.search.backend.spi.BatchBackend; import org.hibernate.search.batchindexing.MassIndexerProgressMonitor; import org.hibernate.search.spi.SearchIntegrator; import org.hibernate.search.engine.integration.impl.ExtendedSearchIntegrator; import org.hibernate.search.exception.ErrorHandler; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.search.util.logging.impl.LoggerFactory; /** * This runnable will prepare a pipeline for batch indexing * of entities, managing the lifecycle of several ThreadPools. * * @author Sanne Grinovero * @author Davide D'Alto <davide@hibernate.org> */ public class BatchIndexingWorkspace implements Runnable { private static final Log log = LoggerFactory.make(); private final ExtendedSearchIntegrator searchIntegrator; private final SessionFactoryImplementor sessionFactory; private final Class<?> indexedType; // progress monitor private final MassIndexerProgressMonitor monitor; // loading options private final CacheMode cacheMode; private final BatchBackend batchBackend; private final GridDialect gridDialect; private final CountDownLatch endAllSignal; private final String tenantId; public BatchIndexingWorkspace(GridDialect gridDialect, SearchIntegrator search, SessionFactoryImplementor sessionFactory, Class<?> entityType, CacheMode cacheMode, CountDownLatch endAllSignal, MassIndexerProgressMonitor monitor, BatchBackend backend, String tenantId) { this.gridDialect = gridDialect; this.indexedType = entityType; this.tenantId = tenantId; this.searchIntegrator = search.unwrap( ExtendedSearchIntegrator.class ); this.sessionFactory = sessionFactory; this.cacheMode = cacheMode; this.endAllSignal = endAllSignal; this.batchBackend = backend; this.monitor = monitor; } @Override public void run() { ErrorHandler errorHandler = searchIntegrator.getErrorHandler(); try { OgmEntityPersister persister = (OgmEntityPersister) sessionFactory.getEntityPersister( indexedType.getName() ); final EntityKeyMetadata keyMetadata = new DefaultEntityKeyMetadata( persister.getTableName(), persister.getRootTableIdentifierColumnNames() ); final SessionAwareRunnable consumer = new TupleIndexer( indexedType, monitor, sessionFactory, searchIntegrator, cacheMode, batchBackend, errorHandler, tenantId ); gridDialect.forEachTuple( new OptionallyWrapInJTATransaction( sessionFactory, errorHandler, consumer ), persister.getTupleTypeContext(), keyMetadata ); } catch ( RuntimeException re ) { // being this an async thread we want to make sure everything is somehow reported errorHandler.handleException( log.massIndexerUnexpectedErrorMessage(), re ); } finally { endAllSignal.countDown(); } } }