loadTest.loadTestLib.LUtil.java Source code

Java tutorial

Introduction

Here is the source code for loadTest.loadTestLib.LUtil.java

Source

/*
 * 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 loadTest.loadTestLib;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.pieShare.pieShareApp.service.PieShareService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

/**
 *
 * @author richy
 */
public class LUtil {

    private static boolean runInDockerCluster = false;
    private static boolean dockerError;
    private static int doneDockers;
    private static boolean useDocker = false;
    private HashMap<String, Integer> startedClusterContainer = new HashMap<>();
    private HashMap<String, List<String>> runningContainers = new HashMap<>();
    private List<Process> slaves = new ArrayList<>();

    public static boolean UseDocker() {
        return useDocker;
    }

    public static String getWorkingDir() {
        return "loadTest/workingDir";
    }

    public static String getTmpDir() {
        return "loadTest/tmpDir";
    }

    public static String getConfigDir() {
        return "loadTest/loadTestConfig";
    }

    public static void setUpEnviroment() {
        System.setProperty("java.net.preferIPv4Stack", "true");
        System.setProperty("jgroups.logging.log_factory_class",
                "org.pieShare.pieTools.piePlate.service.cluster.jgroupsCluster.JGroupsLoggerFactory");
    }

    public void performTearDown(ApplicationContext context) throws Exception {

        int responseCode = -1;
        if (runInDockerCluster) {
            try {
                for (Entry<String, List<String>> node : runningContainers.entrySet()) {
                    for (String container : node.getValue()) {
                        String url = String.format("%s/containers/%s/stop?t=0", node.getKey(), container);
                        URL obj = new URL(url);
                        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                        con.setRequestMethod("POST");
                        responseCode = con.getResponseCode();
                        con.disconnect();
                    }
                }

                if (responseCode != 204) {
                    dockerError = true;
                }
            } catch (MalformedURLException ex) {
                dockerError = true;
            } catch (FileNotFoundException ex) {
                dockerError = true;
            } catch (IOException ex) {
                dockerError = true;
            }

            if (dockerError) {
                throw new Exception("Error closing docker containers!");
            }
        }

        /*PieShareService service = context.getBean(PieShareService.class);
        service.stop();
        System.out.println("Services stoped!");
            
        ConfigurableApplicationContext con = (ConfigurableApplicationContext)context;
        con.close();*/

        slaves.forEach(s -> s.destroy());
    }

    public void performTearDownDelete() throws Exception {
        FileUtils.deleteDirectory(new File(getWorkingDir()));
        FileUtils.deleteDirectory(new File(getTmpDir()));
        FileUtils.deleteDirectory(new File(getConfigDir()));
    }

    public static List<LoadTestConfigModel> readJSONConfig() throws IOException {
        InputStream in = LUtil.class.getClassLoader().getResourceAsStream("loadTestConfig.json");
        ObjectMapper mapper = new ObjectMapper();
        List<LoadTestConfigModel> myObjects = mapper.readValue(in,
                mapper.getTypeFactory().constructCollectionType(List.class, LoadTestConfigModel.class));
        return myObjects;
    }

    public static void setUpResultFile() throws IOException {
        FileWriter writer = new FileWriter("loadTestResults.csv");
        writer.write("NodeCount,FileCount,FileSize,ResultTime\n");
        writer.flush();
        writer.close();
    }

    public static void writeCSVResult(LoadTestConfigModel model, long resTime) throws IOException {
        FileWriter writer = new FileWriter("loadTestResults.csv", true);
        writer.append(String.valueOf(model.getNodeCount()));
        writer.append(",");
        writer.append(String.valueOf(model.getFileCount()));
        writer.append(",");
        writer.append(String.valueOf(model.getFileSize()));
        writer.append(",");
        writer.append(String.valueOf(resTime));
        writer.append("\n");
        writer.flush();
        writer.close();
    }

    public static boolean IsMaster() {
        String ltType = System.getenv("LTTYPE");

        if (ltType == null) {
            return true;
        }

        if (ltType.equals("master")) {
            return true;
        }

        return false;
    }

    public static HashMap<String, Integer> getDockerNodes() {
        HashMap<String, Integer> dockerNodes = new HashMap<>();
        dockerNodes.put("http://127.0.0.1:2375", 5);
        //dockerNodes.put("192.168.0.16:2375", 5);
        return dockerNodes;
    }

    public static void runInDockerCluster() {
        runInDockerCluster = true;
    }

