Merge branch 'v1.7' of github.com:metersphere/metersphere into v1.7
This commit is contained in:
commit
8aaa11fb0b
|
@ -31,6 +31,7 @@ import io.metersphere.service.CheckPermissionService;
|
||||||
import io.metersphere.service.FileService;
|
import io.metersphere.service.FileService;
|
||||||
import io.metersphere.service.ScheduleService;
|
import io.metersphere.service.ScheduleService;
|
||||||
import io.metersphere.track.request.testplan.SaveTestPlanRequest;
|
import io.metersphere.track.request.testplan.SaveTestPlanRequest;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
|
@ -212,18 +213,18 @@ public class APITestController {
|
||||||
//查询完成率、进行中、已完成
|
//查询完成率、进行中、已完成
|
||||||
List<ApiDataCountResult> countResultByStatelList = apiDefinitionService.countStateByProjectID(projectId);
|
List<ApiDataCountResult> countResultByStatelList = apiDefinitionService.countStateByProjectID(projectId);
|
||||||
apiCountResult.countStatus(countResultByStatelList);
|
apiCountResult.countStatus(countResultByStatelList);
|
||||||
long allCount = apiCountResult.getFinishedCount()+apiCountResult.getRunningCount()+apiCountResult.getNotStartedCount();
|
long allCount = apiCountResult.getFinishedCount() + apiCountResult.getRunningCount() + apiCountResult.getNotStartedCount();
|
||||||
|
|
||||||
if(allCount!=0){
|
if (allCount != 0) {
|
||||||
float complateRageNumber =(float)apiCountResult.getFinishedCount()*100/allCount;
|
float complateRageNumber = (float) apiCountResult.getFinishedCount() * 100 / allCount;
|
||||||
DecimalFormat df = new DecimalFormat("0.0");
|
DecimalFormat df = new DecimalFormat("0.0");
|
||||||
apiCountResult.setCompletionRage(df.format(complateRageNumber)+"%");
|
apiCountResult.setCompletionRage(df.format(complateRageNumber) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>"+apiCountResult.getHttpApiDataCountNumber());
|
apiCountResult.setHttpCountStr("HTTP <br/><br/>" + apiCountResult.getHttpApiDataCountNumber());
|
||||||
apiCountResult.setRpcCountStr("RPC <br/><br/>"+apiCountResult.getRpcApiDataCountNumber());
|
apiCountResult.setRpcCountStr("RPC <br/><br/>" + apiCountResult.getRpcApiDataCountNumber());
|
||||||
apiCountResult.setTcpCountStr("TCP <br/><br/>"+apiCountResult.getTcpApiDataCountNumber());
|
apiCountResult.setTcpCountStr("TCP <br/><br/>" + apiCountResult.getTcpApiDataCountNumber());
|
||||||
apiCountResult.setSqlCountStr("SQL <br/><br/>"+apiCountResult.getSqlApiDataCountNumber());
|
apiCountResult.setSqlCountStr("SQL <br/><br/>" + apiCountResult.getSqlApiDataCountNumber());
|
||||||
return apiCountResult;
|
return apiCountResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,19 +246,19 @@ public class APITestController {
|
||||||
//未覆盖 已覆盖: 统计当前接口下是否含有案例
|
//未覆盖 已覆盖: 统计当前接口下是否含有案例
|
||||||
List<ApiDataCountResult> countResultByApiCoverageList = apiDefinitionService.countApiCoverageByProjectID(projectId);
|
List<ApiDataCountResult> countResultByApiCoverageList = apiDefinitionService.countApiCoverageByProjectID(projectId);
|
||||||
apiCountResult.countApiCoverage(countResultByApiCoverageList);
|
apiCountResult.countApiCoverage(countResultByApiCoverageList);
|
||||||
long allCount = apiCountResult.getCoverageCount()+apiCountResult.getUncoverageCount();
|
long allCount = apiCountResult.getCoverageCount() + apiCountResult.getUncoverageCount();
|
||||||
|
|
||||||
if(allCount!=0){
|
if (allCount != 0) {
|
||||||
float coverageRageNumber =(float)apiCountResult.getCoverageCount()*100/allCount;
|
float coverageRageNumber = (float) apiCountResult.getCoverageCount() * 100 / allCount;
|
||||||
DecimalFormat df = new DecimalFormat("0.0");
|
DecimalFormat df = new DecimalFormat("0.0");
|
||||||
apiCountResult.setCoverageRage(df.format(coverageRageNumber)+"%");
|
apiCountResult.setCoverageRage(df.format(coverageRageNumber) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>"+apiCountResult.getHttpApiDataCountNumber());
|
apiCountResult.setHttpCountStr("HTTP <br/><br/>" + apiCountResult.getHttpApiDataCountNumber());
|
||||||
apiCountResult.setRpcCountStr("RPC <br/><br/>"+apiCountResult.getRpcApiDataCountNumber());
|
apiCountResult.setRpcCountStr("RPC <br/><br/>" + apiCountResult.getRpcApiDataCountNumber());
|
||||||
apiCountResult.setTcpCountStr("TCP <br/><br/>"+apiCountResult.getTcpApiDataCountNumber());
|
apiCountResult.setTcpCountStr("TCP <br/><br/>" + apiCountResult.getTcpApiDataCountNumber());
|
||||||
apiCountResult.setSqlCountStr("SQL <br/><br/>"+apiCountResult.getSqlApiDataCountNumber());
|
apiCountResult.setSqlCountStr("SQL <br/><br/>" + apiCountResult.getSqlApiDataCountNumber());
|
||||||
|
|
||||||
return apiCountResult;
|
return apiCountResult;
|
||||||
}
|
}
|
||||||
|
@ -318,10 +319,10 @@ public class APITestController {
|
||||||
apiCountResult.countScheduleExecute(allExecuteResult);
|
apiCountResult.countScheduleExecute(allExecuteResult);
|
||||||
|
|
||||||
long allCount = apiCountResult.getExecutedCount();
|
long allCount = apiCountResult.getExecutedCount();
|
||||||
if(allCount!=0){
|
if (allCount != 0) {
|
||||||
float coverageRageNumber =(float)apiCountResult.getSuccessCount()*100/allCount;
|
float coverageRageNumber = (float) apiCountResult.getSuccessCount() * 100 / allCount;
|
||||||
DecimalFormat df = new DecimalFormat("0.0");
|
DecimalFormat df = new DecimalFormat("0.0");
|
||||||
apiCountResult.setSuccessRage(df.format(coverageRageNumber)+"%");
|
apiCountResult.setSuccessRage(df.format(coverageRageNumber) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiCountResult;
|
return apiCountResult;
|
||||||
|
@ -330,16 +331,16 @@ public class APITestController {
|
||||||
@GetMapping("/faliureCaseAboutTestPlan/{projectId}/{limitNumber}")
|
@GetMapping("/faliureCaseAboutTestPlan/{projectId}/{limitNumber}")
|
||||||
public List<ExecutedCaseInfoDTO> faliureCaseAboutTestPlan(@PathVariable String projectId, @PathVariable int limitNumber) {
|
public List<ExecutedCaseInfoDTO> faliureCaseAboutTestPlan(@PathVariable String projectId, @PathVariable int limitNumber) {
|
||||||
|
|
||||||
List<ExecutedCaseInfoResult> selectDataList = apiDefinitionExecResultService.findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(projectId,limitNumber);
|
List<ExecutedCaseInfoResult> selectDataList = apiDefinitionExecResultService.findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(projectId, limitNumber);
|
||||||
|
|
||||||
List<ExecutedCaseInfoDTO> returnList = new ArrayList<>(limitNumber);
|
List<ExecutedCaseInfoDTO> returnList = new ArrayList<>(limitNumber);
|
||||||
|
|
||||||
for(int dataIndex = 0;dataIndex < limitNumber;dataIndex ++){
|
for (int dataIndex = 0; dataIndex < limitNumber; dataIndex++) {
|
||||||
|
|
||||||
ExecutedCaseInfoDTO dataDTO = new ExecutedCaseInfoDTO();
|
ExecutedCaseInfoDTO dataDTO = new ExecutedCaseInfoDTO();
|
||||||
dataDTO.setSortIndex(dataIndex+1);
|
dataDTO.setSortIndex(dataIndex + 1);
|
||||||
|
|
||||||
if(dataIndex<selectDataList.size()){
|
if (dataIndex < selectDataList.size()) {
|
||||||
ExecutedCaseInfoResult selectData = selectDataList.get(dataIndex);
|
ExecutedCaseInfoResult selectData = selectDataList.get(dataIndex);
|
||||||
dataDTO.setCaseID(selectData.getTestCaseID());
|
dataDTO.setCaseID(selectData.getTestCaseID());
|
||||||
dataDTO.setCaseName(selectData.getCaseName());
|
dataDTO.setCaseName(selectData.getCaseName());
|
||||||
|
@ -347,7 +348,7 @@ public class APITestController {
|
||||||
dataDTO.setFailureTimes(selectData.getFailureTimes());
|
dataDTO.setFailureTimes(selectData.getFailureTimes());
|
||||||
dataDTO.setCaseType(selectData.getCaseType());
|
dataDTO.setCaseType(selectData.getCaseType());
|
||||||
dataDTO.setTestPlanDTOList(selectData.getTestPlanDTOList());
|
dataDTO.setTestPlanDTOList(selectData.getTestPlanDTOList());
|
||||||
}else {
|
} else {
|
||||||
dataDTO.setCaseName("");
|
dataDTO.setCaseName("");
|
||||||
dataDTO.setTestPlan("");
|
dataDTO.setTestPlan("");
|
||||||
}
|
}
|
||||||
|
@ -365,7 +366,7 @@ public class APITestController {
|
||||||
resultList) {
|
resultList) {
|
||||||
taskInfo.setIndex(dataIndex++);
|
taskInfo.setIndex(dataIndex++);
|
||||||
Date nextExecutionTime = CronUtils.getNextTriggerTime(taskInfo.getRule());
|
Date nextExecutionTime = CronUtils.getNextTriggerTime(taskInfo.getRule());
|
||||||
if(nextExecutionTime!=null){
|
if (nextExecutionTime != null) {
|
||||||
taskInfo.setNextExecutionTime(nextExecutionTime.getTime());
|
taskInfo.setNextExecutionTime(nextExecutionTime.getTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,6 +379,7 @@ public class APITestController {
|
||||||
schedule.setEnable(request.isEnable());
|
schedule.setEnable(request.isEnable());
|
||||||
apiAutomationService.updateSchedule(schedule);
|
apiAutomationService.updateSchedule(schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/historicalDataUpgrade")
|
@PostMapping(value = "/historicalDataUpgrade")
|
||||||
public String historicalDataUpgrade(@RequestBody SaveHistoricalDataUpgrade request) {
|
public String historicalDataUpgrade(@RequestBody SaveHistoricalDataUpgrade request) {
|
||||||
return historicalDataUpgradeService.upgrade(request);
|
return historicalDataUpgradeService.upgrade(request);
|
||||||
|
@ -390,30 +392,11 @@ public class APITestController {
|
||||||
|
|
||||||
String testName = runRequest.getName();
|
String testName = runRequest.getName();
|
||||||
|
|
||||||
try{
|
//将jmx处理封装为通用方法
|
||||||
//将ThreadGroup的testname改为接口名称
|
jmxString = apiTestService.updateJmxString(jmxString,testName,true);
|
||||||
Document doc = DocumentHelper.parseText(jmxString);// 获取可续保保单列表报文模板
|
|
||||||
Element root = doc.getRootElement();
|
|
||||||
Element rootHashTreeElement = root.element("hashTree");
|
|
||||||
Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
|
|
||||||
Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
|
|
||||||
theadGroupElement.attribute("testname").setText(testName);
|
|
||||||
|
|
||||||
List<Element> thirdHashTreeElementList =innerHashTreeElement.elements("hashTree");
|
|
||||||
for (Element element:thirdHashTreeElementList) {
|
|
||||||
List<Element> sampleProxyElementList = element.elements("HTTPSamplerProxy");
|
|
||||||
for (Element itemElement: sampleProxyElementList) {
|
|
||||||
itemElement.attribute("testname").setText(testName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jmxString = root.asXML();
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
JmxInfoDTO dto = new JmxInfoDTO();
|
JmxInfoDTO dto = new JmxInfoDTO();
|
||||||
dto.setName(runRequest.getName()+".jmx");
|
dto.setName(runRequest.getName() + ".jmx");
|
||||||
dto.setXml(jmxString);
|
dto.setXml(jmxString);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ import io.metersphere.track.service.TestCaseService;
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.common.constants.CommonConstants;
|
import org.apache.dubbo.common.constants.CommonConstants;
|
||||||
import org.aspectj.util.FileUtil;
|
import org.aspectj.util.FileUtil;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.Element;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
@ -457,4 +460,88 @@ public class APITestService {
|
||||||
copyBodyFiles(test.getId(), sourceId);
|
copyBodyFiles(test.getId(), sourceId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String updateJmxString(String jmxString,String testName,boolean updateHTTPSamplerProxyName) {
|
||||||
|
try {
|
||||||
|
//将ThreadGroup的testname改为接口名称
|
||||||
|
Document doc = DocumentHelper.parseText(jmxString);// 获取可续保保单列表报文模板
|
||||||
|
Element root = doc.getRootElement();
|
||||||
|
Element rootHashTreeElement = root.element("hashTree");
|
||||||
|
Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
|
||||||
|
Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
|
||||||
|
theadGroupElement.attribute("testname").setText(testName);
|
||||||
|
|
||||||
|
List<Element> thirdHashTreeElementList = innerHashTreeElement.elements("hashTree");
|
||||||
|
for (Element element : thirdHashTreeElementList) {
|
||||||
|
List<Element> sampleProxyElementList = element.elements("HTTPSamplerProxy");
|
||||||
|
for (Element itemElement : sampleProxyElementList) {
|
||||||
|
if(updateHTTPSamplerProxyName){
|
||||||
|
itemElement.attribute("testname").setText(testName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Element> tcpSamplerList = element.elements("TCPSampler");
|
||||||
|
for (Element itemElement : tcpSamplerList) {
|
||||||
|
if(updateHTTPSamplerProxyName){
|
||||||
|
itemElement.attribute("testname").setText(testName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Element> jdbcSamplerList = element.elements("JDBCSampler");
|
||||||
|
for (Element itemElement : jdbcSamplerList) {
|
||||||
|
if(updateHTTPSamplerProxyName){
|
||||||
|
itemElement.attribute("testname").setText(testName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Element> dubboSampleList = element.elements("DubboSample");
|
||||||
|
for (Element itemElement : dubboSampleList) {
|
||||||
|
if(updateHTTPSamplerProxyName){
|
||||||
|
itemElement.attribute("testname").setText(testName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//dubbo节点要更新 标签、guiClass 和 testClass
|
||||||
|
itemElement.setName("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
|
||||||
|
itemElement.attribute("testclass").setText("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
|
||||||
|
itemElement.attribute("guiclass").setText("io.github.ningyu.jmeter.plugin.dubbo.gui.DubboSampleGui");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查有没有自定义参数
|
||||||
|
List<Element> scriptHashTreeElementList = element.elements("hashTree");
|
||||||
|
for (Element scriptHashTreeElement : scriptHashTreeElementList) {
|
||||||
|
boolean isRemove = false;
|
||||||
|
List<Element> removeElement = new ArrayList<>();
|
||||||
|
List<Element> scriptElementItemList = scriptHashTreeElement.elements();
|
||||||
|
for (Element hashTreeItemElement : scriptElementItemList) {
|
||||||
|
String className = hashTreeItemElement.attributeValue("testclass");
|
||||||
|
String qname = hashTreeItemElement.getQName().getName();
|
||||||
|
|
||||||
|
if (isRemove) {
|
||||||
|
if (org.apache.commons.lang3.StringUtils.equals("hashTree", qname)) {
|
||||||
|
removeElement.add(hashTreeItemElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isRemove = false;
|
||||||
|
if (org.apache.commons.lang3.StringUtils.equals(className, "JSR223PostProcessor")) {
|
||||||
|
List<Element> scriptElements = hashTreeItemElement.elements("stringProp");
|
||||||
|
for (Element scriptElement : scriptElements) {
|
||||||
|
String scriptName = scriptElement.attributeValue("name");
|
||||||
|
String contentValue = scriptElement.getStringValue();
|
||||||
|
|
||||||
|
if ("script".equals(scriptName) && contentValue.startsWith("io.metersphere.api.jmeter.JMeterVars.addVars")) {
|
||||||
|
isRemove = true;
|
||||||
|
removeElement.add(hashTreeItemElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Element itemElement : removeElement) {
|
||||||
|
scriptHashTreeElement.remove(itemElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jmxString = root.asXML();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return jmxString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ public class ApiAutomationService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioMapper apiScenarioMapper;
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private APITestService apiTestService;
|
||||||
|
@Resource
|
||||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||||
|
@ -680,14 +682,17 @@ public class ApiAutomationService {
|
||||||
|
|
||||||
HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null);
|
HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null);
|
||||||
String jmx = testPlan.getJmx(jmeterHashTree);
|
String jmx = testPlan.getJmx(jmeterHashTree);
|
||||||
|
|
||||||
|
jmx = apiTestService.updateJmxString(jmx,testName,false);
|
||||||
|
|
||||||
//将ThreadGroup的testname改为接口名称
|
//将ThreadGroup的testname改为接口名称
|
||||||
Document doc = DocumentHelper.parseText(jmx);// 获取可续保保单列表报文模板
|
// Document doc = DocumentHelper.parseText(jmx);// 获取可续保保单列表报文模板
|
||||||
Element root = doc.getRootElement();
|
// Element root = doc.getRootElement();
|
||||||
Element rootHashTreeElement = root.element("hashTree");
|
// Element rootHashTreeElement = root.element("hashTree");
|
||||||
Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
|
// Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
|
||||||
Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
|
// Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
|
||||||
theadGroupElement.attribute("testname").setText(testName);
|
// theadGroupElement.attribute("testname").setText(testName);
|
||||||
jmx = root.asXML();
|
// jmx = root.asXML();
|
||||||
|
|
||||||
String name = request.getName() + ".jmx";
|
String name = request.getName() + ".jmx";
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ public class TestPlanService {
|
||||||
testPlan.setActualEndTime(null);
|
testPlan.setActualEndTime(null);
|
||||||
} // 已完成->进行中,结束时间置空
|
} // 已完成->进行中,结束时间置空
|
||||||
} else if (!res.getStatus().equals(TestPlanStatus.Prepare.name()) &&
|
} else if (!res.getStatus().equals(TestPlanStatus.Prepare.name()) &&
|
||||||
testPlan.getStatus().equals(TestPlanStatus.Prepare.name())) {
|
TestPlanStatus.Prepare.name().equals(testPlan.getStatus())) {
|
||||||
testPlan.setActualStartTime(null);
|
testPlan.setActualStartTime(null);
|
||||||
testPlan.setActualEndTime(null);
|
testPlan.setActualEndTime(null);
|
||||||
} // 非未开始->未开始,时间都置空
|
} // 非未开始->未开始,时间都置空
|
||||||
|
@ -193,7 +193,7 @@ public class TestPlanService {
|
||||||
List<String> userIds = new ArrayList<>();
|
List<String> userIds = new ArrayList<>();
|
||||||
userIds.add(testPlan.getPrincipal());
|
userIds.add(testPlan.getPrincipal());
|
||||||
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
||||||
int i = testPlanMapper.updateByPrimaryKey(testPlan); // 更新
|
int i = testPlanMapper.updateByPrimaryKeySelective(testPlan); // 更新
|
||||||
if (!StringUtils.isBlank(testPlan.getStatus())) {
|
if (!StringUtils.isBlank(testPlan.getStatus())) {
|
||||||
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
|
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
|
||||||
String context = getTestPlanContext(testPlans, NoticeConstants.Event.UPDATE);
|
String context = getTestPlanContext(testPlans, NoticeConstants.Event.UPDATE);
|
||||||
|
|
Loading…
Reference in New Issue