Simulator.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
requestssimulator /
Simulator.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package br.ufrgs.inf.prosoft.requestssimulator;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
/**
*
* @author romulo
*/
public class Simulator {
private static final Logger logger = Logger.getLogger(Simulator.class.getName());
public static final void simulate(String path) {
simulate(path, 1);
}
public static final void simulate(String path, int users) {
if (users < 1) {
logger.log(Level.SEVERE, "informed {0} users. Using 1", users);
users = 1;
}
try {
long count = Files.lines(Paths.get(path)).count();
logger.log(Level.INFO, "requesting {0} URLS", count);
if (users == 1) {
Stream<String> lines = Files.lines(Paths.get(path));
lines.forEach(new RequestProcesser());
} else {
List<String> requests = Files.readAllLines(Paths.get(path));
int requestsSize = requests.size();
int inclusiveStart = 0;
int partitionSize = requestsSize / users;
if (partitionSize < 1) {
partitionSize = 1;
logger.log(Level.SEVERE, "more users {0} than requests {1}. Using {1} users", new Object[]{users, requests.size()});
}
Collection<Thread> threads = new ArrayList<>();
while (inclusiveStart < requestsSize) {
int exclusiveEnd = inclusiveStart + partitionSize;
Thread thread = new Thread(new PartitionProcesser(requests, inclusiveStart, exclusiveEnd));
thread.start();
threads.add(thread);
inclusiveStart = exclusiveEnd;
}
threads.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException ex) {
logger.log(Level.SEVERE, "thread stopped");
}
});
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "cannot open file {0}", path);
}
}
private static class RequestProcesser implements Consumer<String> {
private int i;
public RequestProcesser() {
this.i = 1;
}
public RequestProcesser(int i) {
this.i = i;
}
@Override
public void accept(String line) {
try {
if (line.startsWith("POST")) {
String[] split = line.split(" ");
URL url = new URL(split[1]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
try (OutputStream outputStream = connection.getOutputStream()) {
outputStream.write(split[2].getBytes());
}
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
logger.log(Level.INFO, "{0} {1}", new Object[]{i, line});
} else {
logger.log(Level.SEVERE, "{0} error {1} on {2}", new Object[]{i, responseCode, line});
}
connection.disconnect();
} else {
URL url = new URL(line);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
logger.log(Level.INFO, "{0} GET {1}", new Object[]{i, line});
} else {
logger.log(Level.SEVERE, "{0} error {1} on {2}", new Object[]{i, responseCode, line});
}
connection.disconnect();
}
} catch (MalformedURLException ex) {
logger.log(Level.SEVERE, "Malormed URL");
} catch (IOException ex) {
logger.log(Level.SEVERE, "IOException");
}
i++;
}
}
private static class PartitionProcesser implements Runnable {
private final Stream<String> requests;
private final int inclusiveStart;
public PartitionProcesser(List<String> requests, int incusiveStart, int exclusiveEnd) {
this.inclusiveStart = incusiveStart;
this.requests = requests.subList(incusiveStart, exclusiveEnd).stream();
}
public PartitionProcesser(Stream<String> requests) {
this.requests = requests;
this.inclusiveStart = 1;
}
@Override
public void run() {
this.requests.forEach(new RequestProcesser(this.inclusiveStart + 1));
}
}
}