jmeter源码解析

生成/解析jmx文件

package com.haoke.ratel.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.haoke.ratel.constant.JmxMemberType;
import com.haoke.ratel.dto.script.*;
import com.haoke.ratel.entity.StScript;
import com.haoke.ratel.utils.ResponseModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.CSVDataSet;
import org.apache.jmeter.config.gui.ArgumentsPanel;
import org.apache.jmeter.control.Controller;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.apache.jmeter.protocol.http.gui.CookiePanel;
import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel;
import org.apache.jmeter.protocol.http.gui.HeaderPanel;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
import org.apache.jmeter.testelement.AbstractTestElement;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jmeter.testelement.property.TestElementProperty;
import org.apache.jmeter.threads.PostThreadGroup;
import org.apache.jmeter.threads.SetupThreadGroup;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.threads.gui.PostThreadGroupGui;
import org.apache.jmeter.threads.gui.SetupThreadGroupGui;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.ListedHashTree;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;


@Service
@Slf4j
public class ConfigScriptService {

    @Value("${data.jmeter-home}")
    private String jmeterHome;

    @Value("${data.jmx-path}")
    private String jmxPath;

    @PostConstruct
    private void init(){
        // 设置bin路径
        JMeterUtils.setJMeterHome(jmeterHome);
        // 加载jmeter.properties配置文件
        JMeterUtils.loadJMeterProperties(jmeterHome + File.separator + "bin"
                + File.separator + "jmeter.properties");
        // 设置语言
        JMeterUtils.setLocale(Locale.CHINESE);
    }

    /**
     * 生成jmx文件
     * @param jmxMemberList
     * @return
     */
    public ResponseModel<String> createJmx(List<JmxMember> jmxMemberList){
        try {
            if (CollectionUtils.isEmpty(jmxMemberList)){
                return ResponseModel.error("请录入构建压测的数据");
            }
            JmxMember jmxMember = jmxMemberList.get(0);
            ResponseModel resp =  iterateSonNode(jmxMember);
            if(!resp.isOk()){
                return resp;
            }
            ListedHashTree hashTreeTestPlan = (ListedHashTree) resp.getData();
            //可以将生成的hashTree保存成一个jmx文件  与Jmeter自己生成的做对比
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            String filePath = jmxPath + File.separator + uuid + ".jmx";
            SaveService.saveTree(hashTreeTestPlan, new FileOutputStream(filePath));
            return ResponseModel.ok(filePath);
        }catch (Exception e){
            log.error("生成脚本异常",e);
            return ResponseModel.error("生成脚本异常:"+e.getMessage());
        }
    }

    /**
     * 解析jmx文件
     * @param stScript
     * @return
     */
    public ResponseModel analysisJmx(StScript stScript){
        try{
            // 将xml内容写入临时文件中
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            File jmxFile = new File(jmxPath + File.separator + uuid + ".jmx");
            FileOutputStream outStream = new FileOutputStream(jmxFile);
            outStream.write(stScript.getJmxFile().getBytes());
            outStream.close();
            // 解析jmx文件并生成List<JmxMember>
            ListedHashTree hashTree = (ListedHashTree) SaveService.loadTree(new File(jmxPath
                    + File.separator + uuid + ".jmx"));
            int i =0;
            ResponseModel<List<JmxMember>> responseModel = iterateHashTree(hashTree, i);
            if(!responseModel.isOk()){
                return responseModel;
            }
            ConfigJmxDto configJmxDto = new ConfigJmxDto();
            configJmxDto.setJmxMember(responseModel.getData());
            StScript script = new StScript();
            script.setId(stScript.getId());
            script.setName(stScript.getName());
            script.setDescription(stScript.getDescription());
            script.setScriptFileName(stScript.getScriptFileName());
            script.setIsLocked(stScript.getIsLocked());
            script.setOwner(stScript.getOwner());
            configJmxDto.setScript(script);
            return ResponseModel.ok(configJmxDto);
        }catch (Exception e){
            log.error("解析jmx文件异常", e);
            return ResponseModel.error("解析jmx文件异常:" + e.getMessage());
        }
    }

    private ResponseModel<List<JmxMember>> iterateHashTree(ListedHashTree hashTree, Integer i){
        try{
            List<JmxMember> jmxMember = new ArrayList();
            for(Object key : hashTree.keySet()){
                i++;
                JmxMember member = new JmxMember();
                AbstractTestElement abstractTestElement = (AbstractTestElement) key;
                member.setName(abstractTestElement.getName());
                String guiClass = abstractTestElement.getPropertyAsString("TestElement.gui_class");
                JmxMemberType jmxMemberType ;
                if("org.apache.jmeter.control.gui.HTTPArgumentsPanel".equalsIgnoreCase(guiClass)
                        || "org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel".equalsIgnoreCase(guiClass) ){
                    jmxMemberType = JmxMemberType.HTTPArguments;
                }else {
                    jmxMemberType = getType(key);
                }
                member.setType(jmxMemberType);
                ResponseModel rm = getMemberValue(jmxMemberType, key);
                if(!rm.isOk()){
                    return rm;
                }
                member.setValue(rm.getData());
                member.setId(i);
                if(!hashTree.get(key).isEmpty()) {
                    ResponseModel<List<JmxMember>> responseModel = iterateHashTree((ListedHashTree) hashTree.get(key), i);
                    if (!responseModel.isOk()) {
                        return responseModel;
                    }
                    member.setId(i++);
                    member.setSons(responseModel.getData());
                }
                jmxMember.add(member);
            }
            return ResponseModel.ok(jmxMember);
        }catch (Exception e){
            log.error("遍历hashTree方法异常", e);
            return ResponseModel.error("遍历hashTree方法异常:" + e.getMessage());
        }
    }

