/* * Copyright 2015 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.springframework.xd.loadgenerator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.integration.endpoint.MessageProducerSupport; import org.springframework.integration.support.MessageBuilder; /** * Is a source module that generates a series of fixed size messages to be * dispatched to a stream. The load-generator is used to test the performance of * XD in different environments. * * @author Janne Valkealahti */ public class LoadGenerator extends MessageProducerSupport { private int producers; private int messageCount; private int recordCount; private String recordDelimiter; private boolean recordType; private long sleepTime; private int sleepCount; private final boolean sleep; private final AtomicBoolean running = new AtomicBoolean(false); private ExecutorService executorService; Logger logger = LoggerFactory.getLogger(LoadGenerator.class); public LoadGenerator(int producers, int messageCount, int recordCount, String recordDelimiter, String recordType, long sleepTime, int sleepCount) { this.producers = producers; this.messageCount = messageCount; this.recordCount = recordCount; if ("\\t".equals(recordDelimiter)) { this.recordDelimiter = "\t"; } else { this.recordDelimiter = recordDelimiter; } if ("counter".equals(recordType)) { this.recordType = true; } this.sleepTime = sleepTime; this.sleepCount = sleepCount; this.sleep = sleepTime > 0 && sleepCount > 0; } @Override protected void doStart() { executorService = Executors.newFixedThreadPool(producers); if (running.compareAndSet(false, true)) { for (int x = 0; x < producers; x++) { executorService.submit(new Producer(Integer.toString(x))); } } } @Override protected void doStop() { if (running.compareAndSet(true, false)) { executorService.shutdown(); } } protected class Producer implements Runnable { String prefix; public Producer(String prefix) { this.prefix = prefix; } private void send() { logger.info("Sending " + messageCount + " messages"); for (int x = 0; x < messageCount; x++) { StringBuilder buf = new StringBuilder(); buf.append(prefix); for (int i = 0; i < recordCount; i++) { buf.append(recordDelimiter); if (recordType) { buf.append(x); } else { buf.append(System.nanoTime()); } } sendMessage(MessageBuilder.withPayload(buf.toString()).build()); if (sleep && ((x + 1) % sleepCount) == 0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } logger.info("All Messages Dispatched"); } public void run() { send(); } } }