diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java new file mode 100644 index 000000000..4f389f4ab --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java @@ -0,0 +1,212 @@ +package com.predic8.membrane.core.interceptor.soap; + +import com.predic8.membrane.annot.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import org.w3c.dom.*; + +import javax.xml.parsers.*; +import javax.xml.stream.*; +import javax.xml.stream.events.*; +import javax.xml.transform.*; +import java.io.*; +import java.util.*; +import java.util.regex.Pattern; + +import static com.predic8.membrane.core.Constants.*; +import static com.predic8.membrane.core.http.Header.CONTENT_TYPE; +import static com.predic8.membrane.core.http.MimeType.*; +import static com.predic8.membrane.core.http.Response.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; +import static com.predic8.membrane.core.openapi.util.Utils.*; +import static com.predic8.membrane.core.util.XMLUtil.*; +import static javax.xml.stream.XMLStreamConstants.*; + +@MCElement(name = "sampleSoapService") +public class SampleSoapServiceInterceptor extends AbstractInterceptor { + + public static final Pattern WSDL_PATH_PARAM = Pattern.compile("(?i).+\\?.*wsdl.*"); + public static final String CITY_SERVICE_NS = "https://predic8.de/city-service"; + + public SampleSoapServiceInterceptor() { + name = "SampleSoapService"; + } + + @Override + public Outcome handleRequest(Exchange exc) throws Exception { + if (isWSDLRequest(exc)) { + exc.setResponse(createWSDLResponse(exc)); + } else if(!exc.getRequest().isPOSTRequest()) { + exc.setResponse(createMethodNotAllowedSOAPFault()); + } else { + try { + exc.setResponse(createGetCityResponse(exc)); + } catch (Exception e) { + exc.setResponse(createResourceNotFoundSOAPFault()); + } + } + return RETURN; + } + + private static Response createResourceNotFoundSOAPFault() throws Exception { + return ok(getSoapFault("Resource Not Found", "404", "Cannot parse SOAP message. Request should contain e.g. Bonn")).contentType(APPLICATION_XML).build(); + } + + private static Response createGetCityResponse(Exchange exc) throws Exception { + return ok(getResponse(getCity(exc))).contentType(TEXT_XML).build(); + } + + private static Response createMethodNotAllowedSOAPFault() throws Exception { + return ok(getSoapFault("Method Not Allowed", "405", "Use POST to access the service.")).contentType(APPLICATION_XML).build(); + } + + private Response createWSDLResponse(Exchange exc) throws XMLStreamException { + return ok().header(CONTENT_TYPE, TEXT_XML_UTF8) + .body(setWsdlServer( + getResourceAsStream(this,"/wsdl/city.wsdl"),exc) + ).build(); + } + + + static boolean isWSDLRequest(Exchange exc) { + return WSDL_PATH_PARAM.matcher(exc.getRequest().getUri()).matches(); + } + + private static String getCity(Exchange exc) throws Exception { + return getElementAsString(exc.getRequest().getBodyAsStream(), "name"); + } + + private static final HashMap cityMap = new HashMap<>() {{ + put("Bonn", new City("Bonn", 327_000, "Germany")); + put("Bielefeld", new City("Bielefeld", 333_000, "Germany")); + put("Manila", new City("Manila", 1_780_000, "Philippines")); + put("Da Nang", new City("Da Nang", 1_220_000, "Vietnam")); + put("London", new City("London", 8_980_000, "England")); + put("New York", new City("New York", 8_460_000, "USA")); + }}; + + public static String getSoapFault(String faultString, String code, String errorMessage) { + return """ + + + + s11:Client + %s + + %s + %s + + + + + """.formatted(faultString, code, errorMessage); + } + + public static String getElementAsString(InputStream is, String localName) throws Exception { + // MLInputFactory is not required to be thread-safe, ... + // https://javadoc.io/static/com.sun.xml.ws/jaxws-rt/2.2.10-b140319.1121/com/sun/xml/ws/api/streaming/XMLStreamReaderFactory.Default.html#:~:text=XMLInputFactory%20is%20not%20required%20to,using%20a%20XMLInputFactory%20per%20thread. + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLStreamReader reader = factory.createXMLStreamReader(is); + + while (reader.hasNext()) { + if (reader.next() == START_ELEMENT) { + if (reader.getName().getLocalPart().equals(localName)) { + return reader.getElementText(); + } + } + } + throw new Exception(); + } + + public static String setWsdlServer(InputStream is, Exchange exc) throws XMLStreamException { + // XMLEventFactory is not required to be thread-safe, ... + // https://javadoc.io/static/com.sun.xml.ws/jaxws-rt/2.2.10-b140319.1121/com/sun/xml/ws/api/streaming/XMLStreamReaderFactory.Default.html + StringWriter modifiedXmlWriter = new StringWriter(); + XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(Objects.requireNonNull(is)); + XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(modifiedXmlWriter); + XMLEventFactory fac = XMLEventFactory.newInstance(); + + while (reader.hasNext()) { + XMLEvent event = reader.nextEvent(); + if (event.isStartElement()) { + StartElement startElement = event.asStartElement(); + if ("address".equals(startElement.getName().getLocalPart())) { + writer.add(fac.createStartElement("soap", "soap", "address")); + writer.add(fac.createAttribute("location", getSOAPAddress(exc))); + } else { + writer.add(event); + } + } else { + writer.add(event); + } + } + + return modifiedXmlWriter.toString(); + } + + public static String getSOAPAddress(Exchange exc) { + return exc.getInboundProtocol() + "://" + exc.getRequest().getHeader().getHost() + getPathWithoutParam(exc.getOriginalRequestUri()); + } + + static String getPathWithoutParam(String exc) { + return exc.replaceAll("\\?.*$", ""); + } + + + public static String getResponse(String city) throws ParserConfigurationException, TransformerException { + try { + return xml2string(createResponse(city)); + } catch (Exception e) { + return getSoapFault("Not Found", "404", "Do not know %s. Try Bonn, London or New York".formatted(city)); + } + } + + private static Document createResponse(String city) throws Exception { + // DocumentBuilderFactory is not guaranteed to be thread safe + // https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.5/api/javax/xml/parsers/DocumentBuilderFactory.html + Document res = createDocumentBuilder().newDocument(); + res.appendChild(createResponseEnvelope(city, res)); + return res; + } + + private static Element createResponseEnvelope(String city, Document res) { + Element env = res.createElementNS(SOAP11_NS, "s:Envelope"); + env.setAttribute("xmlns:s", SOAP11_NS); + env.setAttribute("xmlns:cs", CITY_SERVICE_NS); + env.appendChild(createBody(city, res)); + return env; + } + + private static Element createBody(String city, Document res) { + Element body = res.createElement("s:Body"); + body.appendChild(createCityDetails(city, res)); + return body; + } + + private static Element createCityDetails(String city, Document res) { + Element details = res.createElement("cs:getCityResponse"); + details.appendChild(createCountry(city, res)); + details.appendChild(createPopulation(city, res)); + return details; + } + + private static Element createPopulation(String city, Document res) { + Element pop = res.createElement("population"); + pop.appendChild(res.createTextNode(String.valueOf(cityMap.get(city).population))); + return pop; + } + + private static Element createCountry(String city, Document res) { + Element country = res.createElement("country"); + country.appendChild(res.createTextNode(cityMap.get(city).country)); + return country; + } + + private static DocumentBuilder createDocumentBuilder() throws ParserConfigurationException { + return DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + public record City(String name, int population, String country) {} + +} \ No newline at end of file diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java index a9a55e93b..f3af18991 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java @@ -33,6 +33,7 @@ import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE; import static java.nio.charset.StandardCharsets.UTF_8; +import static javax.xml.transform.OutputKeys.*; /** @@ -92,10 +93,10 @@ public static String documentToString(Document doc) { tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty(OutputKeys.INDENT, "no"); - transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(METHOD, "xml"); + transformer.setOutputProperty(INDENT, "no"); + transformer.setOutputProperty(ENCODING, "UTF-8"); transformer.transform(new DOMSource(doc), new StreamResult(sw)); return sw.toString(); } catch (Exception ex) { diff --git a/core/src/main/java/com/predic8/membrane/core/util/SOAPUtil.java b/core/src/main/java/com/predic8/membrane/core/util/SOAPUtil.java index 20532a532..43599d2c0 100644 --- a/core/src/main/java/com/predic8/membrane/core/util/SOAPUtil.java +++ b/core/src/main/java/com/predic8/membrane/core/util/SOAPUtil.java @@ -94,17 +94,12 @@ public static boolean isFault(XMLInputFactory xmlInputFactory, XOPReconstitutor String expected; switch (state) { - case 0: - expected = "Envelope"; - break; - case 1: - expected = "Body"; - break; - case 2: - expected = "Fault"; - break; - default: - return false; + case 0 -> expected = "Envelope"; + case 1 -> expected = "Body"; + case 2 -> expected = "Fault"; + default -> { + return false; + } } if (expected.equals(name.getLocalPart())) { if (state == 2) diff --git a/core/src/main/java/com/predic8/membrane/core/util/XMLUtil.java b/core/src/main/java/com/predic8/membrane/core/util/XMLUtil.java new file mode 100644 index 000000000..0151bcee7 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/util/XMLUtil.java @@ -0,0 +1,29 @@ +package com.predic8.membrane.core.util; + +import org.w3c.dom.*; + +import javax.xml.transform.*; +import javax.xml.transform.dom.*; +import javax.xml.transform.stream.*; +import java.io.*; + +import static javax.xml.transform.OutputKeys.INDENT; +import static javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION; + +public class XMLUtil { + + // TODO 2. param boolean indent + // Write Test + public static String xml2string(Document doc) throws TransformerException { + TransformerFactory tfFactory = TransformerFactory.newInstance(); // Comment ThreadSafe? with URL + Transformer tf = tfFactory.newTransformer(); + tf.setOutputProperty(OMIT_XML_DECLARATION, "yes"); + + tf.setOutputProperty(INDENT, "yes"); + tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + + StringWriter writer = new StringWriter(); + tf.transform(new DOMSource(doc), new StreamResult(writer)); + return writer.toString(); + } +} diff --git a/core/src/main/resources/wsdl/city.wsdl b/core/src/main/resources/wsdl/city.wsdl new file mode 100644 index 000000000..55ad7a2f0 --- /dev/null +++ b/core/src/main/resources/wsdl/city.wsdl @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SampleSoapInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SampleSoapInterceptorTest.java new file mode 100644 index 000000000..0cb9e7694 --- /dev/null +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SampleSoapInterceptorTest.java @@ -0,0 +1,179 @@ +package com.predic8.membrane.core.interceptor.soap; + +import com.predic8.membrane.core.exchange.Exchange; +import com.predic8.membrane.core.http.MimeType; +import com.predic8.membrane.core.http.Request; +import com.predic8.membrane.core.rules.ServiceProxy; +import com.predic8.membrane.core.rules.ServiceProxyKey; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Objects; + +import static com.predic8.membrane.core.interceptor.soap.SampleSoapServiceInterceptor.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SampleSoapInterceptorTest { + + private static SampleSoapServiceInterceptor service; + private static final Exchange exc = new Exchange(null); + + private static ServiceProxy serviceProxy; + + @BeforeAll + public static void setUp() throws IOException { + service = new SampleSoapServiceInterceptor(); + serviceProxy = new ServiceProxy(new ServiceProxyKey("localhost", ".*", ".*", 3011), "thomas-bayer.com", 80); + } + + @Test + public void notFoundTest() throws Exception { + exc.setRequest(new Request.Builder().contentType(MimeType.TEXT_XML).post("/foo") + .body(IOUtils.toByteArray(Objects.requireNonNull(this.getClass().getResourceAsStream("/soap-sample/wrong-request.xml")))).build()); + service.handleRequest(exc); + assertEquals(SampleSoapServiceInterceptor.getSoapFault("Resource Not Found", "404", "Cannot parse SOAP message. Request should contain e.g. Bonn"), exc.getResponse().getBody().toString()); + // System.out.println(exc.getResponse().getBody().toString()); + } + + @ParameterizedTest + @CsvSource({ + "/foo?bar, false", + "/foo?content-wsdl, true", + "/foo?wSdL, true", + "/foo?w-sdl, false" + }) + public void isWsdlTest(String path, boolean expected) throws Exception { + exc.setRequest(new Request.Builder().get(path).build()); + assertEquals(expected, isWSDLRequest(exc)); + } + + @Test + public void wsdlTest() throws Exception { + exc.setRequest(new Request.Builder().contentType(MimeType.TEXT_XML).get("/bar?wsdl").header("Host", "Host").build()); + exc.setRule(serviceProxy); + exc.setOriginalRequestUri("/foo"); + service.handleRequest(exc); + // System.out.println(exc.getResponse().getBody().toString()); + assertTrue(exc.getResponse().getBody().toString().contains("Host")); + } + + @ParameterizedTest + @CsvSource({ + "/foo?bar, /foo", + "/foo?content-wsdl, /foo", + "/foo?wSdL, /foo", + "/foo?w-sdl, /foo" + }) + public void getPathWithoutParamTest(String path, String expected) throws Exception { + assertEquals(getPathWithoutParam(path), expected); + } + + + @Test + public void methodTest() throws Exception { + exc.setRequest(new Request.Builder().contentType(MimeType.TEXT_XML).get("/foo").build()); + service.handleRequest(exc); + assertTrue(exc.getResponse().getBodyAsStringDecoded().contains("Use POST to access the service.")); + } + + + private void testValidRequest(String requestFileName, String country, String population) throws Exception { + InputStream requestStream = getClass().getResourceAsStream("/soap-sample/" + requestFileName); + exc.setRequest(new Request.Builder().contentType(MimeType.TEXT_XML).body(IOUtils.toByteArray(Objects.requireNonNull(requestStream))).post("/foo").build()); + service.handleRequest(exc); + + String responseXML = exc.getResponse().getBody().toString(); + System.out.println(exc.getResponse().getBody().toString()); + + assertTrue(compareXmlStrings(responseXML, country, population)); + } + + @Test + public void validRequest1Test() throws Exception { + testValidRequest("soap-request-bonn.xml", "Germany", "327000"); + } + + @Test + public void validRequest2Test() throws Exception { + testValidRequest("soap-request-london.xml", "England", "8980000"); + } + + @Test + public void validRequest3Test() throws Exception { + testValidRequest("soap-request-new-york.xml", "USA", "8460000"); + } + + private boolean compareXmlStrings(String xml, String country, String population) { + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes()); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new InputSource(inputStream)); + + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.setNamespaceContext(new NamespaceContext() { + @Override + public Iterator getPrefixes(String namespaceURI) { + return null; + } + + @Override + public String getPrefix(String namespaceURI) { + if ("http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceURI)) { + return "s"; + } else if ("https://predic8.de/city-service".equals(namespaceURI)) { + return "cs"; + } + return null; + } + + @Override + public String getNamespaceURI(String prefix) { + if ("s".equals(prefix)) { + return "http://schemas.xmlsoap.org/soap/envelope/"; + } else if ("cs".equals(prefix)) { + return "https://predic8.de/city-service"; + } + return null; + } + }); + + Node countryNode = (Node) xPath.evaluate( + String.format("/s:Envelope/s:Body/cs:getCityResponse/country[text()='%s']", country), + document, + XPathConstants.NODE + ); + Node populationNode = (Node) xPath.evaluate( + String.format("/s:Envelope/s:Body/cs:getCityResponse/population[text()='%s']", population), + document, + XPathConstants.NODE + ); + + return country.equals(countryNode != null ? countryNode.getTextContent() : null) + && population.equals(populationNode != null ? populationNode.getTextContent() : null); + + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/core/src/test/resources/soap-sample/soap-request-bonn.xml b/core/src/test/resources/soap-sample/soap-request-bonn.xml new file mode 100644 index 000000000..5b448a8b5 --- /dev/null +++ b/core/src/test/resources/soap-sample/soap-request-bonn.xml @@ -0,0 +1,7 @@ + + + + Bonn + + + \ No newline at end of file diff --git a/core/src/test/resources/soap-sample/soap-request-london.xml b/core/src/test/resources/soap-sample/soap-request-london.xml new file mode 100644 index 000000000..22bc7b8c1 --- /dev/null +++ b/core/src/test/resources/soap-sample/soap-request-london.xml @@ -0,0 +1,7 @@ + + + + London + + + \ No newline at end of file diff --git a/core/src/test/resources/soap-sample/soap-request-new-york.xml b/core/src/test/resources/soap-sample/soap-request-new-york.xml new file mode 100644 index 000000000..d26455aa4 --- /dev/null +++ b/core/src/test/resources/soap-sample/soap-request-new-york.xml @@ -0,0 +1,7 @@ + + + + New York + + + \ No newline at end of file diff --git a/core/src/test/resources/soap-sample/wrong-request.xml b/core/src/test/resources/soap-sample/wrong-request.xml new file mode 100644 index 000000000..3bcad09be --- /dev/null +++ b/core/src/test/resources/soap-sample/wrong-request.xml @@ -0,0 +1,7 @@ + + + + Bonn + + + \ No newline at end of file diff --git a/distribution/examples/soap/sample-soap-service/README.md b/distribution/examples/soap/sample-soap-service/README.md new file mode 100644 index 000000000..858d0df10 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/README.md @@ -0,0 +1,33 @@ +# Sample Soap Service: CitiesService + +This plugin offers a sample SOAP service that can be used in tutorials and for testing purposes. + +## Starting the Service + +1. Go to the `examples/soap/sample-soap-service` directory. +2. Run `service-proxy.sh` or `service-proxy.bat` to start the API Gateway. + +## Using the Service +### Get the WSDL + +Unter `http://localhost:2000?wsdl` you can retrieve the Web Service Description Language (WSDL). + +`curl http://localhost:2000?wsdl` + +### Get City Information +You can retrieve information about a city using the following curl: +``` +curl http://localhost:2000 \ +-H 'Content-Type: text/xml' \ +-d ' + + + + Bonn + + +' +``` +Please note that this is an example service, and it contains data for the following cities: +Bonn, Bielefeld, Manila, Da Nang, London, and New York. You can replace Bonn` +in the above request with the city of your choice to retrieve information for a different city. \ No newline at end of file diff --git a/distribution/examples/soap/sample-soap-service/proxies.xml b/distribution/examples/soap/sample-soap-service/proxies.xml new file mode 100644 index 000000000..aa0340097 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/proxies.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/distribution/examples/soap/sample-soap-service/request.xml b/distribution/examples/soap/sample-soap-service/request.xml new file mode 100644 index 000000000..5b448a8b5 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/request.xml @@ -0,0 +1,7 @@ + + + + Bonn + + + \ No newline at end of file diff --git a/distribution/examples/soap/sample-soap-service/requests.http b/distribution/examples/soap/sample-soap-service/requests.http new file mode 100644 index 000000000..a6827cf15 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/requests.http @@ -0,0 +1,14 @@ +GET http://localhost:2000?WSDL + +### + +POST http://localhost:2000 +Content-Type: text/xml + + + + + London + + + \ No newline at end of file diff --git a/distribution/examples/soap/sample-soap-service/service-proxy.bat b/distribution/examples/soap/sample-soap-service/service-proxy.bat new file mode 100644 index 000000000..6742f74b4 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/service-proxy.bat @@ -0,0 +1,18 @@ +@echo off +if not "%MEMBRANE_HOME%" == "" goto homeSet +set "MEMBRANE_HOME=%cd%\..\..\.." +echo "%MEMBRANE_HOME%" +if exist "%MEMBRANE_HOME%\service-proxy.bat" goto homeOk + +:homeSet +if exist "%MEMBRANE_HOME%\service-proxy.bat" goto homeOk +echo Please set the MEMBRANE_HOME environment variable to point to +echo the directory where you have extracted the Membrane software. +exit + +:homeOk +set "CLASSPATH=%MEMBRANE_HOME%" +set "CLASSPATH=%MEMBRANE_HOME%/conf" +set "CLASSPATH=%CLASSPATH%;%MEMBRANE_HOME%/starter.jar" +echo Membrane Router running... +java -classpath "%CLASSPATH%" com.predic8.membrane.core.Starter -c proxies.xml \ No newline at end of file diff --git a/distribution/examples/soap/sample-soap-service/service-proxy.sh b/distribution/examples/soap/sample-soap-service/service-proxy.sh new file mode 100755 index 000000000..2c6c5d0d6 --- /dev/null +++ b/distribution/examples/soap/sample-soap-service/service-proxy.sh @@ -0,0 +1,35 @@ +#!/bin/bash +homeSet() { + echo "MEMBRANE_HOME variable is now set" + CLASSPATH="$MEMBRANE_HOME/conf" + CLASSPATH="$CLASSPATH:$MEMBRANE_HOME/starter.jar" + export CLASSPATH + echo Membrane Router running... + java -classpath "$CLASSPATH" com.predic8.membrane.core.Starter -c proxies.xml + +} + +terminate() { + echo "Starting of Membrane Router failed." + echo "Please execute this script from the appropriate subfolder of MEMBRANE_HOME/examples/" + +} + +homeNotSet() { + echo "MEMBRANE_HOME variable is not set" + + if [ -f "`pwd`/../../../starter.jar" ] + then + export MEMBRANE_HOME="`pwd`/../../.." + homeSet + else + terminate + fi +} + + +if [ "$MEMBRANE_HOME" ] + then homeSet + else homeNotSet +fi + diff --git a/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithoutInternet.java b/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithoutInternet.java index a635b37cf..6f4244e6b 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithoutInternet.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithoutInternet.java @@ -54,6 +54,7 @@ JSONSchemaValidationTest.class, XMLValidationTest.class, + SampleSoapServiceTest.class, // Transformatiom Xml2JsonTest.class, diff --git a/distribution/src/test/java/com/predic8/membrane/examples/tests/SampleSoapServiceTest.java b/distribution/src/test/java/com/predic8/membrane/examples/tests/SampleSoapServiceTest.java new file mode 100644 index 000000000..cf791af05 --- /dev/null +++ b/distribution/src/test/java/com/predic8/membrane/examples/tests/SampleSoapServiceTest.java @@ -0,0 +1,68 @@ +package com.predic8.membrane.examples.tests; + +import com.predic8.membrane.examples.util.AbstractSampleMembraneStartStopTestcase; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.HashMap; +import java.util.List; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class SampleSoapServiceTest extends AbstractSampleMembraneStartStopTestcase { + + @Override + protected String getExampleDirName() { + return "soap/sampleSoapService"; + } + + private final HashMap methodGETmap = new HashMap<>() {{ + String soapWsdlSubStr = "Method Not Allowed"); + + }}; + + final List parameters() { + return methodGETmap.keySet().stream().toList(); + } + + @ParameterizedTest + @MethodSource("parameters") + public void testMethod(String query) { + given() + .when() + .get("http://localhost:2000/" + query) + .then() + .body(containsString(methodGETmap.get(query))); + + } + + + private final HashMap cityMap = new HashMap<>() {{ + put("Bonn", "327000"); + put("London", "8980000"); + put("Berlin", "404"); + + }}; + + final List cityMap() { + return cityMap.keySet().stream().toList(); + } + + @ParameterizedTest + @MethodSource("cityMap") + public void testCity(String city) throws Exception { + given() + .body(readFileFromBaseDir("request.xml").replace("Bonn", city)) + .when() + .post("http://localhost:2000/") + .then() + .body(containsString(cityMap.get(city))); + + } +}