Skip to content

Instantly share code, notes, and snippets.

@jstefek
Last active January 29, 2022 05:22
Show Gist options
  • Save jstefek/51795a0c9882e88cffb200567d625721 to your computer and use it in GitHub Desktop.
Save jstefek/51795a0c9882e88cffb200567d625721 to your computer and use it in GitHub Desktop.
package org.whatever.request.delay;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
public class DelayValve extends ValveBase {
private static final Pattern DELAY_PATTERN = Pattern.compile(".*delay=(\\d+).*");
private static final Pattern FOR_CONTEXT_PATH_PATTERN = Pattern.compile(".*path=([a-zA-Z0-9]*).*");
private static final Pattern MIN_DELAY_PATTERN = Pattern.compile(".*minDelay=(\\d+).*");
private static final Random RANDOM = new Random();
private static int delay = 0;
private static String forContextPath = "";
private static int minDelay = 100;
private long getRandomDelay() {
return Math.max(minDelay, RANDOM.nextInt(delay));
}
private String initDelaysAndGetContextPath(Request request) {
HttpServletRequest r = request.getRequest();
String contextPath = r.getContextPath();
if (contextPath.isEmpty()) {// process only when context path is empty (e.g. 'localhost:8080/')
String queryString = r.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
Matcher matcher = DELAY_PATTERN.matcher(queryString);
if (matcher.find()) {
delay = Integer.valueOf(matcher.group(1));
Logger.getLogger(DelayValve.class.getName()).log(Level.INFO, "Delay set to " + delay);
}
matcher = MIN_DELAY_PATTERN.matcher(queryString);
if (matcher.find()) {
minDelay = Integer.valueOf(matcher.group(1));
Logger.getLogger(DelayValve.class.getName()).log(Level.INFO, "Minimum delay set to " + minDelay);
}
matcher = FOR_CONTEXT_PATH_PATTERN.matcher(queryString);
if (matcher.find()) {
forContextPath = matcher.group(1);
Logger.getLogger(DelayValve.class.getName()).log(Level.INFO, "Base context path set to " + forContextPath);
}
}
}
if (contextPath.startsWith("/")) {
contextPath = contextPath.substring(1);
}
return contextPath;
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (initDelaysAndGetContextPath(request).startsWith(forContextPath) && delay > 0) {
try {
long randomDelay = getRandomDelay();
Logger.getLogger(DelayValve.class.getName()).log(Level.INFO, "sleeping for " + randomDelay);
TimeUnit.MILLISECONDS.sleep(randomDelay);
} catch (InterruptedException ex) {
Logger.getLogger(DelayValve.class.getName()).log(Level.SEVERE, null, ex);
}
}
getNext().invoke(request, response);
}
}
@jstefek
Copy link
Author

jstefek commented Feb 1, 2017

Get the jar:

  • built it with dependency : org.apache.tomcat:tomcat-catalina:7.0.73
  • or download following and rename png -> jar and use that instead (sorry no zip/jar attachments)
    tomcat-request-delay-1 0-snapshot

Setup tomcat

  • add the jar from previous step to the tomcat/lib folder.
  • add following line to the tomcat/conf/server.xml under other valves for localhost
    <Valve className="org.whatever.request.delay.DelayValve" />

How to set it up?

  • start Tomcat and wait until it starts and deploys all the applications
  • all settings can be set up in a real time using queries to the base (no context path) URL
  • to set context path (default is "", resolves to all requests) for delays: open URL with path attribute. E.g.: http://localhost:8080/?path=vmweb will preform the delays when the context path is starting with 'vmweb' (e.g. http://localhost:8080/vmwebWhatever/whatever2)
  • to set the maximum value of random delay interval (default is 0 ms): open URL with delay attribute. E.g.: http://localhost:8080/?delay=3000 will set the delay randomly from 0 to 3000 ms
  • to set the minimum delay (default is 100 ms): open URL with minDelay attribute. E.g.: http://localhost:8080/?minDelay=500 will increase the minimum of delay interval to 500 ms (when there is no delay set, this value is ignored)
  • all can be set up in one step: just open URL with all the attribuites separated with '&'. E.g.: http://localhost:8080/?path=vmweb&delay=1500&minDelay=500 will set the delay randomly from 500 to 1500 ms only for context path starting with 'vmweb'

@infa-ddeore
Copy link

nice work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment