Flat Message Layout
This commit is contained in:
@@ -2,8 +2,8 @@ package com.eactive.testmaster.client.controller;
|
|||||||
|
|
||||||
import com.eactive.testmaster.client.dto.ApiRequestDTO;
|
import com.eactive.testmaster.client.dto.ApiRequestDTO;
|
||||||
import com.eactive.testmaster.client.dto.ApiResponse;
|
import com.eactive.testmaster.client.dto.ApiResponse;
|
||||||
import com.eactive.testmaster.client.service.ApiClient;
|
|
||||||
import com.eactive.testmaster.client.service.ApiClientFactory;
|
import com.eactive.testmaster.client.service.ApiClientFactory;
|
||||||
|
import com.eactive.testmaster.loadtest.service.VirtualUser;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
@@ -30,9 +30,8 @@ public class ApiClientController {
|
|||||||
if (bindingResult.hasErrors()) {
|
if (bindingResult.hasErrors()) {
|
||||||
throw new IllegalArgumentException(bindingResult.getAllErrors().get(0).getDefaultMessage());
|
throw new IllegalArgumentException(bindingResult.getAllErrors().get(0).getDefaultMessage());
|
||||||
}
|
}
|
||||||
|
VirtualUser virtualUser = new VirtualUser(request.getId(), apiClientFactory);
|
||||||
ApiClient client = apiClientFactory.getClient(request);
|
return virtualUser.processApiAndReturn(request);
|
||||||
return client.handleRequest(request).get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import javax.persistence.Entity;
|
|||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.Lob;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
@@ -47,6 +48,9 @@ public class ApiLayout {
|
|||||||
@OneToMany(mappedBy = "apiLayout", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
@OneToMany(mappedBy = "apiLayout", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
private List<ApiLayoutItem> layoutItems = new ArrayList<>();
|
private List<ApiLayoutItem> layoutItems = new ArrayList<>();
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
private String computedLayoutItemRoot;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -164,4 +168,11 @@ public class ApiLayout {
|
|||||||
this.layoutItems.add(item);
|
this.layoutItems.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getComputedLayoutItemRoot() {
|
||||||
|
return computedLayoutItemRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComputedLayoutItemRoot(String computedLayoutItemRoot) {
|
||||||
|
this.computedLayoutItemRoot = computedLayoutItemRoot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.eactive.testmaster.client.mapper;
|
package com.eactive.testmaster.client.mapper;
|
||||||
|
|
||||||
import com.eactive.testmaster.client.dto.ApiLayoutDTO;
|
import com.eactive.testmaster.client.dto.ApiLayoutDTO;
|
||||||
|
import com.eactive.testmaster.client.dto.ApiLayoutItemDTO;
|
||||||
import com.eactive.testmaster.client.entity.ApiLayout;
|
import com.eactive.testmaster.client.entity.ApiLayout;
|
||||||
import com.eactive.testmaster.client.entity.ApiRequestInfo;
|
import com.eactive.testmaster.client.entity.ApiRequestInfo;
|
||||||
import com.eactive.testmaster.client.repository.ApiLayoutRepository;
|
import com.eactive.testmaster.client.repository.ApiLayoutRepository;
|
||||||
import com.eactive.testmaster.client.repository.ApiRequestRepository;
|
import com.eactive.testmaster.client.repository.ApiRequestRepository;
|
||||||
import com.eactive.testmaster.common.mapper.CommonMapper;
|
import com.eactive.testmaster.common.mapper.CommonMapper;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
@@ -19,6 +21,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public abstract class ApiLayoutMapper {
|
public abstract class ApiLayoutMapper {
|
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApiLayoutRepository apiLayoutRepository;
|
private ApiLayoutRepository apiLayoutRepository;
|
||||||
|
|
||||||
@@ -32,6 +36,31 @@ public abstract class ApiLayoutMapper {
|
|||||||
@Mapping(target = "apiRequestId", source = "apiRequestInfo")
|
@Mapping(target = "apiRequestId", source = "apiRequestInfo")
|
||||||
public abstract ApiLayoutDTO map(ApiLayout entity);
|
public abstract ApiLayoutDTO map(ApiLayout entity);
|
||||||
|
|
||||||
|
|
||||||
|
public String treeToString(ApiLayoutItemDTO value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Failed to convert ApiLayoutItemDTO to JSON", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiLayoutItemDTO stringToTree(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(value, ApiLayoutItemDTO.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Failed to convert JSON to ApiLayoutItemDTO", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public ApiRequestInfo mapApiRequestInfo(String id) {
|
public ApiRequestInfo mapApiRequestInfo(String id) {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import com.eactive.testmaster.client.entity.ApiRequestInfo;
|
|||||||
import com.eactive.testmaster.client.repository.ApiLayoutRepository;
|
import com.eactive.testmaster.client.repository.ApiLayoutRepository;
|
||||||
import com.eactive.testmaster.client.repository.ApiRequestRepository;
|
import com.eactive.testmaster.client.repository.ApiRequestRepository;
|
||||||
import com.eactive.testmaster.common.exception.NotFoundException;
|
import com.eactive.testmaster.common.exception.NotFoundException;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -64,6 +63,7 @@ public class ApiLayoutMgmtService {
|
|||||||
layout.setModfMgtStusDstCd(updatedLayout.getModfMgtStusDstCd());
|
layout.setModfMgtStusDstCd(updatedLayout.getModfMgtStusDstCd());
|
||||||
layout.setUseYn(updatedLayout.getUseYn());
|
layout.setUseYn(updatedLayout.getUseYn());
|
||||||
layout.setVerInfo(updatedLayout.getVerInfo());
|
layout.setVerInfo(updatedLayout.getVerInfo());
|
||||||
|
layout.setComputedLayoutItemRoot(updatedLayout.getComputedLayoutItemRoot());
|
||||||
|
|
||||||
if (updatedLayout.getLayoutItems() != null && !updatedLayout.getLayoutItems().isEmpty()) {
|
if (updatedLayout.getLayoutItems() != null && !updatedLayout.getLayoutItems().isEmpty()) {
|
||||||
layout.getLayoutItems().clear();
|
layout.getLayoutItems().clear();
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ public class VirtualUser implements Runnable {
|
|||||||
|
|
||||||
private Thread runningThread;
|
private Thread runningThread;
|
||||||
|
|
||||||
private final LoadTestService loadTestService;
|
private LoadTestService loadTestService;
|
||||||
private final ApiClientFactory apiClientFactory;
|
private ApiClientFactory apiClientFactory;
|
||||||
|
|
||||||
private static Map<String, String> globals = new ConcurrentHashMap<>();
|
private static Map<String, String> globals = new ConcurrentHashMap<>();
|
||||||
private Map<String, String> variables = new ConcurrentHashMap<>();
|
private Map<String, String> variables = new ConcurrentHashMap<>();
|
||||||
@@ -57,7 +57,11 @@ public class VirtualUser implements Runnable {
|
|||||||
this.maxCount = maxCount;
|
this.maxCount = maxCount;
|
||||||
this.apiClientFactory = apiClientFactory;
|
this.apiClientFactory = apiClientFactory;
|
||||||
this.latch = latch;
|
this.latch = latch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VirtualUser(String testId, ApiClientFactory apiClientFactory) {
|
||||||
|
this.testId = testId;
|
||||||
|
this.apiClientFactory = apiClientFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pause() {
|
public void pause() {
|
||||||
@@ -130,7 +134,7 @@ public class VirtualUser implements Runnable {
|
|||||||
visitedNodes.add(currentNode);
|
visitedNodes.add(currentNode);
|
||||||
|
|
||||||
if (currentNode.getClassName().equalsIgnoreCase("api")) {
|
if (currentNode.getClassName().equalsIgnoreCase("api")) {
|
||||||
processApi(currentNode);
|
processApi(currentNode.getApiRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentNode.getConnections() != null && !currentNode.getConnections().isEmpty()) {
|
if (currentNode.getConnections() != null && !currentNode.getConnections().isEmpty()) {
|
||||||
@@ -143,10 +147,35 @@ public class VirtualUser implements Runnable {
|
|||||||
logger.debug("Action performed or interrupted");
|
logger.debug("Action performed or interrupted");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processApi(ScenarioNode currentNode) {
|
|
||||||
|
public ApiResponse processApiAndReturn(ApiRequestDTO apiRequest) {
|
||||||
|
ApiRequestDTO cloned = SerializationUtils.clone(apiRequest);
|
||||||
|
ApiRequestDTO replaced = null;
|
||||||
|
|
||||||
|
executePreRequestScript(cloned);
|
||||||
|
replaced = replacePlaceHoldersWithVariables(cloned);
|
||||||
|
|
||||||
|
// long startTime = System.currentTimeMillis();
|
||||||
|
ApiResponse response = null;
|
||||||
try {
|
try {
|
||||||
if (currentNode.getApiRequest() != null) {
|
response = apiClientFactory.getClient(replaced).handleRequest(replaced).get();
|
||||||
ApiRequestDTO cloned = SerializationUtils.clone(currentNode.getApiRequest());
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// long endTime = System.currentTimeMillis();
|
||||||
|
// long responseTime = endTime - startTime;
|
||||||
|
|
||||||
|
executePostRequestScript(replaced, response);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processApi(ApiRequestDTO apiRequest) {
|
||||||
|
try {
|
||||||
|
if (apiRequest != null) {
|
||||||
|
ApiRequestDTO cloned = SerializationUtils.clone(apiRequest);
|
||||||
ApiRequestDTO replaced = null;
|
ApiRequestDTO replaced = null;
|
||||||
|
|
||||||
executePreRequestScript(cloned);
|
executePreRequestScript(cloned);
|
||||||
@@ -175,7 +204,8 @@ public class VirtualUser implements Runnable {
|
|||||||
engine.put("variables", variables);
|
engine.put("variables", variables);
|
||||||
engine.put("request", apiRequest);
|
engine.put("request", apiRequest);
|
||||||
try {
|
try {
|
||||||
engine.eval(apiRequest.getPreRequestScript());
|
if(apiRequest.getPreRequestScript() != null)
|
||||||
|
engine.eval(apiRequest.getPreRequestScript());
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
logger.error("Error executing pre-request script", e);
|
logger.error("Error executing pre-request script", e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -191,7 +221,9 @@ public class VirtualUser implements Runnable {
|
|||||||
engine.put("request", apiRequest);
|
engine.put("request", apiRequest);
|
||||||
engine.put("response", response);
|
engine.put("response", response);
|
||||||
try {
|
try {
|
||||||
engine.eval(apiRequest.getPostRequestScript());
|
if (apiRequest.getPostRequestScript() != null){
|
||||||
|
engine.eval(apiRequest.getPostRequestScript());
|
||||||
|
}
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
logger.error("Error executing post-request script", e);
|
logger.error("Error executing post-request script", e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -227,14 +259,38 @@ public class VirtualUser implements Runnable {
|
|||||||
if (apiRequest.getQueryParams() != null) {
|
if (apiRequest.getQueryParams() != null) {
|
||||||
apiRequest.setQueryParams(replaceInList(apiRequest.getQueryParams(), placeholder, value));
|
apiRequest.setQueryParams(replaceInList(apiRequest.getQueryParams(), placeholder, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiRequest.getLayout() != null && apiRequest.getLayout().getLayoutItems() != null) {
|
if (apiRequest.getLayout() != null && apiRequest.getLayout().getLayoutItems() != null) {
|
||||||
apiRequest.getLayout().setLayoutItems(replaceInLayoutItems(apiRequest.getLayout().getLayoutItems(), placeholder, value));
|
apiRequest.getLayout().setLayoutItems(replaceInLayoutItems(apiRequest.getLayout().getLayoutItems(), placeholder, value));
|
||||||
}
|
}
|
||||||
|
if (apiRequest.getLayout() !=null && apiRequest.getLayout().getComputedLayoutItemRoot() !=null){
|
||||||
|
replaceLayoutItemTree(apiRequest.getLayout().getComputedLayoutItemRoot(), placeholder, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiRequest;
|
return apiRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void replaceLayoutItemTree(ApiLayoutItemDTO computedLayoutItemRoot, String placeholder, String value) {
|
||||||
|
if (computedLayoutItemRoot == null) {
|
||||||
|
return; // Base case: if the node is null, just return.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the value in the current node if it contains the placeholder
|
||||||
|
if (computedLayoutItemRoot.getValue() != null) {
|
||||||
|
String replacedValue = computedLayoutItemRoot.getValue().replaceAll(placeholder, value);
|
||||||
|
computedLayoutItemRoot.setValue(replacedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively replace the value in each child
|
||||||
|
if (computedLayoutItemRoot.getChildren() != null) {
|
||||||
|
for (ApiLayoutItemDTO child : computedLayoutItemRoot.getChildren()) {
|
||||||
|
replaceLayoutItemTree(child, placeholder, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<ApiLayoutItemDTO> replaceInLayoutItems(List<ApiLayoutItemDTO> originalList, String placeholder, String value) {
|
private List<ApiLayoutItemDTO> replaceInLayoutItems(List<ApiLayoutItemDTO> originalList, String placeholder, String value) {
|
||||||
List<ApiLayoutItemDTO> replacedList = new ArrayList<>();
|
List<ApiLayoutItemDTO> replacedList = new ArrayList<>();
|
||||||
Pattern pattern = Pattern.compile(placeholder);
|
Pattern pattern = Pattern.compile(placeholder);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user