    /**
     *  解析节点类型
     */
    private JmxMemberType getType(Object key){
        if(key instanceof TestPlan){
            return JmxMemberType.TestPlan;
        }else if(key instanceof ThreadGroup){
            return JmxMemberType.ThreadGroup;
        }else if(key instanceof HTTPSamplerProxy){
            return JmxMemberType.HTTPSampler;
        }else if(key instanceof HeaderManager){
            return JmxMemberType.HeaderManager;
        }else if(key instanceof CookieManager){
            return JmxMemberType.CookieManager;
        }else if(key instanceof CSVDataSet){
            return JmxMemberType.CSVDataSet;
        }else if(key instanceof Arguments){
            return JmxMemberType.Arguments;
        }else {
            return null;
        }
    }

    private ResponseModel getMemberValue(JmxMemberType jmxMemberType, Object key){
        switch(jmxMemberType){
            case TestPlan:
                return analysisTestPlan((TestPlan) key);
            case ThreadGroup:
            case SetUpThreadGroup:
            case PostThreadGroup:
                return analysisThreadGroup(jmxMemberType,  key);
            case HTTPSampler:
                return analysisHttpSamplerProxy((HTTPSamplerProxy) key);
            case CSVDataSet:
                return analysisCSVDataSet((CSVDataSet) key);
            case Arguments:
                return analysisArgumentsPanel((Arguments) key);
            case HTTPArguments:
                return analysisHTTPArgumentsPanel((Arguments) key);
            case HeaderManager:
                return analysisHeaderManager((HeaderManager) key);
            case CookieManager:
                return analysisCookieManager((CookieManager) key);
            default:
                return ResponseModel.error("解析类型不存在");
        }
    }



    private ResponseModel iterateSonNode(JmxMember jmxMember){
        ResponseModel responseModel = createNode(jmxMember);
        if (!responseModel.isOk()){
            return responseModel;
        }
        ListedHashTree tree = new ListedHashTree();
        Object node = responseModel.getData();
        // 递归
        if (!CollectionUtils.isEmpty(jmxMember.getSons())){
            ListedHashTree sonTree = new ListedHashTree();
            for (JmxMember son : jmxMember.getSons()) {
                ResponseModel sonResponse = iterateSonNode(son);
                if (!sonResponse.isOk() && sonResponse.getCode() != 1) {
                    return sonResponse;
                }
                Object sonObj = sonResponse.getData();
                if (sonResponse.getCode() != 1){
                    //返回为ListedHashTree,遍历key,value,添加进入sontree
                    ListedHashTree retTree = (ListedHashTree) sonObj;
                     for (Object key : retTree.keySet()){
                         sonTree.add(key, retTree.get(key));
                     }
                }else {
                    //叶子节点添加到list
                    sonTree.add(sonObj);
                }
            }
            tree.add(node, sonTree);
            return ResponseModel.ok(tree);
        }else {
            // 叶子节点直接返回
            return ResponseModel.ok(1 ,node);
        }
    }

    /**
     * 选择节点
     * @param jmxMember
     * @return
     */
    private ResponseModel createNode(JmxMember jmxMember){
        String args = JSON.toJSONString(jmxMember.getValue());
        switch (jmxMember.getType()){
            case TestPlan:
                return createTestPlan(args);
            case ThreadGroup:
            case SetUpThreadGroup:
            case PostThreadGroup:
                return createThreadGroup(args);
            case HTTPSampler:
                return createHttpSamplerProxy(args);
            case HeaderManager:
                return createHeaderManager(args);
            case CookieManager:
                return createCookieManager(args);
            case CSVDataSet:
                return createCsvDataSet(args);
            case Arguments:
                return createArgumentsPanel(args);
            case HTTPArguments:
                return createHTTPArgumentsPanel(args);
            default:
                return ResponseModel.error("节点类型不存在");
        }
    }

    /**
     * 生成TestPlan
     * @param args
     * @return
     */
    private ResponseModel createTestPlan(String args){
        try {
            TestPlan testPlan = JSON.parseObject(args, TestPlan.class);
            testPlan.setProperty("TestPlan.serialize_threadgroups", false);
            Arguments arguments = testPlan.getArguments();
            arguments.setName("User Defined Variables");
            arguments.setEnabled(true);
            arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
            arguments.setProperty(TestElement.GUI_CLASS, ArgumentsPanel.class.getName());
            testPlan.setUserDefinedVariables(arguments);
            testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
            testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
            return ResponseModel.ok(testPlan);
        }catch (Exception e){
            log.error("生成测试计划的方法异常", e);
            return ResponseModel.error("生成测试计划的方法异常"+e.getMessage());
        }
    }

