diff --git a/src/main/jastadd/InferParameter.jrag b/src/main/jastadd/InferParameter.jrag index 6b09344a6640329b01acf0cddcdb1d49b10af603..a6df93cecf44c7d80d86b3c3b61938da60e32003 100644 --- a/src/main/jastadd/InferParameter.jrag +++ b/src/main/jastadd/InferParameter.jrag @@ -4,183 +4,183 @@ import com.fasterxml.jackson.databind.node.ArrayNode; aspect InferParameter{ - /** - * Saves response data names generated by random requests. - * <p>This is an auxiliary method to distinguish saved dictionary values.</p> - * <p>(Future work: translate this to Map or Tuple).</p> - * @return first String part divided by <code>?</code>. - */ - syn String ParameterObject.dictName(String dict) = dict.substring(0, dict.indexOf("?")); - - /** - * Saves response data values generated by random requests. - * <p>This is an auxiliary method to distinguish saved dictionary values.</p> - * <p>(Future work: translate this to Map or Tuple).</p> - * @return second String part divided by <code>?</code>. - */ - syn String ParameterObject.dictValue(String dict) = dict.substring(dict.indexOf("?")+1); - - /** - * Checks if a path has the request types <code>GET</code> and/or <code>POST</code>, and calls <code>inferUrl(String pathRef,OperationObject operationObject, List<String> dict)</code>. - * <p>Afterwards, inferred URLs are saved in a list.</p> - * @return The list of String representing the inferred URLs. - */ - inh List<String> PathsObject.inferUrl(List<String> dict); - eq OpenAPIObject.getP(int i).inferUrl(List<String> dict){ - List<String> paths = new ArrayList<>(); - PathItemObject p = getP(i).getP().pathItemObject(); - String path = getServ(0).getUrl(); - - if (p.hasG()) - paths.addAll(p.getG().inferUrl(path + getP(i).getRef(), p.getG().getO(), dict)); - else if (p.hasPostOb()) - paths.addAll(p.getPostOb().inferUrl(path + getP(i).getRef(), p.getPostOb().getO(), dict)); - - return paths; - } - - /** - * Checks which parameter types the targeted GET request has (Path or Query) and calls corresponding parameter inferrer. - * <p>Afterwards, inferred parameters are written in the url.</p> - * @return An URL with the inferred parameters in String. + /** + * Saves response data names generated by random requests. + * <p>This is an auxiliary method to distinguish saved dictionary values.</p> + * <p>(Future work: translate this to Map or Tuple).</p> + * @return first String part divided by <code>?</code>. */ - syn List<String> Get.inferUrl(String pathRef,OperationObject operationObject, List<String> dict){ - List<String> paths = new ArrayList<>(); - - for (ParameterOb o : operationObject.getPList()) { - ParameterObject p = o.parameterObject(); - SchemaObject s = p.getSchema().schemaObject(); - - // check if the parameter is in type 'path'. - if (p.getIn().equals("path")) - paths = p.addinfPathParameters(pathRef, dict); - // check if the parameter is in type 'query' - else if (p.getIn().equals("query")) - paths = p.addinfQueryParameters(pathRef, dict); - } + syn String ParameterObject.dictName(String dict) = dict.substring(0, dict.indexOf("?")); - System.out.println(paths.size() + " paths for " + pathRef + " GET request are inferred"); - return paths; - } + /** + * Saves response data values generated by random requests. + * <p>This is an auxiliary method to distinguish saved dictionary values.</p> + * <p>(Future work: translate this to Map or Tuple).</p> + * @return second String part divided by <code>?</code>. + */ + syn String ParameterObject.dictValue(String dict) = dict.substring(dict.indexOf("?") + 1); - /** - * Checks which parameter types the targeted POST request has (Path or Query) and calls corresponding parameter inferrer. - * <p>Afterwards, inferred parameters are written in the url.</p> - * @return An URL with the inferred parameters in String. + /** + * Checks if a path has the request types <code>GET</code> and/or <code>POST</code>, and calls <code>inferUrl(String pathRef,OperationObject operationObject, List<String> dict)</code>. + * <p>Afterwards, inferred URLs are saved in a list.</p> + * @return The list of String representing the inferred URLs. */ - syn List<String> Post.inferUrl(String pathRef,OperationObject operationObject, List<String> dict){ - List<String> paths = new ArrayList<>(); - - for (ParameterOb o : operationObject.getPList()) { - ParameterObject p = o.parameterObject(); - SchemaObject s = p.getSchema().schemaObject(); - - // check if the parameter is in type 'path'. - if (p.getIn().equals("path")) - paths = p.addinfPathParameters(pathRef, dict); - // check if the parameter is in type 'query' - else if (p.getIn().equals("query")) - paths = p.addinfQueryParameters(pathRef, dict); + inh List<String> PathsObject.inferUrl(List<String> dict); + eq OpenAPIObject.getP(int i).inferUrl(List<String> dict){ + List<String> paths = new ArrayList<>(); + PathItemObject p = getP(i).getP().pathItemObject(); + String path = getServ(0).getUrl(); + + if (p.hasG()) + paths.addAll(p.getG().inferUrl(path + getP(i).getRef(), p.getG().getO(), dict)); + else if (p.hasPostOb()) + paths.addAll(p.getPostOb().inferUrl(path + getP(i).getRef(), p.getPostOb().getO(), dict)); + + return paths; } - System.out.println(paths.size() + " paths for " + pathRef + " POST request are inferred"); - return paths; - } + /** + * Checks which parameter types the targeted GET request has (Path or Query) and calls corresponding parameter inferrer. + * <p>Afterwards, inferred parameters are written in the url.</p> + * @return An URL with the inferred parameters in String. + */ + syn List<String> Get.inferUrl(String pathRef,OperationObject operationObject, List<String> dict){ + List<String> paths = new ArrayList<>(); + + for (ParameterOb o : operationObject.getPList()) { + ParameterObject p = o.parameterObject(); + SchemaObject s = p.getSchema().schemaObject(); + + // check if the parameter is in type 'path'. + if (p.getIn().equals("path")) + paths = p.addinfPathParameters(pathRef, dict); + // check if the parameter is in type 'query' + else if (p.getIn().equals("query")) + paths = p.addinfQueryParameters(pathRef, dict); + } + + System.out.println(paths.size() + " paths for " + pathRef + " GET request are inferred"); + return paths; + } - /** - * Checks if there are Path parameters that are saved in the dictionary and might be usable. - * <p>Search is provided by schema names and Case-Insensitivity./p> - * @return The list of Urls with the added Url from the dicitionary. - */ - syn List<String> ParameterObject.addinfPathParameters(String pathRef,List<String> dict){ - List<String> paths = new ArrayList<>(); - for (String d : dict){ - // get the field which must be modified - String pathPart = pathRef.substring(pathRef.indexOf("{"), pathRef.indexOf("}")+1); - // case insensitive comparison of parameter name and name of inferred parameters - if (getName().equalsIgnoreCase(d.substring(0, d.indexOf("?")))) - // add inferred parameter in url - paths = root().addInList(paths, pathRef.replace(pathPart, d.substring(d.indexOf("?")+1))); + /** + * Checks which parameter types the targeted POST request has (Path or Query) and calls corresponding parameter inferrer. + * <p>Afterwards, inferred parameters are written in the url.</p> + * @return An URL with the inferred parameters in String. + */ + syn List<String> Post.inferUrl(String pathRef,OperationObject operationObject, List<String> dict){ + List<String> paths = new ArrayList<>(); + + for (ParameterOb o : operationObject.getPList()) { + ParameterObject p = o.parameterObject(); + SchemaObject s = p.getSchema().schemaObject(); + + // check if the parameter is in type 'path'. + if (p.getIn().equals("path")) + paths = p.addinfPathParameters(pathRef, dict); + // check if the parameter is in type 'query' + else if (p.getIn().equals("query")) + paths = p.addinfQueryParameters(pathRef, dict); + } + + System.out.println(paths.size() + " paths for " + pathRef + " POST request are inferred"); + return paths; } - return paths; - } - /** - * Checks if there are Query parameters that are saved in the dictionary and might be usable. - * <p>Search is provided by schema names and Case-Insensitivity./p> - * @return The list of Urls with the added Url from the dicitionary. - */ - syn List<String> ParameterObject.addinfQueryParameters(String pathRef,List<String> dict){ - List<String> paths = new ArrayList<>(); - SchemaObject s = getSchema().schemaObject(); - // check if query parameter is in type 'array' - if (s.getType().equals("array")) { - for (String d : dict){ - // case insensitive comparison of parameter name and name of inferred parameters - if (getName().equalsIgnoreCase(dictName(d)) && !pathRef.contains(getName() + "=" + dictValue(d))) - // add inferred parameter in url - pathRef = pathRef + "&" + getName() + "=" + dictValue(d); - } - paths = root().addInList(paths, pathRef.replaceFirst("&", "?")); - } else { - for (String d : dict){ - // case insensitive comparison of parameter name and name of inferred parameters - if (getName().equalsIgnoreCase(dictName(d))) - // add inferred parameter in url - paths = root().addInList(paths, pathRef + "?" + getName() + "=" + dictValue(d)); - } + /** + * Checks if there are Path parameters that are saved in the dictionary and might be usable. + * <p>Search is provided by schema names and Case-Insensitivity./p> + * @return The list of Urls with the added Url from the dicitionary. + */ + syn List<String> ParameterObject.addinfPathParameters(String pathRef,List<String> dict){ + List<String> paths = new ArrayList<>(); + for (String d : dict) { + // get the field which must be modified + String pathPart = pathRef.substring(pathRef.indexOf("{"), pathRef.indexOf("}") + 1); + // case insensitive comparison of parameter name and name of inferred parameters + if (getName().equalsIgnoreCase(d.substring(0, d.indexOf("?")))) + // add inferred parameter in url + paths = root().addInList(paths, pathRef.replace(pathPart, d.substring(d.indexOf("?") + 1))); + } + return paths; } - return paths; - } - /** - * Saves single response JSON data into the dictionary. - * @return The list of response data (dictionary). - */ - public List<String> OperationObject.writeDictionary(SchemaOb schema,String resp, List<String> dict)throws Exception{ - ObjectMapper mapper = new ObjectMapper(); - JsonNode respNode = mapper.readTree(resp); - String value; - - if (schema instanceof SchemaReference) { - for (PropertyItem p : schema.schemaObject().getPList()) { - String infName = ((SchemaReference) schema).getRef().substring(((SchemaReference) schema).getRef().lastIndexOf("/") + 1) + p.getName(); - value = respNode.get(p.getName()).toString().startsWith("\"") && - respNode.get(p.getName()).toString().endsWith("\"") ? - respNode.get(p.getName()).toString().substring(1, respNode.get(p.getName()).toString().length() - 1) : respNode.get(p.getName()).toString(); - - dict = root().addInList(dict, infName + "?" + value); - dict = root().addInList(dict, p.getName() + "?" + value); - } - } else { - for (PropertyItem p : schema.schemaObject().getPList()) { - value = respNode.get(p.getName()).toString().startsWith("\"") && - respNode.get(p.getName()).toString().endsWith("\"") ? - respNode.get(p.getName()).toString().substring(1, respNode.get(p.getName()).toString().length() - 1) : respNode.get(p.getName()).toString(); - - dict = root().addInList(dict, p.getName() + "?" + respNode.get(p.getName()).textValue()); - } + /** + * Checks if there are Query parameters that are saved in the dictionary and might be usable. + * <p>Search is provided by schema names and Case-Insensitivity./p> + * @return The list of Urls with the added Url from the dicitionary. + */ + syn List<String> ParameterObject.addinfQueryParameters(String pathRef,List<String> dict){ + List<String> paths = new ArrayList<>(); + SchemaObject s = getSchema().schemaObject(); + // check if query parameter is in type 'array' + if (s.getType().equals("array")) { + for (String d : dict) { + // case insensitive comparison of parameter name and name of inferred parameters + if (getName().equalsIgnoreCase(dictName(d)) && !pathRef.contains(getName() + "=" + dictValue(d))) + // add inferred parameter in url + pathRef = pathRef + "&" + getName() + "=" + dictValue(d); + } + paths = root().addInList(paths, pathRef.replaceFirst("&", "?")); + } else { + for (String d : dict) { + // case insensitive comparison of parameter name and name of inferred parameters + if (getName().equalsIgnoreCase(dictName(d))) + // add inferred parameter in url + paths = root().addInList(paths, pathRef + "?" + getName() + "=" + dictValue(d)); + } + } + return paths; } - return dict; - } - /** - * Saves array response JSON data into the dictionary. - * @return The list of response data (dictionary). - */ - public List<String> OperationObject.writeDictionaryWithArray(SchemaOb schema,String resp, List<String> dict)throws Exception{ - ObjectMapper mapper = new ObjectMapper(); - ArrayNode respNode = ((ArrayNode) mapper.readTree(resp)); - Iterator<JsonNode> props = respNode.elements(); - - while (props.hasNext()) - dict = writeDictionary(schema.schemaObject().getI().getSchema(), props.next().toString(), dict); - return dict; - } - - public List<String> OpenAPIObject.addInList(List<String> list, String value){ - if( !list.contains(value) ) - list.add(value); - return list; - } + /** + * Saves single response JSON data into the dictionary. + * @return The list of response data (dictionary). + */ + public List<String> OperationObject.writeDictionary(SchemaOb schema,String resp, List<String> dict)throws Exception{ + ObjectMapper mapper = new ObjectMapper(); + JsonNode respNode = mapper.readTree(resp); + String value; + + if (schema instanceof SchemaReference) { + for (PropertyItem p : schema.schemaObject().getPList()) { + String infName = ((SchemaReference) schema).getRef().substring(((SchemaReference) schema).getRef().lastIndexOf("/") + 1) + p.getName(); + value = respNode.get(p.getName()).toString().startsWith("\"") && + respNode.get(p.getName()).toString().endsWith("\"") ? + respNode.get(p.getName()).toString().substring(1, respNode.get(p.getName()).toString().length() - 1) : respNode.get(p.getName()).toString(); + + dict = root().addInList(dict, infName + "?" + value); + dict = root().addInList(dict, p.getName() + "?" + value); + } + } else { + for (PropertyItem p : schema.schemaObject().getPList()) { + value = respNode.get(p.getName()).toString().startsWith("\"") && + respNode.get(p.getName()).toString().endsWith("\"") ? + respNode.get(p.getName()).toString().substring(1, respNode.get(p.getName()).toString().length() - 1) : respNode.get(p.getName()).toString(); + + dict = root().addInList(dict, p.getName() + "?" + respNode.get(p.getName()).textValue()); + } + } + return dict; + } + + /** + * Saves array response JSON data into the dictionary. + * @return The list of response data (dictionary). + */ + public List<String> OperationObject.writeDictionaryWithArray(SchemaOb schema,String resp, List<String> dict)throws Exception{ + ObjectMapper mapper = new ObjectMapper(); + ArrayNode respNode = ((ArrayNode) mapper.readTree(resp)); + Iterator<JsonNode> props = respNode.elements(); + + while (props.hasNext()) + dict = writeDictionary(schema.schemaObject().getI().getSchema(), props.next().toString(), dict); + return dict; + } + + public List<String> OpenAPIObject.addInList(List<String> list, String value){ + if (!list.contains(value)) + list.add(value); + return list; + } } \ No newline at end of file diff --git a/src/main/jastadd/RandomRequestGenerator.jrag b/src/main/jastadd/RandomRequestGenerator.jrag index 51f96494000ffd66fc781b23673b926079d3fe63..b7ac53b558a68378cab3d5aae94c6e9e328ed8c8 100644 --- a/src/main/jastadd/RandomRequestGenerator.jrag +++ b/src/main/jastadd/RandomRequestGenerator.jrag @@ -3,192 +3,241 @@ import java.nio.charset.Charset; aspect RandomRequestGenerator{ - /** - * Calls <code>generateUrl()</code> for all paths. - * @return The list of String representing the generated URLs. - */ syn List<String> OpenAPIObject.generateRequests(){ - List<String> urls = new ArrayList<>(); - try { - for (PathsObject p : getPList()) - urls.addAll(p.generateUrl()); - } catch (Exception e) { - System.out.println(e.toString() + " at OpenAPIObject.generateRequests()"); - return null; + /** + * Calls <code>generateUrl()</code> for all paths. + * @return The list of String representing the generated URLs. + */ + syn List<String> OpenAPIObject.generateRequests(){ + List<String> urls = new ArrayList<>(); + try { + for (PathsObject p : getPList()) + urls.addAll(p.generateUrl()); + } catch (Exception e) { + System.out.println(e.toString() + " at OpenAPIObject.generateRequests()"); + return null; + } + return urls; } - return urls; - } - - /** - * Checks if a path has the request types <code>GET</code> and/or <code>POST</code>, and calls <code>generateRandomUrl(String pathRef)</code>. - * <p>Afterwards, generated URLs are saved in a list.</p> - * @return The list of String representing the generated URLs. - */ - inh List<String> PathsObject.generateUrl(); - eq OpenAPIObject.getP(int i).generateUrl(){ - List<String> urls = new ArrayList<>(); - try { - PathItemObject p = getP(i).getP().pathItemObject(); - String path = getServ(0).getUrl(); - if (getServ(0).getNumSt() != 0){ - for ( ServerVariablesTuple t : getServ(0).getStList() ) - path = path.replace("{" + t.getName() + "}", t.getS().getDefault()); - } - - if (p.hasG()) - urls.add(p.getG().generateRandomUrl(path + getP(i).getRef())); - if (p.hasPostOb()) - urls.add(p.getPostOb().generateRandomUrl(path + getP(i).getRef())); - - return urls; - } catch (Exception e) { - System.out.println(e.toString() + " at PathsObject.generateUrl()"); - return null; + + /** + * Checks if a path has the request types <code>GET</code> and/or <code>POST</code>, and calls <code>generateRandomUrl(String pathRef)</code>. + * <p>Afterwards, generated URLs are saved in a list.</p> + * @return The list of String representing the generated URLs. + */ + inh List<String> PathsObject.generateUrl(); + eq OpenAPIObject.getP(int i).generateUrl(){ + List<String> urls = new ArrayList<>(); + try { + PathItemObject p = getP(i).getP().pathItemObject(); + String path = getServ(0).getUrl(); + if (getServ(0).getNumSt() != 0) { + for (ServerVariablesTuple t : getServ(0).getStList()) + path = path.replace("{" + t.getName() + "}", t.getS().getDefault()); + } + + if (p.hasG()) + urls.add(p.getG().generateRandomUrl(path + getP(i).getRef())); + if (p.hasPostOb()) + urls.add(p.getPostOb().generateRandomUrl(path + getP(i).getRef())); + + return urls; + } catch (Exception e) { + System.out.println(e.toString() + " at PathsObject.generateUrl()"); + return null; + } } - } - - /** - * Checks which parameter types the targeted GET request has (Path or Query) and calls corresponding random parameter generator. - * <p>Afterwards, generated parameters are written in the url.</p> - * @return An URL with the generated parameters in String. - */ - syn String Get.generateRandomUrl(String pathRef){ - try { - for (ParameterOb o : getO().getPList()) { - ParameterObject p = o.parameterObject(); - if (p.getIn().equals("path")) - pathRef = p.randomPathParameter(pathRef); - else if (p.getIn().equals("query")) - pathRef = p.randomQueryParameter(pathRef); - } - if (pathRef.contains("&")) - pathRef = pathRef.replaceFirst("&", "?"); - System.out.println("Generated path : " + pathRef); - return pathRef; - } catch (Exception e) { - System.out.println(e.toString() + " at Get.generateRandomUrl(String pathRef)"); - return null; + + /** + * Checks which parameter types the targeted GET request has (Path or Query) and calls corresponding random parameter generator. + * <p>Afterwards, generated parameters are written in the url.</p> + * @return An URL with the generated parameters in String. + */ + syn String Get.generateRandomUrl(String pathRef){ + try { + for (ParameterOb o : getO().getPList()) { + ParameterObject p = o.parameterObject(); + if (p.getIn().equals("path")) + pathRef = p.randomPathParameter(pathRef); + else if (p.getIn().equals("query")) + pathRef = p.randomQueryParameter(pathRef); + } + if (pathRef.contains("&")) + pathRef = pathRef.replaceFirst("&", "?"); + System.out.println("Generated path : " + pathRef); + return pathRef; + } catch (Exception e) { + System.out.println(e.toString() + " at Get.generateRandomUrl(String pathRef)"); + return null; + } } - } - - /** - * Checks which parameter types the targeted POST request has (Path or Query) and calls corresponding random parameter generator. - * <p>Afterwards, generated parameters are written in the url.</p> - * @return An URL with the generated parameters in String. - */ - syn String Post.generateRandomUrl(String pathRef){ - try { - for (ParameterOb o : getO().getPList()) { - ParameterObject p = o.parameterObject(); - if (p.getIn().equals("path")) - pathRef = p.randomPathParameter(pathRef); - else if (p.getIn().equals("query")) - pathRef = p.randomQueryParameter(pathRef); - } - if (pathRef.contains("&")) - pathRef = pathRef.replaceFirst("&", "?"); - System.out.println("Generated path : " + pathRef); - return pathRef; - } catch (Exception e) { - System.out.println(e.toString() + " at Post.generateRandomUrl(String pathRef)"); - return null; + + /** + * Checks which parameter types the targeted POST request has (Path or Query) and calls corresponding random parameter generator. + * <p>Afterwards, generated parameters are written in the url.</p> + * @return An URL with the generated parameters in String. + */ + syn String Post.generateRandomUrl(String pathRef){ + try { + for (ParameterOb o : getO().getPList()) { + ParameterObject p = o.parameterObject(); + if (p.getIn().equals("path")) + pathRef = p.randomPathParameter(pathRef); + else if (p.getIn().equals("query")) + pathRef = p.randomQueryParameter(pathRef); + } + if (pathRef.contains("&")) + pathRef = pathRef.replaceFirst("&", "?"); + System.out.println("Generated path : " + pathRef); + return pathRef; + } catch (Exception e) { + System.out.println(e.toString() + " at Post.generateRandomUrl(String pathRef)"); + return null; + } } - } - - /** - * Checks which schema type the parameter has (String or Integer) and generates parameters. - * @return A generated Path parameter. - */ - syn String ParameterObject.randomPathParameter(String pathRef){ - SchemaObject s = getSchema().schemaObject(); - String pathPart = pathRef.substring(pathRef.indexOf("{"), pathRef.indexOf("}") + 1); - - if (s.getType().equals("string")) - pathRef = pathRef.replace(pathPart, generateRandomString(s.getEList())); - else if (s.getType().equals("integer")) - pathRef = pathRef.replace(pathPart, generateRandomInt( - -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, - 10 // s.getMaximum() != null ? s.getMaximum().intValue() : -1 - )); - return pathRef; - } - - /** - * Checks which schema type the parameter has (String or Integer) and generates parameters. - * @return A generated Query parameter. - */ - syn String ParameterObject.randomQueryParameter(String pathRef){ - SchemaObject s = getSchema().schemaObject(); - - if (s.getType().equals("string")) - pathRef = pathRef + "&" + getName() + "=" + generateRandomString(s.getEList()); - else if (s.getType().equals("integer")) - pathRef = pathRef + "&" + getName() + "=" + generateRandomInt( - -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, - 10); // s.getMaximum() != null ? s.getMaximum().intValue() : -1 - else if (s.getType().equals("array")) { - if (s.getI().getSchema().schemaObject().getType().equals("string")) { - for (EnumObj e : s.getI().getSchema().schemaObject().getEList()) - pathRef = pathWithEnum(e, pathRef); - } else if (s.getI().getSchema().schemaObject().getType().equals("integer")) { - for (int i = 0; i < 5; i++) - pathRef = pathRef + "&" + getName() + "=" + generateRandomInt( - -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, - 10); // s.getMaximum() != null ? s.getMaximum().intValue() : -1 - } + + /** + * Checks which schema type the parameter has (String or Integer) and generates parameters. + * @return A generated Path parameter. + */ + syn String ParameterObject.randomPathParameter(String pathRef){ + SchemaObject s = getSchema().schemaObject(); + String pathPart = pathRef.substring(pathRef.indexOf("{"), pathRef.indexOf("}") + 1); + + if (s.getType().equals("string")) + pathRef = pathRef.replace(pathPart, generateRandomString(s.getEList())); + else if (s.getType().equals("integer")) + pathRef = pathRef.replace(pathPart, generateRandomInt( + -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, + 10 // s.getMaximum() != null ? s.getMaximum().intValue() : -1 + )); + return pathRef; } - return pathRef; - } - - /** - * Generates a random String value. - * @return A random String. - */ - public String ParameterObject.generateRandomString(JastAddList<EnumObj> objs){ - Random rand = new Random(); - if (objs.getNumChild() != 0) - return URLEncoder.encode(objs.getChild(rand.nextInt(objs.getNumChild())).getEnumOb().toString(), Charset.forName("US-ASCII")); - - return rand - .ints(97, 123) - .limit(10) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - } - - /** - * Generates a random Integer value. - * @return A random Integer. - */ - public String ParameterObject.generateRandomInt(int minimum,int maximum){ - Random rand = new Random(); - if (minimum > -1 && maximum > 0) - return String.valueOf(rand.nextInt(minimum + maximum) - minimum); - else if (minimum > -1) - return String.valueOf(rand.nextInt() + minimum); - else if (maximum > 0) - return String.valueOf(rand.nextInt(maximum)); - return String.valueOf(rand.nextInt()); - } - - /** - * Generates a random value of Enum. - * @return A random value of Enum. - */ - public String ParameterObject.pathWithEnum(EnumObj e, String pathRef){ - Random rand = new Random(); - return rand.nextDouble() < 0.5 ? - pathRef + "&" + this.getName() + "=" + URLEncoder.encode(e.getEnumOb().toString(), Charset.forName("US-ASCII")) : pathRef; - } - - /** - * This is a method to avoid the duplication of Urls. - * @return The list of Urls. - */ - syn String OpenAPIObject.getURLFromGeneratedURLs(List<String> urls, String ref){ - for( String url : urls ){ - if( url.contains(ref) ) - return url; + + /** + * Checks which schema type the parameter has (String or Integer) and generates parameters. + * @return A generated Query parameter. + */ + syn String ParameterObject.randomQueryParameter(String pathRef){ + SchemaObject s = getSchema().schemaObject(); + + if (s.getType().equals("string")) + pathRef = pathRef + "&" + getName() + "=" + generateRandomString(s.getEList()); + else if (s.getType().equals("integer")) + pathRef = pathRef + "&" + getName() + "=" + generateRandomInt( + -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, + 10); // s.getMaximum() != null ? s.getMaximum().intValue() : -1 + else if (s.getType().equals("array")) { + if (s.getI().getSchema().schemaObject().getType().equals("string")) { + for (EnumObj e : s.getI().getSchema().schemaObject().getEList()) + pathRef = pathWithEnum(e, pathRef); + } else if (s.getI().getSchema().schemaObject().getType().equals("integer")) { + for (int i = 0; i < 5; i++) + pathRef = pathRef + "&" + getName() + "=" + generateRandomInt( + -1, // s.getMinimum() != null ? s.getMinimum().intValue() : -1, + 10); // s.getMaximum() != null ? s.getMaximum().intValue() : -1 + } + } + return pathRef; + } + + /** + * Generates parameters for all paths. + * @return The tuple (Map) representing the generated parameter values mapped into corresponding parameter names. + */ + public Map<String, List<Object>> OpenAPIObject.generateParameters() { + Map<String, List<Object>> parameters = new HashMap<>(); + ParameterObject o; + SchemaObject s; + + for (ParameterOb p : parameterObs()) { + List<Object> values = new ArrayList<>(); + o = p.parameterObject(); + s = o.getSchema().schemaObject(); + + if (s.getType().equals("string")) + values.add(o.generateRandomString(s.getEList())); + else if (s.getType().equals("integer")) + values.add(o.generateRandomInt(-1, 100)); // boundary at -1 and 100 + else if (s.getType().equals("array")) { + List<Object> arrayValues = new ArrayList<>(); + if (s.getI().getSchema().schemaObject().getType().equals("string")) { + for (EnumObj e : s.getI().getSchema().schemaObject().getEList()) + arrayValues.add(o.randomValueFromEnum(e)); + values.add(arrayValues); + } else if (s.getI().getSchema().schemaObject().getType().equals("integer")) { + for (int i = 0; i < 5; i++) + arrayValues.add(o.generateRandomInt(-1, 100)); + values.add(arrayValues); + } + } + + if( parameters.get(o.getName()) != null ) + values.addAll(parameters.get(o.getName())); + parameters.put(o.getName(), values); + } + + return parameters; + } + + /** + * Generates a random String value. + * @return A random String. + */ + public String ParameterObject.generateRandomString(JastAddList<EnumObj> objs){ + Random rand = new Random(); + if (objs.getNumChild() != 0) + return URLEncoder.encode(objs.getChild(rand.nextInt(objs.getNumChild())).getEnumOb().toString(), Charset.forName("US-ASCII")); + + return rand + .ints(97, 123) + .limit(10) + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) + .toString(); + } + + /** + * Generates a random Integer value. + * @return A random Integer. + */ + public String ParameterObject.generateRandomInt(int minimum,int maximum){ + Random rand = new Random(); + if (minimum > -1 && maximum > 0) + return String.valueOf(rand.nextInt(minimum + maximum) - minimum); + else if (minimum > -1) + return String.valueOf(rand.nextInt() + minimum); + else if (maximum > 0) + return String.valueOf(rand.nextInt(maximum)); + return String.valueOf(rand.nextInt()); + } + + /** + * Generates a random value of Enum. + * @return A random value of Enum. + */ + public String ParameterObject.pathWithEnum(EnumObj e, String pathRef){ + Random rand = new Random(); + return rand.nextDouble() < 0.5 ? + pathRef + "&" + this.getName() + "=" + URLEncoder.encode(e.getEnumOb().toString(), Charset.forName("US-ASCII")) : pathRef; + } + + /** + * Generates a random value of Enum. + * @return A random value of Enum. + */ + public String ParameterObject.randomValueFromEnum(EnumObj e){ + Random rand = new Random(); + return rand.nextDouble() < 0.5 ? URLEncoder.encode(e.getEnumOb().toString(), Charset.forName("US-ASCII")) : ""; + } + + /** + * This is a method to avoid the duplication of Urls. + * @return The list of Urls. + */ + syn String OpenAPIObject.getURLFromGeneratedURLs(List<String> urls, String ref){ + for (String url : urls) { + if (url.contains(ref)) + return url; + } + return ref; } - return ref; - } } \ No newline at end of file diff --git a/src/main/jastadd/Reference.jrag b/src/main/jastadd/Reference.jrag index ac5a211160f1f1dd954408972d617b5d04c5935a..6227600a22700d6ea7dcdd1275179517dfa1b81d 100644 --- a/src/main/jastadd/Reference.jrag +++ b/src/main/jastadd/Reference.jrag @@ -1,133 +1,137 @@ import java.util.*; aspect Reference { - inh OpenAPIObject ASTNode.root(); - eq OpenAPIObject.getChild().root() = this; + inh OpenAPIObject ASTNode.root(); + eq OpenAPIObject.getChild().root() = this; - coll List<SchemaTuple> OpenAPIObject.schemaTuples() [new ArrayList<>()] root OpenAPIObject; - SchemaTuple contributes this + coll List<SchemaTuple> OpenAPIObject.schemaTuples() [new ArrayList<>()] root OpenAPIObject; + SchemaTuple contributes this to OpenAPIObject.schemaTuples(); - coll List<ResponseTuple> OpenAPIObject.responseTuples() [new ArrayList<>()] root OpenAPIObject; - ResponseTuple contributes this + coll List<ResponseTuple> OpenAPIObject.responseTuples() [new ArrayList<>()] root OpenAPIObject; + ResponseTuple contributes this to OpenAPIObject.responseTuples(); - coll List<ParameterTuple> OpenAPIObject.parameterTuples() [new ArrayList<>()] root OpenAPIObject; - ParameterTuple contributes this + coll List<ParameterTuple> OpenAPIObject.parameterTuples() [new ArrayList<>()] root OpenAPIObject; + ParameterTuple contributes this to OpenAPIObject.parameterTuples(); - coll List<RequestBodyTuple> OpenAPIObject.requestBodyTuples() [new ArrayList<>()] root OpenAPIObject; - RequestBodyTuple contributes this + coll List<RequestBodyTuple> OpenAPIObject.requestBodyTuples() [new ArrayList<>()] root OpenAPIObject; + RequestBodyTuple contributes this to OpenAPIObject.requestBodyTuples(); - coll List<HeaderTuple> OpenAPIObject.headerTuples() [new ArrayList<>()] root OpenAPIObject; - HeaderTuple contributes this + coll List<HeaderTuple> OpenAPIObject.headerTuples() [new ArrayList<>()] root OpenAPIObject; + HeaderTuple contributes this to OpenAPIObject.headerTuples(); - coll List<SecuritySchemeTuple> OpenAPIObject.securitySchemeTuples() [new ArrayList<>()] root OpenAPIObject; - SecuritySchemeTuple contributes this + coll List<SecuritySchemeTuple> OpenAPIObject.securitySchemeTuples() [new ArrayList<>()] root OpenAPIObject; + SecuritySchemeTuple contributes this to OpenAPIObject.securitySchemeTuples(); - coll List<LinkTuple> OpenAPIObject.linkTuples() [new ArrayList<>()] root OpenAPIObject; - LinkTuple contributes this + coll List<LinkTuple> OpenAPIObject.linkTuples() [new ArrayList<>()] root OpenAPIObject; + LinkTuple contributes this to OpenAPIObject.linkTuples(); - coll List<CallbackTuple> OpenAPIObject.callbackTuples() [new ArrayList<>()] root OpenAPIObject; - CallbackTuple contributes this + coll List<CallbackTuple> OpenAPIObject.callbackTuples() [new ArrayList<>()] root OpenAPIObject; + CallbackTuple contributes this to OpenAPIObject.callbackTuples(); - coll List<PathItemTuple> OpenAPIObject.pathItemTuples() [new ArrayList<>()] root OpenAPIObject; - PathItemTuple contributes this + coll List<PathItemTuple> OpenAPIObject.pathItemTuples() [new ArrayList<>()] root OpenAPIObject; + PathItemTuple contributes this to OpenAPIObject.pathItemTuples(); - syn PathItemObject PathItemOb.pathItemObject(); - eq PathItemObject.pathItemObject() = this; - eq PathItemReference.pathItemObject() { - for (PathItemTuple t : root().pathItemTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().pathItemObject(); - } - return new PathItemObject(); - } - - syn ParameterObject ParameterOb.parameterObject(); - eq ParameterObject.parameterObject() = this; - eq ParameterReference.parameterObject() { - for (ParameterTuple t : root().parameterTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().parameterObject(); + coll List<ParameterOb> OpenAPIObject.parameterObs() [new ArrayList<>()] root OpenAPIObject; + ParameterOb contributes this + to OpenAPIObject.parameterObs(); + + syn PathItemObject PathItemOb.pathItemObject(); + eq PathItemObject.pathItemObject() = this; + eq PathItemReference.pathItemObject() { + for (PathItemTuple t : root().pathItemTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().pathItemObject(); + } + return new PathItemObject(); } - return new ParameterObject(); - } - - syn SchemaObject SchemaOb.schemaObject(); - eq SchemaObject.schemaObject() = this; - eq SchemaReference.schemaObject() { - for (SchemaTuple t : root().schemaTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().schemaObject(); + + syn ParameterObject ParameterOb.parameterObject(); + eq ParameterObject.parameterObject() = this; + eq ParameterReference.parameterObject() { + for (ParameterTuple t : root().parameterTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().parameterObject(); + } + return new ParameterObject(); } - return new SchemaObject(); - } - - syn RequestBodyObject RequestBodyOb.requestBodyObject(); - eq RequestBodyObject.requestBodyObject() = this; - eq RequestBodyReference.requestBodyObject() { - for (RequestBodyTuple t : root().requestBodyTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().requestBodyObject(); + + syn SchemaObject SchemaOb.schemaObject(); + eq SchemaObject.schemaObject() = this; + eq SchemaReference.schemaObject() { + for (SchemaTuple t : root().schemaTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().schemaObject(); + } + return new SchemaObject(); } - return new RequestBodyObject(); - } - - syn ResponseObject ResponseOb.responseObject(); - eq ResponseObject.responseObject() = this; - eq ResponseReference.responseObject() { - for (ResponseTuple t : root().responseTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().responseObject(); + + syn RequestBodyObject RequestBodyOb.requestBodyObject(); + eq RequestBodyObject.requestBodyObject() = this; + eq RequestBodyReference.requestBodyObject() { + for (RequestBodyTuple t : root().requestBodyTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().requestBodyObject(); + } + return new RequestBodyObject(); } - return new ResponseObject(); - } - - syn CallbackObject CallbackOb.callbackObject(); - eq CallbackObject.callbackObject() = this; - eq CallbackReference.callbackObject() { - for (CallbackTuple t : root().callbackTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().callbackObject(); + + syn ResponseObject ResponseOb.responseObject(); + eq ResponseObject.responseObject() = this; + eq ResponseReference.responseObject() { + for (ResponseTuple t : root().responseTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().responseObject(); + } + return new ResponseObject(); } - return new CallbackObject(); - } - - syn LinkObject LinkOb.linkObject(); - eq LinkObject.linkObject() = this; - eq LinkReference.linkObject() { - for (LinkTuple t : root().linkTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().linkObject(); + + syn CallbackObject CallbackOb.callbackObject(); + eq CallbackObject.callbackObject() = this; + eq CallbackReference.callbackObject() { + for (CallbackTuple t : root().callbackTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().callbackObject(); + } + return new CallbackObject(); } - return new LinkObject(); - } - - syn HeaderObject HeaderOb.headerObject(); - eq HeaderObject.headerObject() = this; - eq HeaderReference.headerObject() { - for (HeaderTuple t : root().headerTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().headerObject(); + + syn LinkObject LinkOb.linkObject(); + eq LinkObject.linkObject() = this; + eq LinkReference.linkObject() { + for (LinkTuple t : root().linkTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().linkObject(); + } + return new LinkObject(); + } + + syn HeaderObject HeaderOb.headerObject(); + eq HeaderObject.headerObject() = this; + eq HeaderReference.headerObject() { + for (HeaderTuple t : root().headerTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().headerObject(); + } + return new HeaderObject(); } - return new HeaderObject(); - } - - syn SecuritySchemeObject SecuritySchemeOb.securitySchemeObject(); - eq SecuritySchemeObject.securitySchemeObject() = this; - eq SecuritySchemeReference.securitySchemeObject() { - for (SecuritySchemeTuple t : root().securitySchemeTuples()) { - if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) - return t.getO().securitySchemeObject(); + + syn SecuritySchemeObject SecuritySchemeOb.securitySchemeObject(); + eq SecuritySchemeObject.securitySchemeObject() = this; + eq SecuritySchemeReference.securitySchemeObject() { + for (SecuritySchemeTuple t : root().securitySchemeTuples()) { + if (t.getKey().equals(getRef().substring(getRef().lastIndexOf("/") + 1, getRef().length()))) + return t.getO().securitySchemeObject(); + } + return new SecuritySchemeObject(); } - return new SecuritySchemeObject(); - } } \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java b/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java index b019b9a24c8faf439a1fce8845c02c685f85b246..1df9551a46c41603444bcb4de3fe3823812bcbba 100644 --- a/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java +++ b/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java @@ -10,7 +10,9 @@ import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class OpenAPIMain { static List<String> successfulUrls = new ArrayList<>(); @@ -19,7 +21,7 @@ public class OpenAPIMain { * main-method, calls the set of methods to test the OpenAPI-Generator with JastAdd **/ public static void main(String[] args) throws Exception { - String fileName = "./src/main/resources/APIs/1password.local/connect/1.3.0/openapi.yaml"; + String fileName = "./src/main/resources/3.0/petstore-v2.yaml"; OpenAPIObject jastAddObject; SwaggerParseResult result = new OpenAPIParser().readLocation(fileName, null, null); OpenAPI openAPI = result.getOpenAPI(); @@ -28,6 +30,8 @@ public class OpenAPIMain { jastAddObject = OpenAPIObject.parseOpenAPI(openAPI); + jastAddObject.generateParameters(); + generatedURLs = jastAddObject.generateRequests(); dictionary = sendRandomRequests(jastAddObject, generatedURLs); @@ -51,6 +55,8 @@ public class OpenAPIMain { System.out.println("Loading expression DSL file '" + fileName + "'."); + Map<Object, Object> parameters = new HashMap<>(); + if (args.length > 0) { fileName = args[0]; } diff --git a/src/test/java/openapi/OpenAPIMain_test.java b/src/test/java/openapi/OpenAPIMain_test.java index 20ab2eec0faf83af265f61728a4c33831ab2cd5b..c4dffa456a4dceefdcfb27332f8d23dfa6f7ec25 100644 --- a/src/test/java/openapi/OpenAPIMain_test.java +++ b/src/test/java/openapi/OpenAPIMain_test.java @@ -16,12 +16,9 @@ import org.apache.commons.validator.routines.UrlValidator; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import java.io.File; import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.Charset; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -30,122 +27,126 @@ import java.util.stream.Stream; public class OpenAPIMain_test { - static List<File> resources = new ArrayList<>(); - - @BeforeAll - static void init() { - File r = new File("./src/main/resources"); - initResources(r); - } - - @MethodSource("resources") - @ParameterizedTest - void parserTest(File file) throws Exception { - OpenAPIObject jastAddObject; - OpenAPI POJOOpenAPI; - ObjectMapper mapper = new ObjectMapper(); - List<String> validation; - - // parse OpenAPI in POJO, parse Json by POJO and validate OpenAPI-Json - SwaggerParseResult result = new OpenAPIParser().readLocation(file.getPath(), null, null); - POJOOpenAPI = result.getOpenAPI(); - System.out.println("Loading expression DSL file '" + file + "'."); - JsonNode expectedNode = mapper.readTree(Json.mapper().writeValueAsString(POJOOpenAPI)); - validation = new OpenAPIV3Parser().readContents(expectedNode.toString()).getMessages(); - - Assertions.assertFalse(validation.size() != 0, "validation of the input yaml not succeeded"); - - // parse OpenAPI in JastAdd, transform it to OpenAPI-POJO back and validate this - jastAddObject = OpenAPIObject.parseOpenAPI(POJOOpenAPI); - OpenAPI transformedAPI = OpenAPIObject.reverseOpenAPI(jastAddObject); - JsonNode actualNode = mapper.readTree(Json.mapper().writeValueAsString(transformedAPI)); - validation = new OpenAPIV3Parser().readContents(actualNode.toString()).getMessages(); - - Assertions.assertFalse(validation.size() != 0, "validation of the transformed yaml not succeeded"); - - // compare if parsed OpenAPI (source object, Json) is equivalent to back-transformed OpenAPI (generated object, Json) - compareJson(expectedNode, actualNode, Paths.get(file.getPath())); - } - - @MethodSource("resources") - @ParameterizedTest - void RandomUrlTest(File file) throws Exception { - OpenAPIObject jastAddObject; - OpenAPI POJOOpenAPI; - List<String> urls; - UrlValidator urlValidator = new UrlValidator(); - - SwaggerParseResult result = new OpenAPIParser().readLocation(file.getPath(), null, null); - POJOOpenAPI = result.getOpenAPI(); - System.out.println("Loading expression DSL file '" + file + "'."); - - jastAddObject = OpenAPIObject.parseOpenAPI(POJOOpenAPI); - urls = jastAddObject.generateRequests(); - - for ( String url : urls ) - Assertions.assertTrue(urlValidator.isValid(url), "validation of " + url + " not succeeded"); - } - - static Stream<File> resources() { - return resources.stream(); - } - - static void compareJson(JsonNode expectedNode, JsonNode actualNode, Path path) throws IOException { - JsonNode diff = JsonDiff.asJson(expectedNode, actualNode); - String pathNode; - String result = ""; - - for (int i = diff.size() - 1; i >= 0; i--) { - // get the path of a node involving difference. - pathNode = "$" + diff.get(i).get("path").toString(); - for (String s : pathNode.split("/")) { - if (s.contains(".")) - pathNode = pathNode.replace(s, "['" + s + "']"); - else if (s.contains(" ")) - pathNode = pathNode.replace(s, "['" + s + "']"); - } - pathNode = pathNode - .replace("/", ".") - .replace("~1", "/") - .replace("\"", ""); - for (String s : pathNode.split("\\.")) { - if ( !s.contains("['") && isNumeric(s) && Integer.parseInt(s) < 200) - result = result.concat("[" + s + "]."); - else - result = result.concat(s + "."); - } - pathNode = result.substring(0, result.length()-1); - - // check, if this node is null or has an empty value. - if (JsonPath.parse(expectedNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(expectedNode.toString()).read(pathNode, String.class).isEmpty()) - ((ArrayNode) diff).remove(i); - else if (JsonPath.parse(actualNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(actualNode.toString()).read(pathNode, String.class).isEmpty()) - ((ArrayNode) diff).remove(i); - - result = ""; + static List<File> resources = new ArrayList<>(); + + @BeforeAll + static void init() { + File r = new File("./src/main/resources"); + initResources(r); + } + + @MethodSource("resources") + @ParameterizedTest + void parserTest(File file) throws Exception { + OpenAPIObject jastAddObject; + OpenAPI POJOOpenAPI; + ObjectMapper mapper = new ObjectMapper(); + List<String> validation; + + // parse OpenAPI in POJO, parse Json by POJO and validate OpenAPI-Json + SwaggerParseResult result = new OpenAPIParser().readLocation(file.getPath(), null, null); + POJOOpenAPI = result.getOpenAPI(); + System.out.println("Loading expression DSL file '" + file + "'."); + JsonNode expectedNode = mapper.readTree(Json.mapper().writeValueAsString(POJOOpenAPI)); + validation = new OpenAPIV3Parser().readContents(expectedNode.toString()).getMessages(); + + Assertions.assertFalse(validation.size() != 0, "validation of the input yaml not succeeded"); + + // parse OpenAPI in JastAdd, transform it to OpenAPI-POJO back and validate this + jastAddObject = OpenAPIObject.parseOpenAPI(POJOOpenAPI); + OpenAPI transformedAPI = OpenAPIObject.reverseOpenAPI(jastAddObject); + JsonNode actualNode = mapper.readTree(Json.mapper().writeValueAsString(transformedAPI)); + validation = new OpenAPIV3Parser().readContents(actualNode.toString()).getMessages(); + + Assertions.assertFalse(validation.size() != 0, "validation of the transformed yaml not succeeded"); + + // compare if parsed OpenAPI (source object, Json) is equivalent to back-transformed OpenAPI (generated object, Json) + compareJson(expectedNode, actualNode, Paths.get(file.getPath())); + } + + @MethodSource("resources") + @ParameterizedTest + void RandomUrlTest(File file) throws Exception { + OpenAPIObject jastAddObject; + OpenAPI POJOOpenAPI; + List<String> urls; + UrlValidator urlValidator = new UrlValidator(); + + SwaggerParseResult result = new OpenAPIParser().readLocation(file.getPath(), null, null); + POJOOpenAPI = result.getOpenAPI(); + System.out.println("Loading expression DSL file '" + file + "'."); + + jastAddObject = OpenAPIObject.parseOpenAPI(POJOOpenAPI); + urls = jastAddObject.generateRequests(); + + for (String url : urls) + Assertions.assertTrue(urlValidator.isValid(url), "validation of " + url + " not succeeded"); + } + + static Stream<File> resources() { + return resources.stream(); + } + + static void compareJson(JsonNode expectedNode, JsonNode actualNode, Path path) throws IOException { + JsonNode diff = JsonDiff.asJson(expectedNode, actualNode); + String pathNode; + String result = ""; + + for (int i = diff.size() - 1; i >= 0; i--) { + // get the path of a node involving difference. + pathNode = "$" + diff.get(i).get("path").toString(); + for (String s : pathNode.split("/")) { + if (s.contains(".")) + pathNode = pathNode.replace(s, "['" + s + "']"); + else if (s.contains(" ")) + pathNode = pathNode.replace(s, "['" + s + "']"); + } + pathNode = pathNode + .replace("/", ".") + .replace("~1", "/") + .replace("\"", ""); + for (String s : pathNode.split("\\.")) { + if (!s.contains("['") && isNumeric(s) && Integer.parseInt(s) < 200) + result = result.concat("[" + s + "]."); + else + result = result.concat(s + "."); + } + pathNode = result.substring(0, result.length() - 1); + + // check, if this node is null or has an empty value. + if (JsonPath.parse(expectedNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(expectedNode.toString()).read(pathNode, String.class).isEmpty()) + ((ArrayNode) diff).remove(i); + else if (JsonPath.parse(actualNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(actualNode.toString()).read(pathNode, String.class).isEmpty()) + ((ArrayNode) diff).remove(i); + + result = ""; + } + + // if the Jsons are equivalent, there is no reason to to the text comparison. + // if there is a difference, a text comparison might look better than just the diff. + if (diff.size() != 0) { + Assertions.assertEquals(actualNode.toPrettyString(), expectedNode.toPrettyString(), "JSONs for " + path + " are different:\n" + diff.toPrettyString()); + } + } + + static boolean isNumeric(String str) { + try { + int d = Integer.parseInt(str); + } catch (NumberFormatException nfe) { + return false; + } + return true; } - // if the Jsons are equivalent, there is no reason to to the text comparison. - // if there is a difference, a text comparison might look better than just the diff. - if (diff.size() != 0) { - Assertions.assertEquals(actualNode.toPrettyString(), expectedNode.toPrettyString(), "JSONs for " + path + " are different:\n" + diff.toPrettyString()); + static boolean isAlphaNumeric(String s) { + return s != null && s.matches("^[a-zA-Z0-9]*$"); } - } - static boolean isNumeric(String str) { - try { - int d = Integer.parseInt(str); - } catch (NumberFormatException nfe) { - return false; + static void initResources(File file) { + if (file.isDirectory()) { + for (File f : file.listFiles()) + initResources(f); + } else if (file.isFile() && file.getPath().contains("yaml")) + resources.add(file); } - return true; - } - - static void initResources(File file) { - if ( file.isDirectory() ) { - for ( File f : file.listFiles() ) - initResources(f); - } else if ( file.isFile() && file.getPath().contains("yaml") ) - resources.add(file); - } } \ No newline at end of file