
org.perfcake.message.generator.AbstractMessageGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of perfcake Show documentation
Show all versions of perfcake Show documentation
A Lightweight Performance Testing Framework
/*
* -----------------------------------------------------------------------\
* PerfCake
*
* Copyright (C) 2010 - 2016 the original author or authors.
*
* 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 org.perfcake.message.generator;
import org.perfcake.PerfCakeConst;
import org.perfcake.PerfCakeException;
import org.perfcake.RunInfo;
import org.perfcake.message.MessageTemplate;
import org.perfcake.message.correlator.Correlator;
import org.perfcake.message.sender.MessageSender;
import org.perfcake.message.sender.MessageSenderManager;
import org.perfcake.message.sequence.SequenceManager;
import org.perfcake.reporting.ReportManager;
import org.perfcake.util.Utils;
import org.perfcake.validation.ValidationManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
/**
* A common ancestor for most generators. It can generate messages in parallel using {@link MessageSender Message Senders} running
* concurrently in {@link #threads} number of threads.
*
* @author Pavel Macík
* @author Martin Večeřa
*/
public abstract class AbstractMessageGenerator implements MessageGenerator {
/**
* Our logger.
*/
private static final Logger log = LogManager.getLogger(AbstractMessageGenerator.class);
/**
* Message sender manager.
*/
protected MessageSenderManager messageSenderManager;
/**
* Report manager.
*/
protected ReportManager reportManager;
/**
* A reference to the current message validator manager.
*/
protected ValidationManager validationManager;
/**
* Message store where the messages for senders to be send are taken from.
*/
protected List messageStore;
/**
* The executor service used to run the threads.
*/
protected ThreadPoolExecutor executorService;
/**
* Manager of sequences that can be used to replace placeholders in a message template and sender's target.
*/
protected SequenceManager sequenceManager;
/**
* Represents the information about current run.
*/
protected RunInfo runInfo;
/**
* Number of concurrent threads the generator will use to send the messages.
*/
private int threads = 1;
/**
* True when we should interrupt generating messages on error.
*/
private boolean failFast = false;
/**
* Correlates received messages with the sent ones. Null means that it is unused.
*/
private Correlator correlator = null;
/**
* Initializes the generator. During the initialization the {@link #messageSenderManager} is initialized as well.
*
* @param messageSenderManager
* Message sender manager.
* @param messageStore
* Message store where the messages are taken from.
* @throws PerfCakeException
* When it was not possible to initialize the generator.
*/
@Override
public void init(final MessageSenderManager messageSenderManager, final List messageStore) throws PerfCakeException {
failFast = Boolean.parseBoolean(Utils.getProperty(PerfCakeConst.FAIL_FAST_PROPERTY, "false"));
this.messageStore = messageStore;
this.messageSenderManager = messageSenderManager;
this.messageSenderManager.init();
}
@Override
public void interrupt(final Exception exception) {
log.error("Execution interrupted prematurely by an error in message sender: ", exception);
// we cloned the behavior of Scenario.stop() here as we do not have direct access to the Scenario object
reportManager.stop();
}
/**
* Gets a new instance of a {@link org.perfcake.message.generator.SenderTask}.
* The provided semaphore can be used to control parallel execution of sender tasks in multiple threads.
*
* @return A sender task ready to work on another iteration.
*/
protected SenderTask newSenderTask() {
final SenderTask task = new SenderTask(this);
task.setMessageStore(messageStore);
task.setReportManager(reportManager);
task.setSenderManager(messageSenderManager);
task.setValidationManager(validationManager);
task.setSequenceManager(sequenceManager);
task.setCorrelator(correlator);
return task;
}
/**
* Sets the current {@link org.perfcake.RunInfo} to control generating of the messages.
*
* @param runInfo
* {@link org.perfcake.RunInfo} to be used.
*/
@Override
public void setRunInfo(final RunInfo runInfo) {
this.runInfo = runInfo;
this.runInfo.setThreads(threads);
validateRunInfo();
}
/**
* Verifies that the current configuration of {@link org.perfcake.RunInfo} is supported by the current generator.
*/
protected abstract void validateRunInfo();
/**
* Sets the {@link org.perfcake.reporting.ReportManager} to be used for the current performance test execution.
*
* @param reportManager
* {@link org.perfcake.reporting.ReportManager} to be used.
*/
@Override
public void setReportManager(final ReportManager reportManager) {
this.reportManager = reportManager;
}
/**
* Closes and finalizes the generator. The {@link #messageSenderManager} is closed as well.
*
* @throws PerfCakeException
* When it was not possible to smoothly finalize the generator.
*/
@Override
public void close() throws PerfCakeException {
messageSenderManager.close();
}
/**
* Records the timestamp of the moment when the generator execution started.
*/
protected void setStartTime() {
reportManager.start();
}
/**
* Records the timestamp of the moment when the generator execution stopped.
*/
protected void setStopTime() {
if (runInfo.isStarted()) {
reportManager.stop();
}
}
/**
* Generates the messages. This actually executes the whole performance test.
*
* @throws Exception
* When it was not possible to generate the messages.
*/
@Override
public abstract void generate() throws Exception;
/**
* Gets the number of threads that should be used to generate the messages.
* The return value can change over time during the test execution.
*
* @return Number of currently running threads.
*/
@Override
public int getThreads() {
return threads;
}
/**
* Sets the number of threads used to generate the messages.
*
* @param threads
* The number of threads to be used.
* @return Instance of this to support fluent API.
*/
@Override
public MessageGenerator setThreads(final int threads) {
this.threads = threads;
if (runInfo != null) {
runInfo.setThreads(threads);
}
return this;
}
/**
* Configures the {@link org.perfcake.validation.ValidationManager} to be used for the performance test execution.
*
* @param validationManager
* {@link org.perfcake.validation.ValidationManager} to be used.
*/
@Override
public void setValidationManager(final ValidationManager validationManager) {
this.validationManager = validationManager;
}
/**
* Configures the {@link org.perfcake.message.sequence.SequenceManager} to be used for the performance test execution.
*
* @param sequenceManager
* {@link org.perfcake.message.sequence.SequenceManager} to be used.
*/
@Override
public void setSequenceManager(final SequenceManager sequenceManager) {
this.sequenceManager = sequenceManager;
}
/**
* Gets the number of active threads in the internal executor service.
*
* @return The number of active threads.
*/
@Override
public int getActiveThreadsCount() {
return executorService.getActiveCount();
}
@Override
public long getTasksInQueue() {
return executorService.getTaskCount() - executorService.getCompletedTaskCount();
}
@Override
public boolean isFailFast() {
return failFast;
}
@Override
public void setCorrelator(final Correlator correlator) {
this.correlator = correlator;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy