/** * Copyright Plugtree LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.plugtree.solrmeter.model.executor; import java.util.LinkedList; import java.util.List; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.response.UpdateResponse; import com.google.inject.Inject; import com.google.inject.name.Named; import com.plugtree.solrmeter.model.InputDocumentExtractor; import com.plugtree.solrmeter.model.SolrMeterConfiguration; import com.plugtree.solrmeter.model.UpdateExecutor; import com.plugtree.solrmeter.model.UpdateStatistic; import com.plugtree.solrmeter.model.exception.CommitException; import com.plugtree.solrmeter.model.exception.UpdateException; import com.plugtree.solrmeter.model.operation.CommitOperation; import com.plugtree.solrmeter.model.operation.ConstantOperationExecutorThread; import com.plugtree.solrmeter.model.operation.RandomOperationExecutorThread; import com.plugtree.solrmeter.model.operation.UpdateOperation; import com.plugtree.stressTestScope.StressTestScope; /** * manages update execution Threads. The updates are executed with * RandomOperationExectionThread. * @see com.plugtree.solrmeter.model.operation.RandomOperationExecutorThread * @author tflobbe * */ @StressTestScope public class UpdateExecutorRandomImpl extends AbstractRandomExecutor implements UpdateExecutor { //TODO DI private SolrServer server; private Integer numberOfDocumentsBeforeCommit; private Integer maxTimeBeforeCommit; private List<UpdateStatistic> statistics; protected boolean autocommit; private int notCommitedDocuments; private ConstantOperationExecutorThread commiterThread; private InputDocumentExtractor documentExtractor; @Inject public UpdateExecutorRandomImpl(@Named("updateExtractor") InputDocumentExtractor documentExtractor) { super(); this.documentExtractor = documentExtractor; statistics = new LinkedList<UpdateStatistic>(); operationsPerSecond = Integer.parseInt(SolrMeterConfiguration.getProperty(SolrMeterConfiguration.UPDATES_PER_SECOND)); autocommit = Boolean.valueOf(SolrMeterConfiguration.getProperty("solr.update.solrAutocommit", "false"));; maxTimeBeforeCommit = Integer.valueOf(SolrMeterConfiguration.getProperty("solr.update.timeToCommit", "10000")); numberOfDocumentsBeforeCommit = Integer.valueOf(SolrMeterConfiguration.getProperty("solr.update.documentsToCommit", "100")); super.prepare(); } public UpdateExecutorRandomImpl() { super(); statistics = new LinkedList<UpdateStatistic>(); } public synchronized SolrServer getSolrServer() { if(server == null) { server = super.getSolrServer(SolrMeterConfiguration.getProperty(SolrMeterConfiguration.SOLR_ADD_URL)); } return server; } protected RandomOperationExecutorThread createThread() { return new RandomOperationExecutorThread(new UpdateOperation(this, documentExtractor), 1000); } private void prepareCommitter() { if(commiterThread != null) { commiterThread.destroy(); } commiterThread = new ConstantOperationExecutorThread(new CommitOperation(this)); commiterThread.setTimeToWait(maxTimeBeforeCommit); } public void start() { if(this.isRunning()) { return; } super.start(); if(!isAutocommit()) { prepareCommitter(); commiterThread.start(); } logger.info("Update Executor started"); } public void stop() { if(!this.isRunning()) { return; } if(!isAutocommit()) { commiterThread.destroy(); } super.stop(); } protected void stopStatistics() { for(UpdateStatistic statistic:statistics) { statistic.onFinishedTest(); } } public void notifyAddedDocument(UpdateResponse response) { for(UpdateStatistic statistic:statistics) { statistic.onAddedDocument(response); } if(!isAutocommit()) { notCommitedDocuments++;//synchronize this? if(notCommitedDocuments >= numberOfDocumentsBeforeCommit) { logger.debug("Not Commited Docs is " + notCommitedDocuments + ". Waking commiter thread."); commiterThread.wake(); } } } public void notifyCommitSuccessfull(UpdateResponse response) { notCommitedDocuments = 0; for(UpdateStatistic statistic:statistics) { statistic.onCommit(response); } } public void notifyCommitError(CommitException exception) { for(UpdateStatistic statistic:statistics) { statistic.onCommitError(exception); } } public void notifyUpdateError(UpdateException updateException) { for(UpdateStatistic statistic:statistics) { statistic.onAddError(updateException); } } public void addStatistic(UpdateStatistic statistic) { this.statistics.add(statistic); } public int getNotCommitedDocuments() { return notCommitedDocuments; } @Override public void setNumberOfDocumentsBeforeCommit(int value) { if (value == Integer.MAX_VALUE) { throw new IllegalArgumentException("Number of documents before commit can't be more than " + Integer.MAX_VALUE); } if (value < 0) { throw new IllegalArgumentException("Number of documents before commit can't be less than 0"); } numberOfDocumentsBeforeCommit= value; SolrMeterConfiguration.setProperty("solr.update.documentsToCommit", String.valueOf(numberOfDocumentsBeforeCommit)); } public Integer getNumberOfDocumentsBeforeCommit() { return numberOfDocumentsBeforeCommit; } public void setMaxTimeBeforeCommit(Integer value) { if(value <= 0) { throw new RuntimeException("Time before commit can't be 0"); } maxTimeBeforeCommit = value; SolrMeterConfiguration.setProperty("solr.update.timeToCommit", String.valueOf(maxTimeBeforeCommit)); commiterThread.setTimeToWait(value); } public Integer getMaxTimeBeforeCommit() { return maxTimeBeforeCommit; } public boolean isAutocommit() { return autocommit; } public Integer getUpdatesPerMinute() { return this.operationsPerSecond; } @Override protected String getOperationsPerSecondConfigurationKey() { return "solr.load.updatespersecond"; } }