package gov.nih.ncgc.bard.tools;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SearchDoS {
static final Logger logger = Logger.getLogger(SearchDoS.class.getName());
static final String[] QUERIES = new String[] {
"C[S@%2b]([O-])C1=CC=CC=C1",
"C1=CC=NC=C1",
"C1CCCCC1",
"C1=CN=CN=C1",
"N1C=CC=C1",
"C1CCNCC1",
"N1C=CN=C1",
"N1C=CC2=C1C=CC=C2",
"C1CCNC1",
"C1=CC2=C(C=C1)N=CC=C2",
"C1CNCCN1",
"N1C=CC=N1",
"C1=CC=C(C=C1)C2=CC=CC=C2",
"S1C=CC=C1",
"C(C1=CC=CC=C1)C2=CC=CC=C2",
"C1=CC2=C(C=C1)C=CC=C2",
"C1CCCC1",
"S1C=CN=C1",
"C(NC1=CC=CC=C1)C2=CC=CC=C2",
"O1C=CC=C1",
"C1CCOCC1",
"C1CCOC1",
"C1CCC2CCCCC2C1",
"C1CC1",
"N1C=NC2=C1C=CC=C2",
"C1COCCN1",
"C1CCC=CC1",
"C1=CC2=C(C=C1)N=CN=C2",
"C(OC1=CC=CC=C1)C2=CC=CC=C2",
"O=C(NC1=CC=CC=C1)C2=CC=CC=C2",
"C1=CN=CC=N1",
"N1C=NN=C1",
"C1CC2CCCC(C1)C2",
"C1CN(CCN1)C2=CC=CC=C2",
"O(C1=CC=CC=C1)C2=CC=CC=C2",
"C1CC2=C(N1)C=CC=C2",
"O=C1NC=CC=C1",
"C(N1CCNCC1)C2=CC=CC=C2",
"N1C=CC(=N1)C2=CC=CC=C2",
"C1OC2=C(O1)C=CC=C2",
"C1CCC(CC1)C2CCCCC2",
"O=C1C=CNC=N1",
"N(C1=CC=CC=C1)C2=NC=NC=C2",
"C1CC2CCCCC2C1",
"C(NCC1=CC=CC=C1)C2=CC=CC=C2",
"C1=CC=C(C=C1)C2=NC=CC=C2",
"C1CCC2=C(C1)C=CC=C2",
"C(N1CCCCC1)C2=CC=CC=C2",
"O1C=CN=C1",
"C1CC(CCN1)C2=CC=CC=C2",
"N1C=NC2=C1C=NC=N2",
"C(N1C=CN=C1)C2=CC=CC=C2",
"C1CC2=C(CN1)C=CC=C2",
"N1C=NC(=C1)C2=CC=CC=C2",
"C1=CN(N=C1)C2=CC=CC=C2",
"C1=CN=NC=C1",
"C1CCC(CC1)C2=CC=CC=C2",
"N1C=NN=N1",
"C(CC1=CC=CC=C1)NCC2=CC=CC=C2",
"C(CC1=CC=CC=C1)C2=CC=CC=C2",
"O=C1C=COC2=C1C=CC=C2",
"C1=CC=C(C=C1)C2=CN=CC=C2",
"C1CSCN1",
"C1NCC2=C1C=CC=C2",
"C1COC2=C(C1)C=CC=C2",
"O=C1C=COC=C1",
"O1C=CC=N1",
"C1CCC2C(C1)CCC3CCCCC23",
"C1CC2=C(C1)C=CC=C2",
"O=C1NC=CC(=O)N1",
"C(C=CC1=CC=CC=C1)C2=CC=CC=C2",
"C(CC1=CC=CC=C1)CC2=CC=CC=C2",
"O=C1OC=CC=C1",
"C1CCC(CC1)C2CCC3CCCCC3C2",
"S1C=NC2=C1C=CC=C2",
"O1C=CC2=C1C=CC=C2",
"N1N=CC2=C1C=CC=C2",
"C(N1C=CC=C1)C2=CC=CC=C2",
"N(C1=CC=CC=C1)C2=NC=CC=N2",
"C1=CC2=C(C=C1)C=NC=C2",
"C1CCC(C1)C2CCCCC2",
"C1CNCN1",
"N1C=CC=C1C2=CC=CC=C2",
"C1=CC2=C(C=C1)N=CC=N2",
"C1CC2CCC3CCCCC3C2C1",
"C(CNCCC1=CC=CC=C1)CC2=CC=CC=C2",
"C(NC1=CC=CC=C1)NC2=CC=CC=C2",
"N(C1=CC=CC=C1)C2=CC=NC=C2",
"O=C1OC2=C(C=CC=C2)C=C1",
"N1C=CN=C1C2=CC=CC=C2",
"C1CC(CN1)C2=CC=CC=C2",
"O=S(=O)(NC1=CC=CC=C1)C2=CC=CC=C2",
"C(CC1CCCCC1)C2CCCC2",
"O=C1CC2=C(N1)C=CC=C2",
"C(N1C=CC2=C1C=CC=C2)C3=CC=CC=C3",
"C1CC2CCC(CC2C1)C3CCCCC3",
"N(C1=CC=CC=C1)C2=C3C=CC=CC3=NC=C2",
"N1C=CN=N1",
"C(CC1CCCCC1)C2CCCCC2",
"O=C(NC1=CC=CC=C1)NC2=CC=CC=C2",
"C(=CC1=CC=CC=C1)C2=CC=CC=C2",
"N1C2=C(C=CC=C2)C3=C1C=CC=C3",
"C(CN1CCCCC1)CC2=CC=CC=C2",
"O=C1CCCO1",
"C1=CC2=CC3=C(C=CC=C3)N=C2C=C1",
"O=C1CCCC=C1",
"C1=CC=C(C=C1)C2=NC=NC=C2",
"O1C=CC=C1C2=CC=CC=C2",
"C1CCC2=CCCCC2C1",
"O=C1NC=NC2=C1C=CC=C2",
"O=C1C=CNC=C1",
"O=C1C=CNC2=C1C=CC=C2",
"C1CC=CCN1",
"S1C=CC2=C1C=CC=C2",
"C1CCC(C1)C2CCC3CCCCC3C2",
"C1CC2CCC3C(CCC4CCCCC34)C2C1",
"C1CN=CN1",
"N(C1=CC=CC=C1)C2=CC=CC=C2",
"C1=CC=C(C=C1)C2=CC=NC=C2",
"C1=CN(C=N1)C2=CC=CC=C2",
"C1CCC1",
"C1CNC1",
"O=C(NCCC1=CC=CC=C1)C2=CC=CC=C2",
"C(CNCC1=CC=CC=C1)CC2=CC=CC=C2",
"O=C(NCC1=CC=CC=C1)C2=CC=CC=C2",
"C1C2CC3CC1CC(C2)C3",
"O=C1CCCN1",
"C(CNCCNCCC1=CC=CC=C1)CC2=CC=CC=C2",
"O1C=NC=N1",
"C1COC(C1)N2C=CN=C2",
"O=C(C=CC1=CC=CC=C1)C2=CC=CC=C2",
"O=C1NC(=O)C2=C1C=CC=C2",
"C1NCC=C1",
"C1CC2=C(O1)C=CC=C2",
"C1=CN(C=C1)C2=CC=CC=C2",
"C(N1CCCC1)C2=CC=CC=C2",
"O=S(=O)(NCC1=CC=CC=C1)C2=CC=CC=C2",
"C1CCC2CC=CCC2C1",
"S1C=CC=C1C2=CC=CC=C2",
"S1C=NC(=C1)C2=CC=CC=C2",
"C(CN1CCCC1)CC2=CC=CC=C2",
"N1N=NC(=N1)C2=CC=CC=C2",
"C1=CC=C(C=C1)C2=NC=CC=N2",
"O=C(CCC1=CC=CC=C1)NCCC2=CC=CC=C2",
"C1CNC2=C(C1)C=CC=C2",
"C1NCC2=C1C=CC3=C2C=CN3",
"C1CCCNCC1",
"C(NC1=NC=NC=C1)C2=CC=CC=C2",
"C(CC1CCC2CCCCC2C1)C3CCCCC3",
"C1NCC2=C1C=CC3=C2C4=C(N3)C=CC=C4",
"C(CNCCNCCNCCC1=CC=CC=C1)CC2=CC=CC=C2",
"O1C=NC2=C1C=CC=C2",
"C1=NC=NC=N1",
"C1CC2CCCC1N2",
"N1C=CC2=C1N=CN=C2",
"C1COC(C1)N2C=NC3=C2N=CN=C3",
"O=C1C=COC(=C1)C2=CC=CC=C2",
"C(C1CCNCC1)C2=CC=CC=C2",
"N(C1=CC=CC=C1)C2=C3C=CC=CC3=NC=N2",
"C1CC=NN1",
"C1CCC2C(C1)CC=C3CCCCC23",
"C1C=CCC2=C1C=CC=C2",
"S1C=NN=C1",
"C1CN(CCN1)C2=NC=CC=C2",
"C1=CN2C=CC=CC2=N1",
"C1=CC2=C(N=C1)N=CN=C2",
"O=C(N1CCNCC1)C2=CC=CC=C2",
"C1=NC=NN=C1",
"O=C1NN=CC=C1",
"C1CCC2=C(C1)C=CC=N2",
"O1C=CN=C1C2=CC=CC=C2",
"O=C(C1=CC=CC=C1)C2=CC=CC=C2",
"C(CC1=CC=CC=C1)NC2=CC=CC=C2",
"N1C=CC(=C1)C2=CC=CC=C2",
"O=C1CCCCC1",
"C1CO1",
"O=C1C=C(OC2=C1C=CC=C2)C3=CC=CC=C3",
"O1C=NN=C1",
"N1N=CC2=C1N=CN=C2",
"C(NC1=CC=CC=C1)C=CC2=CC=CC=C2",
"C1=CC=C(C=C1)C2=NC=CN=C2",
"C(NC1=CC=CC=C1)C2=CN=CC=C2",
"N1C=C(C=N1)C2=CC=CC=C2",
"C1CC=CC1",
"C1OCC=C1",
"O=C1CNC(=O)N1",
"C1CC1C2=CC=CC=C2",
"C1C=CCC=C1",
"C(CNC1=CC=CC=C1)CC2=CC=CC=C2",
"O=C1C=CC(=O)C2=C1C=CC=C2",
"N1C=NC(=N1)C2=CC=CC=C2",
"C1NCC(S1)=CC2=CC=CC=C2",
"N1C2=C(C=CC=C2)N=C1C3=CC=CC=C3",
"C1COC2=C(O1)C=CC=C2",
"N1C(=CC2=C1C=CC=C2)C3=CC=CC=C3",
"C(CNCCNCCNCCNCCC1=CC=CC=C1)CC2=CC=CC=C2",
"C1CN(CCN1)C2=NC=NC=C2",
"N1N=NC(=N1)C2=C(C=CC=C2)C3=CC=CC=C3",
"O=C1NC2=C(C=CC=C2)C=C1",
"O=C1CCN1",
"C(CC1=CC=CC=C1)NCC2CCCN2",
"O=C1NC(=O)C=C1",
"O=C1NC(=O)C2=C1C=CC3=C2C=CN3",
"C1=CC=C(C=C1)C2=CN=CN=C2"
};
static class Stats {
String name;
long size;
int top;
Map<Integer, Integer> status = new TreeMap<Integer, Integer>();
Stats (String name) {
this.name = name;
}
public String toString () {
return "["+name+",size="+size+",top="+top+",status="+status+"]";
}
}
static class SearchWorker implements Callable<Stats> {
final CountDownLatch done;
final String url;
final int size;
Random rand = new Random ();
SearchWorker (String url, CountDownLatch done, int size) {
this.done = done;
this.url = url;
this.size = size;
}
public Stats call () {
Stats s = new Stats (Thread.currentThread().getName());
try {
s.top = 100+rand.nextInt(500);
exec (s);
done.countDown();
}
catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
void exec (Stats s) {
for (int i = 0; i < size; ++i) {
int next = rand.nextInt(QUERIES.length);
String q = QUERIES[next];
try {
URL url = new URL
(this.url+"/compounds?filter="
+q+"[structure]&top="+s.top+"&expand=true");
long start = System.currentTimeMillis();
HttpURLConnection http =
(HttpURLConnection)url.openConnection();
http.setConnectTimeout(0);// ms
http.setReadTimeout(0);// ms
long b = getByteCount (http.getInputStream());
long e = System.currentTimeMillis()-start;
int code = http.getResponseCode();
Integer c = s.status.get(code);
s.status.put(code, c == null ? 1 : (c+1));
logger.info(Thread.currentThread().getName()
+": q="+q+" len="
+b+" status=" +code+" top="+s.top
+" time="+e+"ms");
s.size += b;
}
catch (Exception ex) {
logger.log(Level.SEVERE,
"Can't establish network connection", ex);
}
}
}
long getByteCount (InputStream is) throws IOException {
long size = 0;
byte[] buf = new byte[1024];
for (int nb; (nb = is.read(buf, 0, buf.length)) > 0; ) {
size += nb;
}
return size;
}
}
String url;
ExecutorService threadPool;
int connections;
public SearchDoS (String url, int connections) {
this.url = url;
this.connections = connections;
threadPool = Executors.newFixedThreadPool(connections);
}
public void execute () throws Exception {
execute (QUERIES.length);
}
public void execute (int qsize) throws Exception {
CountDownLatch done = new CountDownLatch (connections);
List<Future<Stats>> workers = new ArrayList<Future<Stats>>();
for (int i = 0; i < connections; ++i) {
workers.add(threadPool.submit
(new SearchWorker (url, done, qsize)));
}
done.await();
for (Future<Stats> f : workers) {
logger.info(""+f.get());
}
}
public void shutdown () {
try {
threadPool.shutdownNow();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main (String[] argv) throws Exception {
if (argv.length < 1) {
System.out.println("Usage: SearchDoS URL [CONNECTIONS=20]");
System.exit(1);
}
int connections = 20;
if (argv.length > 1) {
connections = Integer.parseInt(argv[1]);
}
logger.info("DoS against "+argv[0]+" with "+connections
+" simultaneous connections...");
SearchDoS dos = new SearchDoS (argv[0], connections);
dos.execute();
dos.shutdown();
}
}