package com.eactive.httpmockserver.api.controller; import com.eactive.httpmockserver.api.dto.MockConditionDTO; 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; @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 handleRequest(HttpServletRequest httpRequest) { MockRequest request = new MockRequest(httpRequest); AntPathMatcher pathMatcher = new AntPathMatcher(); for (MockRoute mockRoute : mockRouteRepository.findAll()) { if (isRouteMatch(mockRoute, request)) { Map 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 params) { for (Map.Entry 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 pathVariables) { for (MockResponse response : mockRoute.getResponses()) { if (response.getConditions() == null || isRequestMatching(response.getConditions(), mockRequest, pathVariables)) { return response; } } return null; } private boolean isRequestMatching(List conditions, MockRequest request, Map 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; } }