    /**
     * 生成线程组
     * @param args
     * @return
     */
    private ResponseModel createThreadGroup(String args){
        try {
            JSONObject jsonObject = JSONObject.parseObject(args);
            String type = jsonObject.getString("type");
            if("ThreadGroup".equalsIgnoreCase(type.trim())){
                ThreadGroup threadGroup = JSON.parseObject(args, ThreadGroup.class);
                Controller controller = threadGroup.getSamplerController();
                controller.setName("Loop Controller");
                controller.setEnabled(true);
                controller.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                controller.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                threadGroup.setProperty("ThreadGroup.on_sample_error", jsonObject.getString("onSampleError"));
                threadGroup.setProperty("ThreadGroup.delayedStart", jsonObject.getString("delayedStartup"));
                threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
                threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
                return ResponseModel.ok(threadGroup);
            }else if ("SetupThreadGroup".equalsIgnoreCase(type.trim())){
                SetupThreadGroup setupThreadGroup = JSON.parseObject(args, SetupThreadGroup.class);
                Controller controller = setupThreadGroup.getSamplerController();
                controller.setName("Loop Controller");
                controller.setEnabled(true);
                controller.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                controller.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                setupThreadGroup.setProperty("ThreadGroup.on_sample_error", jsonObject.getString("onSampleError"));
                setupThreadGroup.setProperty(TestElement.TEST_CLASS, SetupThreadGroup.class.getName());
                setupThreadGroup.setProperty(TestElement.GUI_CLASS, SetupThreadGroupGui.class.getName());
                return ResponseModel.ok(setupThreadGroup);
            }else if("PostThreadGroup".equalsIgnoreCase(type.trim())){
                PostThreadGroup postThreadGroup = JSON.parseObject(args, PostThreadGroup.class);
                Controller controller = postThreadGroup.getSamplerController();
                controller.setName("Loop Controller");
                controller.setEnabled(true);
                controller.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                controller.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                postThreadGroup.setProperty("ThreadGroup.on_sample_error", jsonObject.getString("onSampleError"));
                postThreadGroup.setProperty(TestElement.TEST_CLASS, PostThreadGroup.class.getName());
                postThreadGroup.setProperty(TestElement.GUI_CLASS, PostThreadGroupGui.class.getName());
                return ResponseModel.ok(postThreadGroup);
            }else {
                return ResponseModel.error("线程组类型不存在");
            }
        }catch (Exception e){
            log.error("线程组格式错误", e);
            return ResponseModel.error("线程组格式错误"+e.getMessage());
        }
    }

    /**
     * 生成http请求
     * @param args
     * @return
     */
    private ResponseModel createHttpSamplerProxy(String args){
        try {
            HTTPSamplerProxy httpSamplerProxy = JSON.parseObject(args, HTTPSamplerProxy.class);
            if (StringUtils.isBlank(httpSamplerProxy.getPath())) {
                return ResponseModel.error("路径不能为空");
            }
            ResponseModel responseModel = createHTTPArgumentsPanel(JSONObject.parseObject(args)
                    .getString("arguments"));
            if (!responseModel.isOk()) {
                return responseModel;
            }
            httpSamplerProxy.setArguments((Arguments) responseModel.getData());
            httpSamplerProxy.setProperty("HTTPSampler.embedded_url_re", "");
            httpSamplerProxy.setProperty("HTTPSampler.connect_timeout", "");
            httpSamplerProxy.setProperty("HTTPSampler.response_timeout", "");
            httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
            httpSamplerProxy.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
            return ResponseModel.ok(httpSamplerProxy);
        }catch (Exception e){
            log.error("生成http的方法异常", e);
            return ResponseModel.error("生成http的方法异常:"+e.getMessage());
        }
    }

