Simulator.java

84 lines | 2.618 kB Blame History Raw Download
/*
 * 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 br.ufrgs.inf.prosoft.requestssimulator.requests.Request;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * @author romulo
 */
public class Simulator {

  private static final Logger LOGGER = Logger.getLogger(Simulator.class.getName());

  public static final void simulate(Profile profile, long time) {
    simulate(profile, time, 1);
  }

  public static final void simulate(Profile profile, long time, int users) {
    simulate(profile, time, users, null);
  }

  public static final void simulate(Profile profile, long time, String logPath) {
    simulate(profile, time, 1, logPath);
  }

  public static final void simulate(Profile profile, long time, int users, String logPath) {
    LOGGER.log(Level.INFO, "simulating with {0} users for {1} millis", new Object[]{users, time});
    Collection<Thread> threads = new ArrayList<>();
    List<Profile> profiles = new ArrayList<>();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> writeLog(logPath, profiles)));
    for (int i = 0; i < users; i++) {
      Profile clone = profile.clone();
      profiles.add(clone);
      Thread thread = new Thread(() -> clone.simulate(time));
      threads.add(thread);
    }
    threads.forEach(Thread::start);
    threads.forEach(thread -> {
      try {
        thread.join();
      } catch (InterruptedException ex) {
        LOGGER.log(Level.SEVERE, null, ex);
      }
    });
  }

  private static void writeLog(String logPath, List<Profile> profiles) {
    if (logPath != null) {
      LOGGER.log(Level.INFO, "writing log");
      List<List<List<JsonObject>>> logs = profiles.stream()
        .map(profile
          -> profile.sessions()
          .map(session
            -> session.requests()
            .map(Request::toJsonObject)
            .collect(Collectors.toList()))
          .collect(Collectors.toList()))
        .collect(Collectors.toList());
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      try (Writer writer = new FileWriter(logPath)) {
        gson.toJson(logs, writer);
      } catch (IOException ex) {
        LOGGER.log(Level.SEVERE, "invalid log path");
      }
    }
  }
}