    public static boolean startDockerBuild() throws IOException, InterruptedException {
        if (useDocker) {
            if (runInDockerCluster) {

                HashMap<String, Integer> dockerNodes = getDockerNodes();
                String dockerTar = LUtil.class.getClassLoader().getResource("docker/loadTest.tar").toString()
                        .substring(5);
                ExecutorService exec = Executors.newFixedThreadPool(dockerNodes.size());

                dockerError = false;
                doneDockers = 0;

                for (Entry<String, Integer> entry : dockerNodes.entrySet()) {
                    exec.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                String url = entry.getKey() + "/images/vauvenal5/loadtest";
                                URL obj = new URL(url);
                                HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                                con.setRequestMethod("DELETE");
                                con.setRequestProperty("force", "true");
                                int responseCode = con.getResponseCode();
                                con.disconnect();

                                url = entry.getKey()
                                        + "/build?t=vauvenal5/loadtest&dockerfile=./loadTest/Dockerfile";
                                obj = new URL(url);
                                con = (HttpURLConnection) obj.openConnection();
                                con.setRequestMethod("POST");
                                con.setRequestProperty("Content-type", "application/tar");
                                con.setDoOutput(true);
                                File file = new File(dockerTar);
                                FileInputStream fileStr = new FileInputStream(file);
                                byte[] b = new byte[(int) file.length()];
                                fileStr.read(b);
                                con.getOutputStream().write(b);
                                con.getOutputStream().flush();
                                con.getOutputStream().close();

                                responseCode = con.getResponseCode();

                                if (responseCode != 200) {
                                    dockerError = true;
                                }

                                String msg = "";

                                do {
                                    Thread.sleep(5000);
                                    msg = "";
                                    url = entry.getKey() + "/images/json";
                                    obj = new URL(url);
                                    HttpURLConnection con2 = (HttpURLConnection) obj.openConnection();
                                    con2.setRequestMethod("GET");
                                    responseCode = con2.getResponseCode();

                                    BufferedReader in = new BufferedReader(
                                            new InputStreamReader(con2.getInputStream()));
                                    String line = null;

                                    while ((line = in.readLine()) != null) {
                                        msg += line;
                                    }

                                    con2.disconnect();
                                } while (!msg.contains("vauvenal5/loadtest"));

                                con.disconnect();
                                doneDockers++;
                            } catch (MalformedURLException ex) {
                                dockerError = true;
                            } catch (FileNotFoundException ex) {
                                dockerError = true;
                            } catch (IOException ex) {
                                dockerError = true;
                            } catch (InterruptedException ex) {
                                dockerError = true;
                            }
                        }
                    });
                }

                while (doneDockers < dockerNodes.size()) {
                    Thread.sleep(5000);
                }

                return !dockerError;
            }

            //get the path and substring the 'file:' from the URI
            String dockerfile = LUtil.class.getClassLoader().getResource("docker/loadTest").toString().substring(5);

            ProcessBuilder processBuilder = new ProcessBuilder("docker", "rmi", "-f", "vauvenal5/loadtest");
            processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            Process docker = processBuilder.start();

            docker.waitFor();

            processBuilder = new ProcessBuilder("docker", "build", "-t", "vauvenal5/loadtest", dockerfile);
            processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            Process proc = processBuilder.start();
            return proc.waitFor() == 0;
        }
        return true;
    }

    private Entry<String, Integer> getLowestDockerHost() {
        HashMap<String, Integer> dockerNodes = getDockerNodes();
        Entry<String, Integer> lowest = null;

        if (this.startedClusterContainer.size() < dockerNodes.size()) {
            for (Entry<String, Integer> entry : dockerNodes.entrySet()) {
                if (!this.startedClusterContainer.containsKey(entry.getKey())) {
                    return new AbstractMap.SimpleEntry<>(entry.getKey(), 0);
                }
            }
        }

        for (Entry<String, Integer> entry : startedClusterContainer.entrySet()) {
            if (entry.getValue() < dockerNodes.get(entry.getKey())) {
                if (lowest == null) {
                    lowest = entry;
                } else {
                    if (lowest.getValue() > entry.getValue()) {
                        lowest = entry;
                    }
                }
            }
        }

        return lowest;
    }

    public boolean startDockerSlave(LoadTestConfigModel ltModel) throws InterruptedException, IOException {

        String fileCount = String.valueOf(ltModel.getFileCount());

        if (runInDockerCluster) {
            HashMap<String, Integer> dockerNodes = getDockerNodes();

            Entry<String, Integer> entry = this.getLowestDockerHost();

            startedClusterContainer.put(entry.getKey(), entry.getValue() + 1);

            String dockerCommand = "{" + "\"Hostname\":\"\"," + "\"User\":\"\","
                    + "\"Entrypoint\":[\"/bin/bash\",\"/pieShare/pieShareAppIntegrationTests/src/test/resources/docker/internal.sh\"],"
                    + "\"Cmd\":[\"slave\",\"" + fileCount.toString() + "\"]," + "\"Memory\":0,"
                    + "\"MemorySwap\":0," + "\"AttachStdin\":false," + "\"AttachStdout\":false,"
                    + "\"AttachStderr\":false," + "\"PortSpecs\":null," + "\"Privileged\": false,"
                    + "\"Tty\":false," + "\"OpenStdin\":false," + "\"StdinOnce\":false," + "\"Env\":null,"
                    + "\"Dns\":null," + "\"Image\":\"vauvenal5/loadtest\"," + "\"Volumes\":{},"
                    + "\"VolumesFrom\":\"\"," + "\"WorkingDir\":\"\"}";

            String url = entry.getKey() + "/containers/create";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-type", "application/json");
            con.setDoOutput(true);
            con.getOutputStream().write(dockerCommand.getBytes());
            con.getOutputStream().flush();
            con.getOutputStream().close();

            int responseCode = con.getResponseCode();

            if (responseCode != 201) {
                return false;
            }

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            String msg = "";

            while ((line = in.readLine()) != null) {
                msg += line;
            }

            ObjectMapper mapper = new ObjectMapper();
            JsonNode node = mapper.readTree(msg);

            String containerId = node.get("Id").asText();
            con.disconnect();

            url = entry.getKey() + "/containers/" + containerId + "/start";
            obj = new URL(url);
            con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-type", "application/json");

            responseCode = con.getResponseCode();

            if (responseCode != 204) {
                return false;
            }

            if (!this.runningContainers.containsKey(entry.getKey())) {
                this.runningContainers.put(entry.getKey(), new ArrayList<>());
            }

            this.runningContainers.get(entry.getKey()).add(containerId);

            return true;
        }

        ProcessBuilder processBuilder = new ProcessBuilder("docker", "run", "vauvenal5/loadtest", "slave",
                fileCount);
        Process proc = processBuilder.start();
        this.slaves.add(proc);
        return true;
    }
}