package com.eactive.testmaster.api.controller; import com.eactive.testmaster.api.condition.ConditionMatcher; import com.eactive.testmaster.api.condition.ConditionMatcherService; import com.eactive.testmaster.api.dto.MockRequest; import com.eactive.testmaster.api.entity.MockCondition; import com.eactive.testmaster.api.entity.MockResponse; import com.eactive.testmaster.api.entity.MockRoute; import com.eactive.testmaster.api.service.MockRouteService; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RestController; @RestController public class MockApiController { private final MockRouteService mockRouteService; private final ConditionMatcherService conditionMatcherService; public MockApiController(MockRouteService mockRouteService, ConditionMatcherService conditionMatcherService) { this.mockRouteService = mockRouteService; this.conditionMatcherService = conditionMatcherService; } private static final Logger logger = LoggerFactory.getLogger(MockApiController.class); public ResponseEntity handleRequest(HttpServletRequest httpRequest) throws IOException { MockRequest request = new MockRequest(httpRequest); AntPathMatcher pathMatcher = new AntPathMatcher(); logger.debug("==========================="); logger.debug("Request: " + request.getMethod() + " " + request.getUri()); logger.debug("Headers:" + request.getHeaders().toString()); logger.debug("Params: " + request.getParams().toString()); logger.debug("Body: "); logger.debug(request.getBody()); logger.debug("==========================="); for (MockRoute mockRoute : mockRouteService.getAllRoutes()) { 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) { Thread.currentThread().interrupt(); logger.error("Error while delaying response", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing request due to interruption."); } } 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) { MockResponse defaultResponse = mockRoute.getResponses().stream().filter(MockResponse::isDefaultResponse).findFirst().orElse(null); List 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 conditions, MockRequest request, Map pathVariables) { if (conditions == null) { return true; } for (MockCondition condition : conditions) { ConditionMatcher matcher = conditionMatcherService.getMatcher(condition.getType().toLowerCase()); if (matcher != null && !matcher.matches(condition, request, pathVariables)) { return false; } } return true; } }