    /**
     * 生成csv节点
     * @param args
     * @return
     */
    private ResponseModel createCsvDataSet(String args){
        try {
            CSVDataSet csvDataSet = JSON.parseObject(args, CSVDataSet.class);
            if(StringUtils.isBlank(csvDataSet.getFilename())){
                return ResponseModel.error("必须上传文件路径");
            }
            if(StringUtils.isBlank(csvDataSet.getVariableNames())){
                return ResponseModel.error("必须上传变量名");
            }
            JSONObject jsonObject = JSONObject.parseObject(args);
            csvDataSet.setProperty("filename", jsonObject.getString("filename"));
            csvDataSet.setProperty("fileEncoding", jsonObject.getString("fileEncoding"));
            csvDataSet.setProperty("variableNames", jsonObject.getString("variableNames"));
            csvDataSet.setProperty("ignoreFirstLine", jsonObject.getBooleanValue("ignoreFirstLine"));
            csvDataSet.setProperty("delimiter",jsonObject.getString("delimiter"));
            csvDataSet.setProperty("quotedData", jsonObject.getBooleanValue("quoted"));
            csvDataSet.setProperty("recycle", jsonObject.getBooleanValue("recycle"));
            csvDataSet.setProperty("stopThread", jsonObject.getBooleanValue("stopThread"));
            csvDataSet.setProperty("shareMode", jsonObject.getString("shareMode"));
            csvDataSet.setProperty(TestElement.TEST_CLASS, CSVDataSet.class.getName());
            csvDataSet.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());
            return ResponseModel.ok(csvDataSet);
        }catch (Exception e){
            log.error("生成csv的方法异常", e);
            return ResponseModel.error("生成csv的方法异常:"+e.getMessage());
        }
    }

    /**
     * 生成header
     * @param args
     * @return
     */
    private ResponseModel createHeaderManager(String args){
        try{
            HeaderManager headerManager = JSON.parseObject(args, HeaderManager.class);
            JSONArray jsonArray = JSONObject.parseObject(args).getJSONArray("headers");
            ArrayList<TestElementProperty> testElementProperties = new ArrayList();
            for(int i=0;i<jsonArray.size();i++) {
                JSONObject job = jsonArray.getJSONObject(i);
                Header header = new Header();
                header.setProperty(new StringProperty("Header.name", job.getString("name")));
                header.setProperty(new StringProperty("Header.value", job.getString("value")));
                testElementProperties.add(new TestElementProperty(job.getString("name"), header));
            }
            headerManager.setProperty(new CollectionProperty("HeaderManager.headers", testElementProperties));
            headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
            headerManager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
            return ResponseModel.ok(headerManager);
        }catch (Exception e){
            log.error("生成header的方法异常", e);
            return ResponseModel.error("生成header的方法异常:"+e.getMessage());
        }
    }

    /**
     * 生成cookies
     * @param args
     * @return
     */
    private ResponseModel createCookieManager(String args){
        try {
            JSONObject jsonObject = JSONObject.parseObject(args);
            JSONArray cookies = jsonObject.getJSONArray("cookies");
            ArrayList<TestElementProperty> testElementProperties = new ArrayList();
            for (int i = 0; i < cookies.size(); i++) {
                JSONObject job = cookies.getJSONObject(i);
                Cookie cookie = new Cookie();
                cookie.setName(job.getString("name"));
                cookie.setValue(job.getString("value"));
                cookie.setDomain(job.getString("domain"));
                cookie.setPath(job.getString("path"));
                cookie.setSecure(job.getBooleanValue("secure"));
                testElementProperties.add(new TestElementProperty(job.getString("name"), cookie));
            }
            CookieManager cookieManager = JSON.parseObject(args, CookieManager.class);
            cookieManager.setProperty(new CollectionProperty("CookieManager.cookies", testElementProperties));
            cookieManager.setProperty("CookieManager.controlledByThreadGroup", jsonObject.getBooleanValue("controlledByThreadGroup"));
            cookieManager.setProperty(TestElement.TEST_CLASS, CookieManager.class.getName());
            cookieManager.setProperty(TestElement.GUI_CLASS, CookiePanel.class.getName());
            return ResponseModel.ok(cookieManager);
        }catch (Exception e){
            log.error("生成cookies的方法异常", e);
            return ResponseModel.error("生成cookies的方法异常:"+e.getMessage());
        }
    }

    /**
     * 生成HTTPArgumentsPanel
     * @param args
     * @return
     */
    private ResponseModel createHTTPArgumentsPanel(String args){
        try {
            Arguments arguments = new Arguments();
            JSONArray httpArguments = JSONObject.parseObject(args).getJSONArray("arguments");
            ArrayList<TestElementProperty> testElementProperties = new ArrayList();
            for (int i = 0; i < httpArguments.size(); i++) {
                JSONObject job = httpArguments.getJSONObject(i);
                HTTPArgument httpArgument = new HTTPArgument();
                httpArgument.setAlwaysEncoded(job.getBooleanValue("alwaysEncoded"));
                httpArgument.setUseEquals(job.getBooleanValue("useEquals"));
                httpArgument.setProperty("HTTPArgument.content_type",job.getBooleanValue("contentType"));
                if(StringUtils.isNotBlank(job.getString("name"))) {
                    httpArgument.setName(job.getString("name"));
                }
                if(StringUtils.isNotBlank(job.getString("value"))) {
                    httpArgument.setValue(job.getString("value"));
                }
                testElementProperties.add(new TestElementProperty(job.getString("name"), httpArgument));
            }
            arguments.setProperty(new CollectionProperty("Arguments.arguments", testElementProperties));
            arguments.setName("User Defined Variables");
            arguments.setEnabled(true);
            arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
            arguments.setProperty(TestElement.GUI_CLASS, HTTPArgumentsPanel.class.getName());
            return ResponseModel.ok(arguments);
        }catch (Exception e){
            log.error("生成HTTPArgumentsPanel的方法异常", e);
            return ResponseModel.error("生成HTTPArgumentsPanel的方法异常:"+e.getMessage());
        }
    }

    /**
     * 生成ArgumentsPanel
     * @param args
     * @return
     */
    private ResponseModel createArgumentsPanel(String args){
        try {
            Arguments arguments = JSON.parseObject(args, Arguments.class);
            arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
            arguments.setProperty(TestElement.GUI_CLASS, ArgumentsPanel.class.getName());
            return ResponseModel.ok(arguments);
        }catch (Exception e){
            log.error("生成ArgumentsPanel的方法异常", e);
            return ResponseModel.error("生成ArgumentsPanel的方法异常:"+e.getMessage());
        }
    }

    /**
     * 解析TestPlan
     * @param testPlan
     * @return
     */
    private ResponseModel analysisTestPlan(TestPlan testPlan){
        try {
            Map<String, Object> map = new HashMap();
            map.put("name", testPlan.getPropertyAsString("TestElement.name"));
            map.put("enabled", testPlan.getPropertyAsBoolean("TestElement.enabled"));
            map.put("comment", testPlan.getPropertyAsString("TestPlan.comments"));
            map.put("functionalMode", testPlan.getPropertyAsBoolean("TestPlan.functional_mode"));
            map.put("tearDownOnShutdown", testPlan.getPropertyAsBoolean("TestPlan.tearDown_on_shutdown"));
            map.put("testPlanClasspath", testPlan.getPropertyAsString("TestPlan.user_define_classpath"));
            TestElementProperty testElementProperty = (TestElementProperty)testPlan.getUserDefinedVariablesAsProperty();
            Arguments args = (Arguments)testElementProperty.getElement();
            ArrayList arrayList = (ArrayList)args.getArguments().getObjectValue();
            List s = new ArrayList();
            if(!CollectionUtils.isEmpty(arrayList)){
                for (Object object : arrayList){
                    TestElementProperty te = (TestElementProperty)object;
                    Argument arg = (Argument)te.getElement();
                    Map<String, String> argument = new HashMap();
                    argument.put("name", arg.getName());
                    argument.put("value", arg.getValue());
                    argument.put("metadata", arg.getMetaData());
                    s.add(argument);
                }
            }
            Map<String, Object> arguments = new HashMap();
            arguments.put("arguments", s);
            map.put("userDefinedVariables",arguments);
            return ResponseModel.ok(map);
        }catch (Exception e){
            log.error("解析testPlan异常", e);
            return ResponseModel.error("解析testPlan异常:"+e.getMessage());
        }
    }

    /**
     * 解析线程组
     * @param jmxMemberType
     * @param key
     * @return
     */
    private ResponseModel analysisThreadGroup(JmxMemberType jmxMemberType, Object key){
        try{

            ThreadGroupDto threadGroupDto = new ThreadGroupDto();
            BeanUtils.copyProperties(key, threadGroupDto);
            ThreadGroup threadGroup = (ThreadGroup)key;
            if(jmxMemberType.equals(JmxMemberType.SetUpThreadGroup)){
                threadGroup = (SetupThreadGroup) key;
            }else if(jmxMemberType.equals(JmxMemberType.PostThreadGroup)){
                threadGroup = (PostThreadGroup) key;
            }
            threadGroupDto.setType(jmxMemberType.getValue());
            threadGroupDto.setOnSampleError(threadGroup.getPropertyAsString("ThreadGroup.on_sample_error"));
            threadGroupDto.setNumThreads(threadGroup.getPropertyAsInt("ThreadGroup.num_threads"));
            if(jmxMemberType.equals(JmxMemberType.ThreadGroup)) {
                threadGroupDto.setDelayedStartup(threadGroup.getPropertyAsBoolean("ThreadGroup.delayedStart"));
            }
            threadGroupDto.setIsSameUserOnNextIteration(threadGroup.getPropertyAsBoolean("ThreadGroup.same_user_on_next_iteration"));
            threadGroupDto.setDuration(threadGroup.getPropertyAsInt("ThreadGroup.duration"));
            threadGroupDto.setDelay(threadGroup.getPropertyAsInt("ThreadGroup.delay"));
            HashMap<String, Object> hashMap = new HashMap();
            LoopController controller = (LoopController)threadGroup.getSamplerController();
            hashMap.put("loops", controller.getLoops());
            hashMap.put("continueForever", controller.getPropertyAsBoolean("LoopController.continue_forever"));
            threadGroupDto.setSamplerController(hashMap);
            return ResponseModel.ok(threadGroupDto);
        }catch (Exception e){
            log.error("解析线程组方法异常", e);
            return ResponseModel.error("解析线程组方法异常" + e.getMessage());
        }
    }

    /**
     * 解析http
     * @param httpSamplerProxy
     * @return
     */
    private ResponseModel analysisHttpSamplerProxy(HTTPSamplerProxy httpSamplerProxy){
        try {
            HttpSamplerDto httpSamplerDto = new HttpSamplerDto();
            BeanUtils.copyProperties(httpSamplerProxy, httpSamplerDto);
            httpSamplerDto.setUseKeepalive(httpSamplerProxy.getUseKeepAlive());
            List list = new ArrayList();
            Arguments arguments = httpSamplerProxy.getArguments();
            for(Object object : arguments){
                TestElementProperty te = (TestElementProperty)object;
                HTTPArgument arg = (HTTPArgument) te.getElement();
                HashMap<String, Object> hashMap = new HashMap();
                hashMap.put("name",arg.getName());
                hashMap.put("value",arg.getValue());
                hashMap.put("alwaysEncode", arg.getPropertyAsBoolean("alwaysEncoded"));
                hashMap.put("contentType", arg.getPropertyAsString("HTTPArgument.content_type"));
                hashMap.put("useEquals", arg.getPropertyAsBoolean("useEquals"));
                list.add(hashMap);
            }
            HashMap<String, Object> argument = new HashMap();
            argument.put("arguments", list);
            httpSamplerDto.setArguments(argument);
            return ResponseModel.ok(httpSamplerDto);
        }catch (Exception e){
            log.error("解析http异常", e);
            return ResponseModel.error("解析http异常:" + e.getMessage());
        }
    }

    /**
     * 解析csv
     * @param csvDataSet
     * @return
     */
    private ResponseModel analysisCSVDataSet(CSVDataSet csvDataSet){
        try {
            CsvDataDto csvDataDto = new CsvDataDto();
            BeanUtils.copyProperties(csvDataSet, csvDataDto);
            csvDataDto.setDelimiter(csvDataSet.getPropertyAsString("delimiter"));
            csvDataDto.setFilename(csvDataSet.getPropertyAsString("filename"));
            csvDataDto.setFileEncoding(csvDataSet.getPropertyAsString("fileEncoding"));
            csvDataDto.setQuoted(csvDataSet.getPropertyAsBoolean("quotedData"));
            csvDataDto.setVariableNames(csvDataSet.getPropertyAsString("variableNames"));
            csvDataDto.setShareMode(csvDataSet.getPropertyAsString("shareMode"));
            return ResponseModel.ok(csvDataDto);
        }catch (Exception e){
            log.error("解析csv异常", e);
            return ResponseModel.error("解析csv异常:" + e.getMessage());
        }
    }

    /**
     * 解析http请求头
     * @param headerManager
     * @return
     */
    private ResponseModel analysisHeaderManager(HeaderManager headerManager){
        try {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("name", headerManager.getName());
            hashMap.put("comment", headerManager.getComment());
            hashMap.put("enabled", headerManager.getPropertyAsBoolean("TestElement.enabled"));
            List list = new ArrayList();
            CollectionProperty collectionProperty = headerManager.getHeaders();
            ArrayList arrayList =  (ArrayList) collectionProperty.getObjectValue();
            for(Object object : arrayList){
                TestElementProperty te = (TestElementProperty)object;
                Header arg = (Header) te.getElement();
                Map<String, Object> argument = new HashMap();
                argument.put("name", arg.getName());
                argument.put("value", arg.getValue());
                list.add(argument);
            }
            hashMap.put("headers", list);
            return ResponseModel.ok(hashMap);
        }catch (Exception e){
            log.error("解析http请求头异常", e);
            return ResponseModel.error("解析http请求头异常:" + e.getMessage());
        }
    }

    /**
     * 解析cookies
     * @param cookieManager
     * @return
     */
    private ResponseModel analysisCookieManager(CookieManager cookieManager){
        try {
            HashMap<String, Object> cookies = new HashMap();
            cookies.put("name", cookieManager.getName());
            cookies.put("comment", cookieManager.getComment());
            cookies.put("enabled", cookieManager.getPropertyAsBoolean("TestElement.enabled"));
            cookies.put("cookiePolicy", cookieManager.getPolicy());
            cookies.put("clearEachIteration", cookieManager.getClearEachIteration());
            cookies.put("controlledByThreadGroup",
                    cookieManager.getPropertyAsBoolean("CookieManager.controlledByThreadGroup"));
            List list = new ArrayList();
            CollectionProperty collectionProperty = cookieManager.getCookies();
            ArrayList arrayList =  (ArrayList) collectionProperty.getObjectValue();
            for(Object object : arrayList){
                TestElementProperty te = (TestElementProperty)object;
                Cookie arg = (Cookie) te.getElement();
                Map<String, Object> argument = new HashMap();
                argument.put("name", arg.getName());
                argument.put("value", arg.getValue());
                argument.put("domain", arg.getDomain());
                argument.put("path", arg.getPath());
                argument.put("secure", arg.getSecure());
                list.add(argument);
            }
            cookies.put("cookies", list);
            return ResponseModel.ok(cookies);
        }catch (Exception e){
            log.error("解析Cookie请求头异常", e);
            return ResponseModel.error("解析Cookie请求头异常:" + e.getMessage());
        }
    }

    /**
     * 解析http请求参数
     * @param arguments
     * @return
     */
    private ResponseModel analysisHTTPArgumentsPanel(Arguments arguments){
        try {
            List list = new ArrayList();
            CollectionProperty collectionProperty = arguments.getArguments();
            ArrayList arrayList =  (ArrayList) collectionProperty.getObjectValue();
            for(Object object : arrayList){
                TestElementProperty te = (TestElementProperty)object;
                HTTPArgument arg = (HTTPArgument) te.getElement();
                Map<String, Object> argument = new HashMap();
                argument.put("name", arg.getName());
                argument.put("value", arg.getValue());
                argument.put("comment", arg.getComment());
                argument.put("alwaysEncode", arg.getPropertyAsBoolean("alwaysEncoded"));
                argument.put("contentType", arg.getPropertyAsString("HTTPArgument.content_type"));
                argument.put("useEquals", arg.getPropertyAsBoolean("useEquals"));
                list.add(argument);
            }
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("arguments", list);
            return ResponseModel.ok(hashMap);
        }catch (Exception e){
            log.error("解析http请求参数异常", e);
            return ResponseModel.error("解析http请求参数异常:" + e.getMessage());
        }
    }

    /**
     * 解析用户自定义变量
     * @param arguments
     * @return
     */
    private ResponseModel analysisArgumentsPanel(Arguments arguments){
        try {
            List list = new ArrayList();
            CollectionProperty collectionProperty = arguments.getArguments();
            ArrayList arrayList =  (ArrayList) collectionProperty.getObjectValue();
            for(Object object : arrayList){
                TestElementProperty te = (TestElementProperty)object;
                Argument arg = (Argument) te.getElement();
                Map<String, Object> argument = new HashMap();
                argument.put("name", arg.getName());
                argument.put("value", arg.getValue());
                argument.put("description", arg.getComment());
                argument.put("metadata", arg.getMetaData());
                list.add(argument);
            }
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("arguments", list);
            hashMap.put("name", arguments.getName());
            hashMap.put("comment", arguments.getComment());
            hashMap.put("enabled", arguments.getPropertyAsBoolean("TestElement.enabled"));
            return ResponseModel.ok(hashMap);
        }catch (Exception e){
            log.error("解析用户自定义变量异常", e);
            return ResponseModel.error("解析用户自定义变量异常:" + e.getMessage());
        }
    }
}

