/** * Runs REST validation on API, stores XML results into apiEntry. * * @param apiEntry informations about API. */ private void validateTreeXML(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("<results_of_REST_checking>"); RestValidator restValidator = new RestValidator(apiEntry.getResourceNodes()); String validation; if (restValidator.validateApi()) { validation = "Your API is RESTful."; } else { ErrsAndWarns errsAndWarns = countErrsAndWarns(apiEntry); if (errsAndWarns.getErrorsCount() == 0) { validation = "Your API is RESTful, but found " + errsAndWarns.getWarnsCount() + " warnings - see details of each resource."; } else { validation = "Your API is not RESTful, found " + errsAndWarns.getErrorsCount() + " errors and " + errsAndWarns.getWarnsCount() + " warnings - see details of each resource."; } } sb.append(validation); sb.append("</results_of_REST_checking>"); apiEntry.setMessage(sb.toString()); }
/** * Handles POST requests for / * * @param apiEntry the object with form data about entry point. * @param result BindingResult with data about validation of input data. * @return JSP page which will be shown. */ @RequestMapping(value = "/", method = RequestMethod.POST) public String doCheckAPI(ApiEntry apiEntry, BindingResult result) { if (result.hasErrors()) { return JSP; } if (!apiEntry.getUrl().startsWith("http://") && !apiEntry.getUrl().startsWith("https://")) { apiEntry.setUrl("http://" + apiEntry.getUrl()); } if (apiEntry.getUrl().length() < 10) { apiEntry.setMessage("Invalid URL"); return JSP; } createTree(apiEntry); if (HttpValidator.responseOk(apiEntry) && apiEntry.getResourceNodes().getDescendants().size() > 0) { validateTree(apiEntry); generateViewOfQuestionnaires(apiEntry); generateViewOfResources(apiEntry); generateViewOfTree(apiEntry); return JSPOkResponse; } else { return JSPBadResponse; } }
/** * Run REST validation on API, stores results into apiEntry. * * @param apiEntry informations about API. */ private void validateTree(ApiEntry apiEntry) { RestValidator restValidator = new RestValidator(apiEntry.getResourceNodes()); String validation = ""; if (restValidator.validateApi()) { if (apiEntry.getQuestionnaires().evaluate().equals("")) { validation = "</p><h3>Great Job! The API is RESTful!</h3><p>"; } validation = validation + "</p><h4>Automatically checked constraints</h4><p>Cache constraint OK!<br />Layered System constraint OK!<br />Uniform Interface OK! (for resources under the API structure)</p>"; } else { ErrsAndWarns errsAndWarns = countErrsAndWarns(apiEntry); if (errsAndWarns.getErrorsCount() == 0) { validation = "</p><h4>Automatically checked constraints</h4><p>Cache constraint OK!<br />Layered System constraint OK!<br />Uniform Interface OK! (for resources under the API structure)<br /> But found " + errsAndWarns.getWarnsCount() + " warnings - see yellow marks below for details.</p>"; } else { validation = "</p><h4>Automatically checked constraints</h4><p>Your API is not RESTful, found " + errsAndWarns.getErrorsCount() + " errors and " + errsAndWarns.getWarnsCount() + " warnings - see colored marks below for details.</p>"; } } apiEntry.setMessage(validation); }
/** * Generates the XML view of API tree from apiEntry and saves it to it. * * @param apiEntry Informations about tree. */ private void generateViewOfTreeXML(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("<api_tree>\n"); writeResourceNodeTreeViewXML( apiEntry.getResourceNodes(), apiEntry.getBaseUrl(), apiEntry.getMaxSiblings(), sb); sb.append("</api_tree>\n"); apiEntry.setMessage(sb.toString()); }
/** * Generates view of HTTP responses of resources in apiEntry and stores it into it. * * @param apiEntry with information about resource tree. */ private void generateViewOfResources(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); Set<String> visited = new HashSet<String>(); sb.append("\n<div id=\"resourceView\">"); writeResourceNodeView(apiEntry.getResourceNodes(), apiEntry.getBaseUrl(), sb, visited); sb.append("</div>\n"); apiEntry.setMessage(sb.toString()); }
/** * Generates the View of APIs resource tree. * * @param apiEntry for which the view is generated and stored into. */ private void generateViewOfTree(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("\n<div id=\"apiTree\">"); sb.append("<h4>The API structure:</h4> "); sb.append("<ul class=\"short\">\n"); writeResourceNodeTreeView( apiEntry.getResourceNodes(), apiEntry.getBaseUrl(), apiEntry.getMaxSiblings(), sb); sb.append("</ul>\n</div><p>"); apiEntry.setMessage(sb.toString()); }
/** * Handles POST requests for /repeatedtesting * * @param apiEntry the object with form data about entry point. * @return ResponseEntity with resource body. */ @RequestMapping(value = "/repeatedtesting", method = RequestMethod.POST) public ResponseEntity<String> doCheckAPIRepeatedTesting(ApiEntry apiEntry, BindingResult result) { if (result.hasErrors()) { apiEntry.setMessage("Invalid input: max siblings"); return new ResponseEntity<String>(apiEntry.getMessage(), HttpStatus.BAD_REQUEST); } if (!apiEntry.getUrl().startsWith("http://") && !apiEntry.getUrl().startsWith("https://")) { apiEntry.setUrl("http://" + apiEntry.getUrl()); } if (apiEntry.getUrl().length() < 10) { apiEntry.setMessage("Invalid input: URL"); return new ResponseEntity<String>(apiEntry.getMessage(), HttpStatus.BAD_REQUEST); } createTree(apiEntry); apiEntry.setMessage("<RESTfulChecker_report>"); generateViewOfEntryPointXML(apiEntry); validateTreeXML(apiEntry); generateViewOfTreeXML(apiEntry); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentType(MediaType.TEXT_XML); apiEntry.setMessage(apiEntry.getMessage() + "</RESTfulChecker_report>"); return new ResponseEntity<String>(apiEntry.getMessage(), responseHeaders, HttpStatus.OK); }
/** * Appends XML information about entrypoint into entrypoints message. * * @param apiEntry data about entrypoint. */ private void generateViewOfEntryPointXML(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("<test_definition>"); sb.append("<request>"); sb.append("<API_entry_URL>"); sb.append(apiEntry.getUrl()); sb.append("</API_entry_URL>"); if (apiEntry.getRequestHeaders().size() > 0) { sb.append("<headers>"); for (Header header : apiEntry.getRequestHeaders()) { sb.append("<header>"); sb.append("<key>"); sb.append(header.getHeaderKey()); sb.append("</key>"); sb.append("<value>"); sb.append(header.getHeaderValue()); sb.append("</value>"); sb.append("</header>"); } sb.append("</headers>"); } sb.append("</request>"); sb.append("<limits>"); sb.append("<max_siblings>"); sb.append(apiEntry.getMaxSiblings()); sb.append("</max_siblings>"); sb.append("<base_url>"); sb.append(apiEntry.getBaseUrl()); sb.append("</base_url>"); sb.append("</limits>"); sb.append("</test_definition>"); apiEntry.setMessage(sb.toString()); }
/** * Generates view of questionnaire for JSP and stores it into apiEntry. * * @param apiEntry for which the view is generated. */ private void generateViewOfQuestionnaires(ApiEntry apiEntry) { String evaluation = apiEntry.getQuestionnaires().evaluate(); StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("\n<div id=\"questionnairesEvaluation\">"); sb.append("<h4>Questionnaires evaluation</h4>"); if (evaluation.equals("")) { sb.append("Client-Server OK!<br /> Stateless constraints OK!<br />"); } else { if (!evaluation.contains("This is violation of REST constraint: Client-Server.")) { sb.append("Client-Server constraint OK!<br />"); } else { sb.append("Client-Server constraint VIOLATION!<br />"); } if (!evaluation.contains("This is violation of REST constraint: Stateless.")) { sb.append("Stateless constraint OK!<br />"); } else { sb.append("Stateless constraint VIOLATION!<br />"); } sb.append(evaluation); } sb.append("</div>\n"); apiEntry.setMessage(sb.toString()); }