Home
| SF Project
| Download
| Forum
| Bugs
| History
| For Coders
| HowTo
| Commentary
| TODO
|
#!/bin/sh . env.sh PROXY_PROPS="-Dlisten.port=9090 -Dtarget.host=dev1 -Dtarget.port=9090" #PROXY_PROPS="$PROXY_PROPS -Dlatency.millis=250" #PROXY_PROPS="$PROXY_PROPS -Dpacket.loss.rate=100" #PROXY_PROPS="$PROXY_PROPS -Dbandwidth.throttle=50" #PROXY_PROPS="$PROXY_PROPS -Denable.connection.loss=true" java $PROXY_PROPS -Xmx1024m -cp "$CP" com.moneybender.proxy.ProxyThe lines that change connection behavior are commented, and can be used individually or in concert by the ones with the desired affect.
PROXY_PROPS="$PROXY_PROPS -Dlatency.millis=250"and change the latency to suit. The latency is stated in milliseconds, and each packet that is received by the proxy will be delayed by this amount before being sent to the target receiver. This can be used to simulate connections that have a high latency, such as through a satellite. If you're developing a web service, web application, or other network service, you can get a rough gauge of your users' experience when using the service.
A connection through a satellite in geostationary orbit (22,236 miles above sea level) will experience roughly 240 milliseconds of delay for the total round-trip due to the propagation delay, so
-Dlatency.millis=240should simulate the affect pretty closely.
PROXY_PROPS="$PROXY_PROPS -Dbandwidth.throttle=50"This will limit the bandwidth to 50 KBPS. This is useful to simulate the affect of a slow connection such as a dial-up modem. Use this to see what a web site or web application's behavior might be on a slow connection.
PROXY_PROPS="$PROXY_PROPS -Dpacket.loss.rate=100"This specifies the denominator - so a packet-loss rate of 100 will drop one of every 100 packets. A packet-loss rate of 30 would lose 1 of every 30 packets. I expect that this might change in the future to be more flexible.
PROXY_PROPS="$PROXY_PROPS -Denable.connection.loss=true"This enables the connection loss, but you have to trigger it. Typically, this will occur in one of two ways.
In the first approach, you need to have a Java program that starts and stops the Proxy. Look at the main() method in Proxy.java and ProxyTest.java for examples. After your program starts the proxy, it can do some stuff that generates traffic. At the point in your code where you want to simulate a network failure, call ConnectionLossDecorator.networkOff(). When you want to simulate the return of the network, call ConnectionLossDecorator.networkOff(). Your code might look something like this:
Proxy proxy = new Proxy();
proxy.start(new ProxySettings());
System.out.println("Sleep");
Thread.sleep(30000);
System.out.println("Break connections");
ConnectionLossDecorator.networkOff();
Thread.sleep(5000);
System.out.println("Fix connections");
ConnectionLossDecorator.networkOn();
System.out.println("wait");
synchronized(proxy) {
proxy.wait();
}
This can be useful in integration tests when you want to simulate network loss, and see how your application behaves.Here's how networkOff() works. When you call it, it sets a flag. All channels will fail on the next read() when that flag is set, and the channels will therefore close with an I/O error. When the networkOn() is called, the flag is cleared and new channels will work normally.
In the second approach, you don't need a Java program, but instead you manually or programmatically toggle the network state via JMX. You can use JMX to do this. Look at DecoratorState...Operations in JConsole:

Use the buttons to enable or disable network connectivity. When the proxy starts, the network will be enabled by default. For example, start the proxy:
./proxy.sh 2008-04-06 08:02:07,687 INFO [ByteReaderFactory] - Connection loss enabled. Call ConnectionLossDecorator.networkOn() and ConnectionLossDecorator.networkOff() to toggle. 2008-04-06 08:02:07,734 INFO [SocketSelectHandler] - Listening on port 9090, target at dev1:9090Connect to the proxy with JConsole, and browse to the DecoratorControl Operations. Then start your application. I'll use curl as an example:
curl -D - --proxy localhost:9090 -O http://suse.mirrors.tds.net/pub/opensuse/distribution/10.3/iso/dvd/openSUSE-10.3-GM-DVD-i386.isoNext, click the networkOff operation. You should see curl fail:
curl -D - --proxy localhost:9090 -O http://suse.mirrors.tds.net/pub/opensuse/distribution/10.3/iso/dvd/openSUSE-10.3-GM-DVD-i386.iso % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:15 --:--:-- 0HTTP/1.1 200 OK Date: Sun, 06 Apr 2008 13:01:00 GMT Server: Apache/2.2.0 Last-Modified: Thu, 27 Sep 2007 15:50:25 GMT ETag: "1073001d-69bd800-edb61240" Accept-Ranges: bytes Content-Length: 4405843968 Expires: Mon, 07 Apr 2008 13:04:04 GMT Content-Type: application/octet-stream Via: 1.1 dev1:9090 0 4201M 0 1338k 0 0 69867 0 17:31:00 0:00:19 17:30:41 296k curl: (18) transfer closed with 4404473088 bytes remaining to readThat's all there is to it.