参数格式:

{
	"script": {
		"name": "压测脚本名称",
		"description": "压测脚本描述",
		"id": 2,
		"scriptFileName": "JMX文件名",
		"isLocked": true,
		"owner": "操作人,以逗号分隔"
	},
	"jmxMember": [{
		"type": "TestPlan",
		"name": "测试计划",
		"id": 1,
		"value": {
			"comment": "计划描述",
			"name": "计划名称",
			"enabled": true,
			"functionalMode": true,
			"tearDownOnShutdown": true,
			"testPlanClasspath": "test.jar",
			"userDefinedVariables": {
				"arguments": [{
					"name": "asd",
					"value": "sd",
					"metadata": "="
				}, {
					"name": "sda",
					"value": "sdas",
					"metadata": "="
				}]
			}
		},
		"sons": [{
			"type": "ThreadGroup",
			"name": "线程组名称",
			"id": 2,
			"value": {
				"type": "threadGroup",
				"comment": "线程组描述",
				"name": "线程组名称",
				"enabled": true,
				"onSampleError": "continue",
				"numThreads": 2000,
				"delayedStartup": true,
				"rampUp": 5,
				"samplerController": {
					"continueForever": false,
					"loops": 2
				},
				"isSameUserOnNextIteration": true,
				"scheduler": true,
				"duration": 12,
				"delay": 20
			},
			"sons": [{
					"type": "HttpSamplerProxy",
					"name": "http请求",
					"id": 3,
					"value": {
						"comment": "请求描述",
						"name": "请求名称",
						"enabled": true,
						"arguments": {
							"arguments": [{
								"name": "key",
								"value": "value",
								"alwaysEncode": true,
								"contentType": "text/plain",
								"useEquals": true
							}]
						},
						"domain": "www.baidu.com",
						"port": 8080,
						"protocol": "http",
						"contentEncoding": "utf-8",
						"path": "/index",
						"method": "GET",
						"followRedirects": true,
						"autoRedirects": false,
						"useKeepalive": true,
						"doMultipartPost": false,
						"doBrowserCompatibleMultipart": false
					},
					"sons": [{
						"type": "CsvDataSet",
						"name": "CsvDataSet",
						"id": 3,
						"value": {
							"comment": "csv描述",
							"name": "csv名称",
							"enabled": true,
							"delimiter": ",",
							"filename": "filePath",
							"fileEncoding": "utf-8",
							"ignoreFirstLine": true,
							"quoted": false,
							"recycle": true,
							"variableNames": "以逗号分隔",
							"stopThread": false,
							"shareMode": "shareMode.all"
						}
					}]
				},
				{
					"type": "CsvDataSet",
					"name": "CsvDataSet",
					"id": 3,
					"value": {
						"comment": "csv描述",
						"name": "csv名称",
						"enabled": true,
						"delimiter": ",",
						"filename": "filePath",
						"fileEncoding": "utf-8",
						"ignoreFirstLine": true,
						"quoted": false,
						"recycle": true,
						"variableNames": "以逗号分隔",
						"stopThread": false,
						"shareMode": "shareMode.all"
					}
				},
				{
					"type": "ArgumentsPanel",
					"name": "argumentsPanel",
					"id": 3,
					"value": {
						"comment": "csv描述",
						"name": "csv名称",
						"enabled": true,
						"arguments": [{
							"name": "as",
							"value": "sa",
							"description": "sadads",
							"metadata": "="
						}, {
							"name": "sd",
							"value": "d",
							"description": "sadads",
							"metadata": "="
						}]
					}
				},
				{
					"type": "HTTPArgumentsPanel",
					"name": "argumentsPanel",
					"id": 3,
					"value": {
						"arguments": [{
							"name": "key",
							"value": "value",
							"comment": "sds",
							"alwaysEncode": true,
							"contentType": "text/plain",
							"useEquals": true
						}]
					}
				},
				{
					"type": "HeaderManager",
					"name": "argumentsPanel",
					"id": 3,
					"value": {
						"comment": "描述",
						"name": "名称",
						"enabled": true,
						"headers": [{
							"name": "de",
							"value": "as"
						}, {
							"name": "zx",
							"value": "vf"
						}]
					}
				},
				{
					"type": "CookieManager",
					"name": "CookieManager",
					"id": 3,
					"value": {
						"comment": "描述",
						"name": "名称",
						"enabled": true,
						"cookiePolicy": "standard",
						"clearEachIteration": false,
						"controlledByThreadGroup": false,
						"cookies": [{
							"name": "xc",
							"value": "xxs",
							"domain": "sw",
							"path": "ew",
							"secure": false
						}]
					}
				}
			]
		}]
	}]
}

