package com.uaihebert.uaimockserver.util; import com.uaihebert.uaimockserver.facade.RequestValidatorFacade; import com.uaihebert.uaimockserver.log.backend.Log; import com.uaihebert.uaimockserver.model.UaiRequest; import com.uaihebert.uaimockserver.model.UaiRoute; import com.uaihebert.uaimockserver.repository.UaiRouteRepository; import io.undertow.server.HttpServerExchange; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; public final class RouteFinderUtil { private static final String INVALID_DATA_MESSAGE = "It was not possible to validate the sent data against the routes in the config file. Check the log."; private static final String URI_NOT_FOUND_MESSAGE = "%nWe could not find the requested URI [%s] with the method [%s]. %n " + "Check the config file and try to find the mapping. A \\ in the end of the URI will affect the result. %n " + "Also check if all the required query param and/header were sent. %n"; private RouteFinderUtil() { } /** * This method will return the route of the received request * It will check for the same queryParam and header * We can have URLs like: * http://uaimockserver.com?queryParam=A returns 201 * http://uaimockserver.com?queryParam=B returns 204 * * @param httpServerExchange the current request * @return the route. */ public static UaiRoute findValidRoute(final HttpServerExchange httpServerExchange) { final List<UaiRoute> orderedList = getSortedRouteByKey(httpServerExchange); if (orderedList.isEmpty()) { final String errorText = String.format(URI_NOT_FOUND_MESSAGE, httpServerExchange.getRequestURI(), httpServerExchange.getRequestMethod()); ExceptionUtil.logBeforeThrowing(new IllegalArgumentException(errorText)); } for (UaiRoute uaiRoute : orderedList) { final RequestValidatorFacade.RequestAnalysisResult validRequest = RequestValidatorFacade.isValidRequest(uaiRoute.getRequest(), httpServerExchange); if (validRequest.isValid()) { return uaiRoute; } if (validRequest.isAbortTheRequest()) { break; } } Log.warnFormatted(INVALID_DATA_MESSAGE); throw new IllegalArgumentException(INVALID_DATA_MESSAGE); } private static List<UaiRoute> getSortedRouteByKey(final HttpServerExchange httpServerExchange) { final Set<UaiRoute> uaiRouteList = UaiRouteRepository.findRouteListByKey(httpServerExchange); final List<UaiRoute> listToOrder = filterRoutesIfNeeded(new ArrayList<UaiRoute>(uaiRouteList)); Collections.sort(listToOrder, new RouteComparator()); return listToOrder; } private static List<UaiRoute> filterRoutesIfNeeded(final List<UaiRoute> orderedList) { final List<UaiRoute> uaiRouteList = filterByHeader(orderedList); return filterByQueryParam(uaiRouteList); } private static List<UaiRoute> filterByHeader(final List<UaiRoute> orderedList) { boolean hasRequiredHeader = hasRequiredHeader(orderedList); if (!hasRequiredHeader) { return orderedList; } final List<UaiRoute> uaiRouteList = new ArrayList<UaiRoute>(); for (UaiRoute uaiRoute : orderedList) { if (uaiRoute.getRequest().getRequiredHeaderList().isEmpty()) { continue; } uaiRouteList.add(uaiRoute); } return uaiRouteList; } private static List<UaiRoute> filterByQueryParam(final List<UaiRoute> orderedList) { boolean hasRequiredQueryParam = hasRequiredQueryParam(orderedList); if (!hasRequiredQueryParam) { return orderedList; } final List<UaiRoute> uaiRouteList = new ArrayList<UaiRoute>(); for (UaiRoute uaiRoute : orderedList) { if (uaiRoute.getRequest().getRequiredQueryParamList().isEmpty()) { continue; } uaiRouteList.add(uaiRoute); } return uaiRouteList; } private static boolean hasRequiredHeader(final List<UaiRoute> orderedList) { for (UaiRoute uaiRoute : orderedList) { final UaiRequest request = uaiRoute.getRequest(); if (!request.getRequiredHeaderList().isEmpty()) { return true; } } return false; } private static boolean hasRequiredQueryParam(final List<UaiRoute> orderedList) { for (UaiRoute uaiRoute : orderedList) { final UaiRequest request = uaiRoute.getRequest(); if (!request.getRequiredQueryParamList().isEmpty()) { return true; } } return false; } }