128 lines
5.6 KiB
Java
128 lines
5.6 KiB
Java
package com.eactive.httpmockserver.api.controller;
|
|
|
|
import com.eactive.httpmockserver.api.dto.MockRequest;
|
|
import com.eactive.httpmockserver.api.entity.MockCondition;
|
|
import com.eactive.httpmockserver.api.entity.MockResponse;
|
|
import com.eactive.httpmockserver.api.entity.MockRoute;
|
|
import com.eactive.httpmockserver.api.repository.MockRouteRepository;
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.jayway.jsonpath.JsonPath;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.HttpHeaders;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.util.AntPathMatcher;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Controller
|
|
public class MockApiController {
|
|
|
|
@Autowired
|
|
private MockRouteRepository mockRouteRepository;
|
|
|
|
@RequestMapping(value = "/{_:^(?!swagger-ui|mgmt|plugins|dist|css|fonts|js|h2-console|img|pages|favicon.ico).*$}/**")
|
|
public ResponseEntity<String> handleRequest(HttpServletRequest httpRequest) {
|
|
MockRequest request = new MockRequest(httpRequest);
|
|
AntPathMatcher pathMatcher = new AntPathMatcher();
|
|
|
|
for (MockRoute mockRoute : mockRouteRepository.findAll()) {
|
|
if (isRouteMatch(mockRoute, request)) {
|
|
Map<String, String> pathVariables = pathMatcher.extractUriTemplateVariables(mockRoute.getPathPattern(), request.getUri());
|
|
MockResponse matchingResponse = findMatchingResponse(mockRoute, request, pathVariables);
|
|
|
|
if (matchingResponse != null) {
|
|
if (matchingResponse.getDelay() > 0) {
|
|
try {
|
|
Thread.sleep(matchingResponse.getDelay());
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
HttpHeaders responseHeaders = new HttpHeaders();
|
|
matchingResponse.getHeaders().forEach(responseHeaders::set);
|
|
|
|
request.getParams().putAll(pathVariables);
|
|
|
|
return new ResponseEntity<>(replaceParams(matchingResponse.getBody(), request.getParams()), responseHeaders, HttpStatus.valueOf(matchingResponse.getStatusCode()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// If no matching route or response is found, return a 404 Not Found
|
|
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not Found");
|
|
}
|
|
|
|
private String replaceParams(String responseBody, Map<String, String> params) {
|
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
responseBody = responseBody.replace("{" + entry.getKey() + "}", entry.getValue());
|
|
}
|
|
return responseBody;
|
|
}
|
|
|
|
private boolean isRouteMatch(MockRoute mockRoute, MockRequest request) {
|
|
AntPathMatcher pathMatcher = new AntPathMatcher();
|
|
return mockRoute.getMethod().equalsIgnoreCase(request.getMethod()) && pathMatcher.match(mockRoute.getPathPattern(), request.getUri());
|
|
}
|
|
|
|
private MockResponse findMatchingResponse(MockRoute mockRoute, MockRequest mockRequest, Map<String, String> pathVariables) {
|
|
|
|
MockResponse defaultResponse = mockRoute.getResponses().stream().filter(MockResponse::isDefaultResponse).findFirst().orElse(null);
|
|
List<MockResponse> responses = mockRoute.getResponses().stream().filter(response -> !response.isDefaultResponse()).collect(Collectors.toList());
|
|
if(defaultResponse!=null){
|
|
responses.add(defaultResponse);
|
|
}
|
|
|
|
for (MockResponse response : responses) {
|
|
if (response.getConditions() == null || isRequestMatching(response.getConditions(), mockRequest, pathVariables)) {
|
|
return response;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private boolean isRequestMatching(List<MockCondition> conditions, MockRequest request, Map<String, String> pathVariables) {
|
|
|
|
if (conditions == null || conditions.size() == 0) {
|
|
return true;
|
|
}
|
|
|
|
for (MockCondition condition : conditions) {
|
|
if (condition.getType().equalsIgnoreCase("query")) {
|
|
if(!condition.getValue().equals(request.getParam(condition.getKey()))){
|
|
return false;
|
|
}
|
|
} else if (condition.getType().equalsIgnoreCase("header")) {
|
|
if (!condition.getValue().equals(request.getHeader(condition.getKey()))){
|
|
return false;
|
|
}
|
|
} else if (condition.getType().equalsIgnoreCase("path")) {
|
|
if (!condition.getValue().equals(pathVariables.get(condition.getKey()))){
|
|
return false;
|
|
}
|
|
} else if (condition.getType().equalsIgnoreCase("jsonpath")) {
|
|
try {
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
JsonNode jsonNode = objectMapper.readTree(request.getBody());
|
|
boolean isMatch = JsonPath.parse(jsonNode).read(condition.getKey()+ '=' + condition.getValue());
|
|
if (!isMatch) {
|
|
return false;
|
|
}
|
|
} catch (JsonProcessingException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
}
|