JMeterUtiles解析

// 加载jmeter.properties配置文件
JMeterUtils.loadJMeterProperties(JMETER_HOME_LOCAL + File.separator + "bin"+ File.separator + "jmeter.properties");
// 指定jmeter bin路径
JMeterUtils.setJMeterHome(JMETER_HOME_LOCAL);
// 使用配置文件中指定的语言
JMeterUtils.initLocale();
// 设置语言
JMeterUtils.setLocale(Locale.CHINESE);
// 获取jmeter/bin目录下的saveservice.properties文件,返回File对象
JMeterUtils.findFile();
// 获取.Properties文件,返回Properties对象
JMeterUtils.loadProperties("");
// 获取jmeter.properties配置文件,返回Properties对象
JMeterUtils.getProperties();
// 获取语言类型
JMeterUtils.getLocale()
JMeterUtils.getJMeterHome()
JMeterUtils.getJMeterBinDir()
JMeterUtils.getJMeterVersion()

SaveService 解析

// 获取saveservice要使用的properties文件,返回Properties对象 
SaveService.loadProperties();
//可以将生成的hashTree保存成一个jmx文件 
String uuid = UUID.randomUUID().toString().replaceAll("-","");
String filePath = jmxPath + File.separator + uuid + ".jmx";
SaveService.saveTree(hashTreeTestPlan, new FileOutputStream(filePath));
// 将文件解析成hashtree
File file = new File("/Users/wzr/Documents/work/ratel/9b0e2b0022fd4b868f3f20b92ed2bb6d.jmx");
HashTree hashTree = SaveService.loadTree(file);
Apache JMeter 源码(apache-jmeter-5.4.3_src.zip)可用于测试静态和动态资源、Web 动态应用程序的性能。 它可用于模拟服务器、服务器组、网络或对象上的重负载,以测试其强度或分析不同负载类型下的整体性能。 Apache JMeter 功能包括: 能够加载和性能测试许多不同的应用程序/服务器/协议类型: 网络 - HTTP、HTTPS(Java、NodeJS、PHP、ASP.NET,...) SOAP/REST 网络服务 FTP 通过 JDBC 数据库 LDAP 通过 JMS 的面向消息的中间件 (MOM) 邮件 - SMTP(S)、POP3(S) 和 IMAP(S) 本机命令或 shell 脚本 TCP Java 对象 全功能测试 IDE,允许快速记录测试计划(来自浏览器或本机应用程序)、构建和调试。 CLI 模式(命令行模式(以前​​称为非 GUI)/无头模式)从任何 Java 兼容操作系统(Linux、Windows、Mac OSX 等)加载测试 完整且可随时呈现的动态 HTML 报告 通过从最流行的响应格式、HTML、JSON、 XML或任何文本格式中提取数据的能力轻松关联 完全可移植性和100% Java 纯度。 完整的多线程框架允许多个线程并发采样和不同线程组同时采样不同功能。 缓存和离线分析/重放测试结果。 高度可扩展的核心: 可插拔采样器允许无限的测试功能。 可编写脚本的采样器(与 JSR223 兼容的语言,如Groovy和 BeanShell) 可以使用可插拔计时器选择多个负载统计信息。 数据分析和可视化插件允许极大的可扩展性和个性化。 函数可用于为测试提供动态输入或提供数据操作。 通过适用于 Maven、Gradle 和 Jenkins 的第3方开源库轻松实现持续集成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值