educloudalliance / xroad-rest-gateway

Unmaintained repository. Development moved to
https://github.com/vrk-kpa/REST-adapter-service
European Union Public License 1.1
20 stars 11 forks source link

Special characters cause org.w3c.dom.DOMException: INVALID_CHARACTER_ERR error #23

Closed petkivim closed 8 years ago

petkivim commented 8 years ago

The below REST Gateway request throws an exception.

http://localhost:8080/rest-gateway-0.0.7/Consumer/api.finna.fi/v1/record?id[]=fennica.123&id[]=fennica.124

The exception is caused by [] characters that are special characters in XML. The numeric character reference should be used instead of the character for parameter values. In this case [] characters are in the parameter name which is why they cannot be used even with numeric character reference, because REST Gateway uses parameter names as XML element names.

01.09.2016 09:27:31 DEBUG ConsumerGateway : Add parameter : "id[]" -> "fennica.123".
01.09.2016 09:27:31 ERROR AbstractServiceRequestSerializer : INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified.
org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified.
        at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.checkQName(CoreDocumentImpl.java:2603)
        at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:121)
        at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:84)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.<init>(ElementImpl.java:98)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementFactory.createElement(ElementFactory.java:82)
        at com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl.createElement(SOAPDocumentImpl.java:98)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.createElement(ElementImpl.java:393)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addElement(ElementImpl.java:373)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addChildElement(ElementImpl.java:122)
        at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addChildElement(ElementImpl.java:130)
        at com.pkrete.xrd4j.tools.rest_gateway.ConsumerGateway$RequestSerializer.serializeRequest(ConsumerGateway.java:449)
        at com.pkrete.xrd4j.client.serializer.AbstractServiceRequestSerializer.serializeBody(AbstractServiceRequestSerializer.java:95)
        at com.pkrete.xrd4j.client.serializer.AbstractServiceRequestSerializer.serialize(AbstractServiceRequestSerializer.java:63)
        at com.pkrete.xrd4j.client.SOAPClientImpl.send(SOAPClientImpl.java:94)
        at com.pkrete.xrd4j.tools.rest_gateway.ConsumerGateway.processRequest(ConsumerGateway.java:176)
        at com.pkrete.xrd4j.tools.rest_gateway.ConsumerGateway.doGet(ConsumerGateway.java:275)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
        at com.pkrete.xrd4j.tools.rest_gateway.filter.ConsumerURIFilter.doFilter(ConsumerURIFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
01.09.2016 09:27:31 WARN  AbstractServiceRequestSerializer : Failed to serialize ServiceRequest message to SOAP.
petkivim commented 8 years ago

Added new properties to ProviderGateway that make it possible to solve the issue using parameter filtering. The below properties must added for the service in providers.properties file.

x.reqParamNameFilterCondition=(id)
x.reqParamNameFilterOperation=$1[]

With the above configuration in place in ProvideGateway the service call for ConsumerGateway looks like this:

http://localhost:8080/rest-gateway-0.0.9/Consumer/api.finna.fi/v1/record?id=fennica.123

ProviderGateway then filters the parameters according the given rules and the actual service URL likes this:

https://api.finna.fi/v1/record?id[]=fennica.123