Details
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Profile.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Profile.java
index 69f2de8..7ebea54 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Profile.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Profile.java
@@ -26,9 +26,13 @@ public class Profile {
public Profile(Map<String, RequestPlan> urlHasRequestPlan) {
this.urlHasRequestPlan = urlHasRequestPlan;
Map<String, RequestPlan> rootsReferences = new HashMap<>(this.urlHasRequestPlan);
- this.urlHasRequestPlan.values().forEach(requestPlan -> {
+ this.urlHasRequestPlan.forEach((reference, requestPlan) -> {
+ if (reference.charAt(0) == '*') {
+ rootsReferences.remove(reference);
+ return;
+ }
if (requestPlan.links().count() == 0) {
- rootsReferences.remove(requestPlan.getReference());
+ rootsReferences.remove(reference);
return;
}
requestPlan.links().forEach(linkReference -> {
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/ProfileReader.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/ProfileReader.java
index 7cf014f..6d8855f 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/ProfileReader.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/ProfileReader.java
@@ -10,9 +10,8 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -20,8 +19,6 @@ import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
*
@@ -30,19 +27,21 @@ import java.util.stream.Stream;
public class ProfileReader {
public static Profile parseFile(String profilePath) {
- String fileContent = null;
- try (Stream<String> lines = Files.lines(Paths.get(profilePath))) {
- fileContent = lines.collect(Collectors.joining());
- } catch (IOException ex) {
- Logger.getLogger(ProfileReader.class.getName()).log(Level.SEVERE, null, ex);
+ FileReader fileReader = null;
+ try {
+ fileReader = new FileReader(profilePath);
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(ProfileReader.class.getName()).log(Level.SEVERE, "File not found");
+ System.exit(1);
}
Map<String, RequestPlan> urlHasRequestPlan = new HashMap<>();
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
- JsonObject jsonObject = jsonParser.parse(fileContent).getAsJsonObject();
+ JsonObject jsonObject = jsonParser.parse(fileReader).getAsJsonObject();
jsonObject.entrySet().forEach(entry -> {
RequestPlan requestPlan = gson.fromJson(entry.getValue(), RequestPlan.class);
- urlHasRequestPlan.put(entry.getKey(), requestPlan);
+ requestPlan.setReference(entry.getKey());
+ urlHasRequestPlan.put(requestPlan.getReference(), requestPlan);
});
jsonObject.entrySet().forEach(entry -> {
RequestPlan requestPlan = urlHasRequestPlan.get(entry.getKey());
@@ -50,8 +49,8 @@ public class ProfileReader {
JsonObject jsonRequestPlan = entry.getValue().getAsJsonObject();
JsonElement linksReferencesElement = jsonRequestPlan.get("linksReferences");
if (linksReferencesElement != null) {
- linksReferencesElement.getAsJsonArray().forEach(array -> {
- linksReferences.add(array.getAsString());
+ linksReferencesElement.getAsJsonArray().forEach(linkElement -> {
+ linksReferences.add(linkElement.getAsString());
});
linksReferences.forEach(new Consumer<String>() {
@Override
@@ -59,13 +58,16 @@ public class ProfileReader {
RequestPlan link;
if (linkReference.charAt(0) == '*') {
link = urlHasRequestPlan.get(linkReference.substring(1));
+ if (link == null) {
+ throw new RuntimeException("link not declared: " + linkReference);
+ }
link.links().forEach(referenceToCopy -> {
accept(referenceToCopy.getReference());
});
} else {
link = urlHasRequestPlan.get(linkReference);
if (link == null) {
- throw new RuntimeException("link not declared");
+ throw new RuntimeException("link not declared: " + linkReference);
}
requestPlan.addLink(link);
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/DeleteRequest.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/DeleteRequest.java
index d3ca315..f1cfc8e 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/DeleteRequest.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/DeleteRequest.java
@@ -13,6 +13,7 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -51,6 +52,8 @@ public class DeleteRequest extends Request {
int responseCode = connection.getResponseCode();
if (responseCode < 400) {
Logger.getGlobal().log(Level.INFO, "{0} on {1} {2}", new Object[]{responseCode, getMethod(), stringURL});
+ List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
+ storeCookies(setCookies);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String response = bufferedReader.lines().collect(Collectors.joining());
processResponse(response);
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/GetRequest.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/GetRequest.java
index 5ff0844..819fb63 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/GetRequest.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/GetRequest.java
@@ -13,6 +13,7 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -51,6 +52,8 @@ public class GetRequest extends Request {
int responseCode = connection.getResponseCode();
if (responseCode < 400) {
Logger.getGlobal().log(Level.INFO, "{0} on {1} {2}", new Object[]{responseCode, getMethod(), stringURL});
+ List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
+ storeCookies(setCookies);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String response = bufferedReader.lines().collect(Collectors.joining());
processResponse(response);
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/MultipartRequest.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/MultipartRequest.java
index 600699c..e1901f1 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/MultipartRequest.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/MultipartRequest.java
@@ -10,8 +10,10 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -54,9 +56,9 @@ public class MultipartRequest extends Request {
public Stream<Map.Entry<String, String>> forms() {
Map<String, String> forms = new HashMap<>();
if (this.forms != null) {
- String[] formsPairs = this.forms.split("; ");
+ String[] formsPairs = this.forms.split("&");
for (String formPair : formsPairs) {
- String[] pair = formPair.split(": ");
+ String[] pair = formPair.split("=");
forms.put(pair[0], pair[1]);
}
}
@@ -87,6 +89,10 @@ public class MultipartRequest extends Request {
int responseCode = closeableHttpResponse.getStatusLine().getStatusCode();
if (responseCode < 400) {
Logger.getGlobal().log(Level.INFO, "{0} on {1} {2}", new Object[]{responseCode, getMethod(), stringURL});
+ List<String> setCookies = Arrays.asList(closeableHttpResponse.getHeaders("Set-Cookie")).stream()
+ .map(header -> header.getName() + "=" + header.getValue())
+ .collect(Collectors.toList());
+ storeCookies(setCookies);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(closeableHttpResponse.getEntity().getContent()))) {
String response = bufferedReader.lines().collect(Collectors.joining());
processResponse(response);
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/PostRequest.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/PostRequest.java
index 7ab2cbf..f55bbed 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/PostRequest.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/PostRequest.java
@@ -14,6 +14,7 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -66,6 +67,8 @@ public class PostRequest extends Request {
int responseCode = connection.getResponseCode();
if (responseCode < 400) {
Logger.getGlobal().log(Level.INFO, "{0} on {1} {2}", new Object[]{responseCode, getMethod(), stringURL});
+ List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
+ storeCookies(setCookies);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String response = bufferedReader.lines().collect(Collectors.joining());
processResponse(response);
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/Request.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/Request.java
index d89a717..20b8896 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/Request.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/Request.java
@@ -13,6 +13,7 @@ import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
@@ -104,15 +105,41 @@ public abstract class Request {
return this.storeFields.stream();
}
+ private Stream<String> storeCookies() {
+ return this.requestPlan.storeCookies();
+ }
+
public Request pickNextRequest(Session session) {
return this.requestPlan.pickNextRequest(session);
}
+ protected void storeCookies(List<String> cookies) {
+ if (storeCookies().count() == 0) {
+ return;
+ }
+ Map<String, String> map = new HashMap<>();
+ cookies.stream().forEach(cookieGroup -> {
+ String[] cookiePairs = cookieGroup.split("; ");
+ for (String cookiePair : cookiePairs) {
+ String[] pair = cookiePair.split("=");
+ if (pair.length > 1) {
+ map.put(pair[0], pair[1]);
+ }
+ }
+ });
+ storeCookies().forEach(storeCookie -> {
+ storeValue(storeCookie, map.get(storeCookie));
+ });
+ }
+
protected void processResponse(String response) {
if (response == null || response.isEmpty()) {
Logger.getGlobal().log(Level.SEVERE, "empty response");
return;
}
+ if (storeFields().count() == 0) {
+ return;
+ }
storeFields().forEach(new Consumer<String>() {
private final JsonParser jsonParser;
@@ -268,6 +295,13 @@ public abstract class Request {
});
jsonObject.add("storeFields", storeFields);
}
+ if (storeCookies().count() > 0) {
+ JsonArray storeCookies = new JsonArray();
+ storeCookies().forEach(storeCookie -> {
+ storeCookies.add(storeCookie);
+ });
+ jsonObject.add("storeCookies", storeCookies);
+ }
if (this instanceof PostRequest) {
PostRequest postRequest = (PostRequest) this;
jsonObject.addProperty("data", postRequest.getData());
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/RequestPlan.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/RequestPlan.java
index b889e5b..6aa7a0f 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/RequestPlan.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/requests/RequestPlan.java
@@ -8,7 +8,9 @@ package br.ufrgs.inf.prosoft.requestssimulator.requests;
import br.ufrgs.inf.prosoft.requestssimulator.Session;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Matcher;
@@ -25,9 +27,11 @@ public class RequestPlan {
private final String method;
private final String URL;
private final String data;
+ private String reference;
private List<RequestPlan> readLinks;
private List<RequestPlan> writeLinks;
private Collection<String> storeFields;
+ private Collection<String> storeCookies;
private Collection<RequestPlan> requirements;
private String headers;
private String forms;
@@ -44,6 +48,12 @@ public class RequestPlan {
this.data = data;
}
+ private RequestPlan(String method, String URL, String data) {
+ this.method = method;
+ this.URL = URL;
+ this.data = data;
+ }
+
public static RequestPlan get(String URL) {
return new RequestPlan(URL);
}
@@ -52,12 +62,24 @@ public class RequestPlan {
return new RequestPlan(URL, data);
}
+ public static RequestPlan delete(String URL, String data) {
+ return new RequestPlan("DELETE", URL, data);
+ }
+
public String getMethod() {
return this.method;
}
+ public RequestPlan setReference(String reference) {
+ this.reference = reference;
+ return this;
+ }
+
public String getReference() {
- return this.method + "@" + this.URL;
+ if (this.reference == null) {
+ return method + "@" + this.URL;
+ }
+ return this.reference;
}
public RequestPlan addHeader(String header) {
@@ -148,12 +170,19 @@ public class RequestPlan {
}
return this.storeFields.stream();
}
+
+ protected Stream<String> storeCookies() {
+ if (this.storeCookies == null || this.storeCookies.isEmpty()) {
+ return Stream.empty();
+ }
+ return this.storeCookies.stream();
+ }
public Request pickNextRequest(Session session) {
Random random = new Random();
int probability = random.nextInt(100);
if ((this.readLinks == null || this.readLinks.isEmpty()) && (this.writeLinks == null || this.writeLinks.isEmpty())) {
- throw new RuntimeException("GET and POST links empty");
+ throw new RuntimeException("GET and POST links empty: " + this.URL);
}
RequestPlan chosen;
if (this.readLinks == null || this.readLinks.isEmpty()) {
@@ -172,26 +201,27 @@ public class RequestPlan {
}
public Request build(Session session) {
- Random random = new Random();
- int randomInt = random.nextInt() & Integer.MAX_VALUE;
if (this.URL == null || this.URL.isEmpty()) {
throw new RuntimeException("URL is empty");
}
- String URL = this.URL.replace("$", String.valueOf(randomInt));
- Pattern pattern = Pattern.compile("#\\{(.*?)\\}");
+ String URL = replaceOptionals(this.URL);
+ HashMap<String, Integer> map = new HashMap<>();
+ URL = replaceRandoms(URL, map);
+ Pattern pattern = Pattern.compile("#\\{(.*?)\\[(.*?)\\](.*?)\\}");
Matcher originalMatcher = pattern.matcher(this.URL);
Matcher randomMatcher = pattern.matcher(URL);
- while (originalMatcher.find() && randomMatcher.find()) {
+ while (originalMatcher.find() & randomMatcher.find()) {
String originalFound = originalMatcher.group();
String randomFound = randomMatcher.group();
URL = URL.replace(randomFound, originalFound);
}
Collection<String> storeFields = storeFields()
- .map(storeField -> storeField.replace("$", String.valueOf(randomInt)))
+ .map(storeField -> replaceRandoms(storeField, map))
.collect(Collectors.toList());
String headers = null;
if (this.headers != null) {
- headers = this.headers.replace("$", String.valueOf(randomInt));
+ headers = replaceOptionals(this.headers);
+ headers = replaceRandoms(headers, map);
if (this.headers.contains("multipart")) {
String forms = this.forms;
return new MultipartRequest(this, session, URL, headers, forms, storeFields);
@@ -203,10 +233,60 @@ public class RequestPlan {
if (this.method.equals("GET")) {
return new GetRequest(this, session, URL, headers, storeFields);
}
- String data = this.data.replace("$", String.valueOf(randomInt));;
+ String data = replaceOptionals(this.data);
+ data = replaceRandoms(data, map);
return new PostRequest(this, session, URL, data, headers, storeFields);
}
+ private String replaceRandoms(String data) {
+ return replaceRandoms(data, new HashMap<>());
+ }
+
+ private String replaceRandoms(String data, Map<String, Integer> map) {
+ Random random = new Random();
+ Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
+ Matcher randomMatcher = pattern.matcher(data);
+ while (randomMatcher.find()) {
+ String randomFound = randomMatcher.group();
+ String randomTrimmed = randomFound.substring(2, randomFound.length() - 1);
+ int randomInt;
+ if (map.containsKey(randomFound)) {
+ randomInt = map.get(randomFound);
+ } else {
+ String[] split = randomTrimmed.split("-");
+ int from = Integer.valueOf(split[0]);
+ int to = Integer.valueOf(split[1]);
+ randomInt = random.nextInt(to - from + 1) + from;
+ map.put(randomFound, randomInt);
+ }
+ data = data.replace(randomFound, String.valueOf(randomInt));
+ }
+ int randomInt;
+ if (map.containsKey("$")) {
+ randomInt = map.get("$");
+ } else {
+ randomInt = random.nextInt() & Integer.MAX_VALUE;
+ map.put("$", randomInt);
+ }
+ data = data.replace("$", String.valueOf(randomInt));
+ return data;
+ }
+
+ private String replaceOptionals(String data) {
+ Pattern pattern = Pattern.compile("<(.*?)>");
+ Matcher matcher = pattern.matcher(data);
+ Random random = new Random();
+ while (matcher.find()) {
+ String options = matcher.group();
+ String optionsTrimmed = options.substring(1, options.length() - 1);
+ String[] split = optionsTrimmed.split("\\|");
+ int nextInt = random.nextInt(split.length);
+ String choice = split[nextInt];
+ data = data.replace(options, choice);
+ }
+ return data;
+ }
+
public Request bind(Request request, Session session) {
if (request instanceof DeleteRequest) {
DeleteRequest deleteRequest = (DeleteRequest) request;
diff --git a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Session.java b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Session.java
index c7a363f..eab37e3 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Session.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/requestssimulator/Session.java
@@ -48,10 +48,16 @@ public class Session {
Random random = new Random();
Request request = null;
int probability = 0;
- while (probability < 50) {
- request = pickNextRequest(request);
+ while (probability < 70) {
+ try {
+ request = pickNextRequest(request);
+ } catch (RuntimeException ex) {
+ break;
+ }
request.fire();
- this.logs.add(request.toJsonObject());
+ JsonObject logRequest = request.toJsonObject();
+ logRequest.addProperty("time", System.currentTimeMillis());
+ this.logs.add(logRequest);
probability = random.nextInt(100);
}
}