Added test cases for WSDL and OpenAPI, OpenAPI is currently failing

This commit is contained in:
Ziver Koc 2021-02-28 22:50:15 +01:00
parent 5622a3b489
commit 02e91a38e9
7 changed files with 293 additions and 40 deletions

View file

@ -181,16 +181,16 @@ public class WSMethodDef {
} else {
// Specific request type was not provided, try to figure it out by the method name
if (name.startsWith("get"))
this.requestType = WSInterface.RequestType.GET;
if (name.startsWith("post"))
this.requestType = WSInterface.RequestType.POST;
if (name.startsWith("put"))
else if (name.startsWith("put"))
this.requestType = WSInterface.RequestType.PUT;
if (name.startsWith("delete"))
else if (name.startsWith("delete"))
this.requestType = WSInterface.RequestType.DELETE;
if (name.startsWith("patch"))
else if (name.startsWith("patch"))
this.requestType = WSInterface.RequestType.PATCH;
else
this.requestType = WSInterface.RequestType.GET;
}
// Handle endpoint path
@ -201,8 +201,8 @@ public class WSMethodDef {
else
path = this.name;
if (path.startsWith("/"))
path = path.substring(1);
if (!path.startsWith("/"))
path = '/' + path;
}
/**

View file

@ -12,7 +12,9 @@ import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
@ -58,12 +60,14 @@ public class OpenAPIWriter {
public String write() {
if (cache == null) {
Map<String, List<WSParameterDef>> schemas = new HashMap<>();
DataNode root = new DataNode(DataNode.DataType.Map);
root.set("openapi", OPENAPI_VERSION);
root.set("info", generateInfo());
root.set("servers", generateServers());
root.set("paths", generatePaths());
root.set("components", generateComponents());
root.set("paths", generatePaths(schemas));
root.set("components", generateComponents(schemas));
this.cache = JSONWriter.toString(root);
}
@ -74,12 +78,12 @@ public class OpenAPIWriter {
DataNode infoRoot = new DataNode(DataNode.DataType.Map);
infoRoot.set("title", ws.getName());
infoRoot.set("description", ws.getDocumentation());
infoRoot.set("version", "");
// Not implemented properties
// "termsOfService": xxx,
// "contact": {"name": xxx,"url": xxx,"email": xxx},
// "license": {"name": xxx, "url": xxx},
// "version": xxx
return infoRoot;
}
@ -87,30 +91,28 @@ public class OpenAPIWriter {
DataNode serversRoot = new DataNode(DataNode.DataType.List);
for (ServerData data : servers) {
DataNode serverNode = new DataNode(DataNode.DataType.Map);
DataNode serverNode = serversRoot.add(DataNode.DataType.Map);
serverNode.set("url", data.url);
serverNode.set("description", data.description);
serversRoot.add(serverNode);
}
return serversRoot;
}
private DataNode generatePaths() {
private DataNode generatePaths(Map<String, List<WSParameterDef>> schemas) {
DataNode pathsRoot = new DataNode(DataNode.DataType.Map);
for (WSMethodDef methodDef : ws.getMethods()) {
DataNode pathNode = new DataNode(DataNode.DataType.Map);
DataNode pathNode = pathsRoot.set(methodDef.getPath(), DataNode.DataType.Map);
DataNode typeNode = new DataNode(DataNode.DataType.Map);
DataNode typeNode = pathNode.set(methodDef.getRequestType().toString().toLowerCase(), DataNode.DataType.Map);
typeNode.set("description", methodDef.getDocumentation());
pathNode.set(methodDef.getRequestType().toString().toLowerCase(), typeNode);
// --------------------------------------------
// Inputs
// --------------------------------------------
DataNode parameterNode = new DataNode(DataNode.DataType.Map);
DataNode parameterNode = typeNode.set("parameters", DataNode.DataType.Map);
for (WSParameterDef parameterDef : methodDef.getInputs()) {
parameterNode.set("name", parameterDef.getName());
parameterNode.set("description", parameterDef.getDocumentation());
@ -119,29 +121,27 @@ public class OpenAPIWriter {
parameterNode.set("schema", "");
}
typeNode.set("parameters", parameterNode);
// --------------------------------------------
// Outputs
// --------------------------------------------
DataNode responseNode = new DataNode(DataNode.DataType.Map);
for (WSParameterDef parameterDef : methodDef.getOutputs()) {
parameterNode.set("name", parameterDef.getName());
parameterNode.set("description", parameterDef.getDocumentation());
parameterNode.set("in", "query");
parameterNode.set("required", parameterDef.isOptional());
DataNode responseNode = typeNode.set("responses", DataNode.DataType.Map);
DataNode schemaNode = responseNode.set("200", DataNode.DataType.Map)
.set("content", DataNode.DataType.Map)
.set("application/json", DataNode.DataType.Map)
.set("schema", DataNode.DataType.Map);
parameterNode.set("schema", "");
}
typeNode.set("responses", responseNode);
String retName = methodDef.getName() + "Return";
schemas.put("retName", methodDef.getOutputs());
schemaNode.set("$ref", "#/components/schemas/" + retName);
}
return pathsRoot;
}
private DataNode generateComponents() {
private DataNode generateComponents(Map<String, List<WSParameterDef>> schemas) {
DataNode componentsRoot = new DataNode(DataNode.DataType.Map);
DataNode schemasNode = new DataNode(DataNode.DataType.Map);
componentsRoot.set("schemas", schemasNode);

View file

@ -313,7 +313,9 @@ public class WSDLWriter {
empty.addAttribute("name", "empty");
empty.addElement("xsd:sequence");
for (Class<?> c : types) {
for (int i=0; i<types.size(); i++) {
Class<?> c = types.get(i);
// Generate Array type
if (c.isArray()) {
Class<?> ctmp = ClassUtil.getArrayClass(c);
@ -344,26 +346,26 @@ public class WSDLWriter {
Element sequence = type.addElement("xsd:sequence");
Field[] fields = c.getFields();
for (int i = 0; i < fields.length; i++) {
WSInterface.WSParamName tmp = fields[i].getAnnotation(WSInterface.WSParamName.class);
for (int j=0; j<fields.length; j++) {
WSInterface.WSParamName tmp = fields[j].getAnnotation(WSInterface.WSParamName.class);
String name;
if (tmp != null)
name = tmp.value();
else
name = "field" + i;
name = "field" + j;
Element element = sequence.addElement("xsd:element");
element.addAttribute("name", name);
// Check if the object is an SOAPObject
Class<?> cTmp = ClassUtil.getArrayClass(fields[i].getType());
Class<?> cTmp = ClassUtil.getArrayClass(fields[j].getType());
if (WSReturnObject.class.isAssignableFrom(cTmp)) {
element.addAttribute("type", "tns:" + SOAPHttpPage.getSOAPClassName(cTmp));
if (!types.contains(cTmp))
types.add(cTmp);
} else {
element.addAttribute("type", "xsd:" + SOAPHttpPage.getSOAPClassName(fields[i].getType()));
element.addAttribute("type", "xsd:" + SOAPHttpPage.getSOAPClassName(fields[j].getType()));
}
// Is the Field optional

View file

@ -182,7 +182,19 @@ public class DataNode implements Iterable<DataNode> {
}
/**
* Adds a node to the Map
* Creates a new node and adds it to the list.
*
* @param type the type of the new DataNode
* @return a newly created DataNode
*/
public DataNode add(DataType type) {
DataNode newNode = new DataNode(type);
list.add(newNode);
return newNode;
}
/**
* Adds a node to the Map with the provided value
*/
public void set(String key, DataNode node) {
map.put(key, node);
@ -208,6 +220,20 @@ public class DataNode implements Iterable<DataNode> {
map.put(key, new DataNode(value));
}
/**
* Creates a new node and adds it to the specified key.
*
* @param key the key where the new DataNode should be assigned
* @param type the type of the new DataNode
* @return a newly created DataNode
*/
public DataNode set(String key, DataType type) {
DataNode newNode = new DataNode(type);
map.put(key, newNode);
return newNode;
}
/**
* Sets the value of the node
*

View file

@ -0,0 +1,42 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zutil.net.ws.openapi;
import org.junit.Test;
import zutil.net.ws.WebServiceDef;
import zutil.net.ws.soap.SOAPTest;
import static org.junit.Assert.assertEquals;
public class OpenAPIWriterTest {
@Test
public void basicTest() {
OpenAPIWriter writer = new OpenAPIWriter(new WebServiceDef(SOAPTest.MainSOAPClass.class));
writer.addServer("example.com", "Main Server");
assertEquals("", writer.write());
}
}

View file

@ -29,6 +29,7 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import zutil.net.ws.WSInterface;
import zutil.net.ws.WSInterface.WSNamespace;
import zutil.net.ws.WSInterface.WSParamName;
import zutil.net.ws.WSReturnObject;
import zutil.net.ws.WebServiceDef;
import zutil.net.ws.wsdl.WSDLWriter;
@ -36,7 +37,11 @@ import zutil.net.ws.wsdl.WSDLWriter;
// TODO: Convert to JUnit
public class SOAPTest {
/************************* TEST CASES ************************/
// ----------------------------------------------------
// TEST CASES
// ----------------------------------------------------
public static void main(String[] args){
WebServiceDef wsDef = new WebServiceDef( MainSOAPClass.class );
SOAPHttpPage soap = new SOAPHttpPage( wsDef );
@ -75,12 +80,15 @@ public class SOAPTest {
}
}
/************************* TEST CLASSES ************************/
// ----------------------------------------------------
// TEST CLASSES
// ----------------------------------------------------
@SuppressWarnings("unused")
public static class SpecialReturnClass extends WSReturnObject{
@WSValueName(value="otherValue1")
@WSParamName("otherValue1")
public String param1 = "otherValue1";
@WSValueName("otherName2")
@WSParamName("otherName2")
public String param2 = "otherValue2";
public byte[] b = new byte[]{0x12, 0x23};
public InnerClass inner = new InnerClass();
@ -94,7 +102,7 @@ public class SOAPTest {
@SuppressWarnings("unused")
public static class SimpleReturnClass extends WSReturnObject{
@WSValueName("otherParam1")
@WSParamName("otherParam1")
public String param1 = "param1";
public String param2 = "param2";
}

View file

@ -0,0 +1,175 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zutil.net.ws.wsdl;
import org.junit.Test;
import zutil.net.ws.WebServiceDef;
import zutil.net.ws.soap.SOAPTest;
import static org.junit.Assert.assertEquals;
public class WSDLWriterTest {
@Test
public void basicTest() {
WSDLWriter writer = new WSDLWriter(new WebServiceDef(SOAPTest.MainSOAPClass.class));
writer.addService(new WSDLServiceSOAP("example.com"));
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"\n" +
"<wsdl:definitions xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://test.se:8080/?type\" targetNamespace=\"http://test.se:8080/\">\n" +
" <wsdl:types>\n" +
" <xsd:schema targetNamespace=\"http://test.se:8080/?type\">\n" +
" <xsd:complexType name=\"empty\">\n" +
" <xsd:sequence/>\n" +
" </xsd:complexType>\n" +
" <xsd:complexType name=\"ArrayOfstring\">\n" +
" <xsd:sequence>\n" +
" <xsd:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\"element\" nillable=\"true\" type=\"xsd:string\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
" <xsd:complexType name=\"ArrayOfSpecialReturnClass\">\n" +
" <xsd:sequence>\n" +
" <xsd:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\"element\" nillable=\"true\" type=\"tns:SpecialReturnClass\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
" <xsd:complexType name=\"SpecialReturnClass\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"otherValue1\" type=\"xsd:string\"/>\n" +
" <xsd:element name=\"otherName2\" type=\"xsd:string\"/>\n" +
" <xsd:element name=\"field2\" type=\"xsd:base64Binary\"/>\n" +
" <xsd:element name=\"field3\" type=\"tns:InnerClass\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
" <xsd:complexType name=\"InnerClass\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"field0\" type=\"xsd:string\"/>\n" +
" <xsd:element name=\"field1\" type=\"xsd:string\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
" </xsd:schema>\n" +
" </wsdl:types>\n" +
" <wsdl:message name=\"stringArrayMethodRequest\">\n" +
" <wsdl:part name=\"StringName\" type=\"xsd:string\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"stringArrayMethodResponse\">\n" +
" <wsdl:part name=\"stringArray\" type=\"td:ArrayOfstring\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"simpleReturnClassMethodRequest\">\n" +
" <wsdl:part name=\"byte\" type=\"xsd:string\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"simpleReturnClassMethodResponse\">\n" +
" <wsdl:part name=\"otherParam1\" type=\"xsd:string\"/>\n" +
" <wsdl:part name=\"param2\" type=\"xsd:string\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"exceptionMethodRequest\">\n" +
" <wsdl:part name=\"otherParam1\" type=\"xsd:int\" minOccurs=\"0\"/>\n" +
" <wsdl:part name=\"otherParam2\" type=\"xsd:int\" minOccurs=\"0\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"specialReturnMethodRequest\">\n" +
" <wsdl:part name=\"StringName2\" type=\"xsd:string\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"specialReturnMethodResponse\">\n" +
" <wsdl:part name=\"specialReturnClass\" type=\"td:ArrayOfSpecialReturnClass\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"empty\">\n" +
" <wsdl:part name=\"empty\" type=\"td:empty\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:message name=\"exception\">\n" +
" <wsdl:part name=\"exception\" type=\"td:string\"/>\n" +
" </wsdl:message>\n" +
" <wsdl:portType name=\"MainSOAPClassPortType\">\n" +
" <wsdl:operation name=\"stringArrayMethod\">\n" +
" <wsdl:input message=\"tns:stringArrayMethodRequest\"/>\n" +
" <wsdl:output message=\"tns:stringArrayMethodResponse\"/>\n" +
" <wsdl:fault message=\"tns:exception\"/>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"simpleReturnClassMethod\">\n" +
" <wsdl:input message=\"tns:simpleReturnClassMethodRequest\"/>\n" +
" <wsdl:output message=\"tns:simpleReturnClassMethodResponse\"/>\n" +
" <wsdl:fault message=\"tns:exception\"/>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"exceptionMethod\">\n" +
" <wsdl:documentation>Documentation of method exceptionMethod()</wsdl:documentation>\n" +
" <wsdl:input message=\"tns:exceptionMethodRequest\"/>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"specialReturnMethod\">\n" +
" <wsdl:input message=\"tns:specialReturnMethodRequest\"/>\n" +
" <wsdl:output message=\"tns:specialReturnMethodResponse\"/>\n" +
" <wsdl:fault message=\"tns:exception\"/>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"voidMethod\"/>\n" +
" </wsdl:portType>\n" +
" <wsdl:binding name=\"MainSOAPClassBinding\" type=\"tns:MainSOAPClassPortType\">\n" +
" <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n" +
" <wsdl:operation name=\"stringArrayMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"simpleReturnClassMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"exceptionMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#exceptionMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#exceptionMethod\"/>\n" +
" </wsdl:input>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"specialReturnMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"voidMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#voidMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#voidMethod\"/>\n" +
" </wsdl:input>\n" +
" </wsdl:operation>\n" +
" </wsdl:binding>\n" +
" <wsdl:service name=\"MainSOAPClassService\">\n" +
" <wsdl:port name=\"MainSOAPClassPort\" binding=\"tns:MainSOAPClassBinding\">\n" +
" <soap:address location=\"example.com\"/>\n" +
" </wsdl:port>\n" +
" </wsdl:service>\n" +
"</wsdl:definitions>\n",
writer.write());
}
}