package gw.solr uses com.google.common.base.Preconditions uses gw.api.system.PLLoggerCategory uses gw.plugin.InitializablePlugin uses gw.plugin.PluginParameter uses gw.plugin.messaging.MessageTransport uses gw.solr.consistency.ConsistencyTracker uses gw.solr.consistency.MessageHistoryFinder uses gw.solr.request.DataHolderImpl uses gw.solr.utils.PLSolrUtils uses gw.solr.utils.SolrUpdateMessage uses org.slf4j.Logger uses java.io.File uses java.util.concurrent.atomic.AtomicBoolean uses java.util.concurrent.atomic.AtomicInteger uses java.util.concurrent.atomic.AtomicReference /** * Base class for a Solr message transport plugin. This type of plugin listens * for updates of interest to the related Solr index documents and creates and * submits the required Solr update messages. */ @ReadOnly @PluginParameter(:name="debug", :type=Boolean) @PluginParameter(:name="commitImmediately", :type=Boolean) abstract class AbstractSolrMessageTransportPlugin implements MessageTransport, InitializablePlugin { static final var DEBUG_PARAM = "debug" static final var COMMIT_IMMEDIATELY_PARAM = "commitImmediately" protected static final var CONSISTENCY_CACHE_SIZE_PARAM: String = "consistencyCacheSize" protected static final var CONSISTENCY_CACHE_EXPIRATION_SECONDS_PARAM: String = "consistencyCacheExpirationSeconds" static var _instance : AbstractSolrMessageTransportPlugin protected static final var _logger : Logger = PLLoggerCategory.SOLR_INDEX var _pluginName : String as PluginName var _debug : boolean as Debug var _commitImmediately : boolean as CommitImmediately final var _consistencyTracker = new AtomicReference(); final var _messageHistoryFinder = new MessageHistoryFinder() final var _destinationStarted = new AtomicBoolean(false); final var _destinationId = new AtomicInteger(); construct(name: String) { _pluginName = name _instance = this } abstract function parseMessagePayload(messagePayload: String): List abstract function createConsistencyTracker(): ConsistencyTracker // Accessed reflectively from tests. private static function getInstance() : AbstractSolrMessageTransportPlugin { return _instance } override property set Parameters(params : Map) { var s = params.get(DEBUG_PARAM) as String _debug = Boolean.parseBoolean(s) s = params.get(COMMIT_IMMEDIATELY_PARAM) as String _commitImmediately = Boolean.parseBoolean(s) } override function resume() { if(_destinationStarted.compareAndSet(false, true)) { _consistencyTracker.set(createConsistencyTracker()) warmUpCache() _logger.info("***** {} is initialized. *****", _pluginName) } } private function warmUpCache() { var destinationId = _destinationId.get() Preconditions.checkState(destinationId != 0, "Destination Id is not set") var messageHistory = _messageHistoryFinder.findMessageHistoryForDuration(destinationId, ConsistencyTracker.ExpireDuration) var solrMessages = messageHistory.flatMap(\msg -> parseMessagePayload(msg.Payload)) solrMessages.forEach(\solrMsg -> ConsistencyTracker.maybeCorrectMessage(solrMsg.JsonPayload)) } protected property get ConsistencyTracker() : ConsistencyTracker { return Preconditions.checkNotNull(_consistencyTracker.get(), "Consistency tracker is not set") } override property set DestinationID(destinationID : int) { _destinationId.set(destinationID) } override function shutdown() { } override function suspend() { } /** * Walks a bean graph from it's root, according to the indexing rules * in the associated configuration file, and detects if interesting * changes are present. * * @param root root of bean graph in which to search for changes. * @param configFile Solr document configuration file containing the indexing rules. * * @return true if this graph contains changes that require an index update * to be sent to Solr, false otherwise. */ static function hasRelevantChanges( root : Object, configFile : File ) : boolean { return hasRelevantChanges( { root }, configFile) } /** * Walks a bean graph from it's root, according to the indexing rules * in the associated configuration file, and detects if interesting * changes are present. * * @param roots List of roots for the bean graph in which to search for changes. * @param configFile Solr document configuration file containing the indexing rules. * * @return true if this graph contains changes that require an index update * to be sent to Solr, false otherwise. */ static function hasRelevantChanges( roots : List, configFile : File ) : boolean { var configReader = PLSolrUtils.getSchemaConfigReader(configFile) var theIndexer = configReader.Indexer var dataHolder = new DataHolderImpl(theIndexer.Root, roots) for(indexField in theIndexer.IndexField) { for(dp in indexField.DataProperty) { if(dataHolder.isChanged(dp)) { return true } } } return false } }