Last active
January 29, 2022 05:22
-
-
Save jstefek/51795a0c9882e88cffb200567d625721 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Get the jar:
Setup tomcat
<Valve className="org.whatever.request.delay.DelayValve" />
How to set it up?