We are using the WSO2 API manager as an API Gateway. One of the APIs I have is a JSON-only not-fully-restful API. It uses HTTP POST requests with JSON as a data exchange format. I have a very basic configuration for this: Configured as a REST API with POST /* allowed.
Some of the responses include JSON which has strings like "P~A" as object keys. When I try to call this via the gateway it chokes on the response:
2018-09-13 18:37:37,890 [-] [PassThroughMessageProcessor-36] ERROR JsonUtil #writeAsJson. Could not convert OMElement to JSON. Invalid XML payload. Error>>> Unexpected character '~' (code 126) excepted space, or '>' or "/>"
at [row,col {unknown-source}]: [1,4956]
2018-09-13 18:37:37,891 [-] [PassThroughMessageProcessor-36] ERROR PassThroughHttpSSLSender Failed to submit the response
org.apache.axis2.AxisFault: Could not convert OMElement to JSON. Invalid XML payload.
at org.apache.synapse.commons.json.JsonUtil.writeAsJson(JsonUtil.java:372)
at org.apache.synapse.commons.json.JsonFormatter.writeTo(JsonFormatter.java:84)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.submitResponse(PassThroughHttpSender.java:573)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:264)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:230)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:531)
at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:118)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
at org.apache.synapse.rest.Resource.process(Resource.java:343)
at org.apache.synapse.rest.API.process(API.java:338)
at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:90)
at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:56)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:304)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:554)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:188)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:262)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '~' (code 126) excepted space, or '>' or "/>"
at [row,col {unknown-source}]: [1,4956]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:647)
at com.ctc.wstx.sr.BasicStreamReader.handleNsAttrs(BasicStreamReader.java:2996)
at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2963)
at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2839)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1073)
at javax.xml.stream.util.StreamReaderDelegate.next(Unknown Source)
at javax.xml.stream.util.StreamReaderDelegate.next(Unknown Source)
at org.codehaus.stax2.ri.Stax2ReaderAdapter.next(Stax2ReaderAdapter.java:129)
at org.codehaus.stax2.ri.Stax2EventReaderImpl.peek(Stax2EventReaderImpl.java:367)
at org.apache.synapse.commons.staxon.core.event.SimpleXMLEventWriter.add(SimpleXMLEventWriter.java:118)
at org.apache.synapse.commons.json.JsonUtil.writeAsJson(JsonUtil.java:368)
... 23 more
2018-09-13 18:37:37,892 [-] [PassThroughMessageProcessor-36] ERROR Axis2Sender Access-Control-Allow-Headers:authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction,Access-Control-Allow-Methods:HEAD,DELETE,POST,PATCH,PUT,GET,Access-Control-Allow-Origin:*,Content-Type:application/json;charset=utf-8,<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><jsonObject>
(it then continues and includes XML which tries to use the "P~A" keys from the JSON as <P~A> XML tags, which is what it chokes on)
The API definition does not have message mediate enabled and also has response caching disabled. So, I'm not clear why it's even using the mediator and trying to convert my JSON response to XML at all.
So, the question: how to get this working? Either by configuring it to cope with converting that to XML or not need to?
I would also note that something in this process takes a long time. It takes a very long time before I get the (error) response but I see that the response data arrives in the API manager quickly.
We do also have the WSO2 Analytics service running. I tried stopping that in case it was causing the issue. Didn't help
I'm posting this as an answer because it solves the problem. Add
synapse.commons.json.buildValidNCNames=true
To the repository/conf/synapse.properties file.
It makes it cope with the ~ (and anything else not valid in a tag) using character codes.
I guess maybe the mediation isn't the message mediation (which was disabled) but something more internal. In that case I really don't understand why the above setting isn't the default value - I don't see a downside with it and without it, the gateway can't cope with certain JSON!
Related
I have been trying to create a new API in WSO2 using WSO2 REST services, While I am able to register DCR application, get authtoken and list down already existing APIs, the create new API call fails with 500 Error.
The same error I receive when trying to crate new API from WSO2 UI. Been using minimal required fields as well as tried with full API body given in documentation.
Here is the API Call:
Endpoint: **https://serverIP:9443/api/am/publisher/v1.2/apis**
Type : POST
Auth: Access-token
Body: {
"name": "Rest Test API",
"context": "/test",
"version": "1.0.0"
}
Postman Response: {
"code": 500,
"message": "Internal server error",
"description": "The server encountered an internal error. Please contact administrator.",
"moreInfo": "",
"error": []
}
Tried checking the logs but they all point to no specific details except the null pointer exception.
Logs for reference: https-jsse-nio-9443-exec-19] ERROR GlobalThrowableMapper An unknown exception has been captured by the
global exception mapper. java.lang.NullPointerException: null
at org.wso2.carbon.apimgt.impl.APIProviderImpl.validateSharedScopes_aroundBody486(APIProviderImpl.java:8708)
~[org.wso2.carbon.apimgt.impl_6.7.206.jar:?]
at org.wso2.carbon.apimgt.impl.APIProviderImpl.validateSharedScopes(APIProviderImpl.java:8706)
~[org.wso2.carbon.apimgt.impl_6.7.206.jar:?]
at org.wso2.carbon.apimgt.impl.UserAwareAPIProvider.validateSharedScopes(UserAwareAPIProvider.java:1)
~[org.wso2.carbon.apimgt.impl_6.7.206.jar:?]
at org.wso2.carbon.apimgt.rest.api.publisher.v1.impl.ApisApiServiceImpl.validateScopes(ApisApiServiceImpl.java:4510) ~[classes/:?]
at org.wso2.carbon.apimgt.rest.api.publisher.v1.impl.ApisApiServiceImpl.apisPost(ApisApiServiceImpl.java:278)
~[classes/:?]
at org.wso2.carbon.apimgt.rest.api.publisher.v1.ApisApi.apisPost(ApisApi.java:962)
~[classes/:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)
~[cxf-core-3.2.8.jar:3.2.8]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
~[cxf-core-3.2.8.jar:3.2.8]
What could be the problem? Is there a specific location I can see for specific logs?
TIA
According to the log, It seems like the payload you passed is invalid or missing mandatory fields.
Seems like, You have try to add a shared scope to an API which is not already defined. So please proceed and check the payload provided is correct.
There are 2 points you need to consider in this case. They are as follows.
1. Rest API version
Based on your API endpoint "https://serverIP:9443/api/am/publisher/v1.2/apis" you are using the REST API version v1.2. Currently, WSO2 APIM does not support such a version. The latest wso2am-3.2.0 uses v1 version. If you are using wso2am-2.2.0 then the version should be v0.12. Please check this.
2. Scopes
In order to add new APIs via a REST API call, you should have generated the access tokens with the following OAuth 2.0 scope in order to access those resources. Please check if you have generated the access tokens with the relevant scopes.
wso2am-3.2.0: apim:api_create (link)
wso2am-2.2.0: apim:api_create (link)
6.0 to call a Drupal 8 RESTful web service endpoint which returns the response in hal_json format. I have never come across this format before but this is what the Drupal 8 response is in. The Content-Type is "application/hal+json". For more information, this is the Drupal 8 link - https://www.drupal.org/docs/8/core/modules/rest/3-post-for-creating-content-entities
I'm using a property mediator to convert the response from hal_json format to XML but I'm getting the below error:
OMException in getSOAPBuilder org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'
I searched online for this error and found that this type of error usually occurs when the API response is in a format that is not enabled in WSO2 (it needs to be enabled in the axis2.xml file). Can anyone please tell me what property I need to add to my axis2.xml file? I think is needs to be a message formatter and builder property.
I have not worked with the JSON message type specified. But if it is a valid JSON message you can define a JsonStreamBuilder builder for this message type. The message builder can be defined as follows in the axis2.xml file under messageBuilders in [EI_HOME]/conf/axis2 directory
<messageBuilders>
..
<messageBuilder contentType="application/hal+json"
class="org.wso2.carbon.integrator.core.json.JsonStreamBuilder"/>
..
</messageBuilders>
After modifying the axis2.xml you need to perform a server restart in order for this to take effect.
I am getting the Blank JSON body in request. due to that ESB is given the below error.
org.apache.axis2.AxisFault: No JSON payload provided.
I am using the wso2 esb 4.9.0 version.
request is POST.
Can you please help in that .
This is a limitation of ESB, you can either send an empty json payload as {} or you can set the Content-Type as application/xml in the request.
According to the HTTP spec "The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET"
[1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
So if you are defining the media type as "application/json", then there should be a matching entity body for POST. That is why you need to send at-least empty JSON body. If you don't have a body then change the resource to GET rather POST.
But the I found the issue. yes you are right but in Wso2 ESB 4.8.1 if we pass any message with without body as post then we got the error to avoid that we had created the blank payload to call that API. as soon as I removed that blank payload issue resolved. I agreed that post need that body but I had to consume the message of other system that will provide the same (Post with body).
one more thing. if any one put log as full then also you will get the same error.
i am call web service with axis2 plugin .The methodology used is rpc.
the code main is :
GetPayIDBillIDStub stub = new GetPayIDBillIDStub("http://80.91.4.113:8088/services/GetPayIDBillID_Proxy");
stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
GetPayIDBillIDStub.PaymentInput input = new GetPayIDBillIDStub.PaymentInput();
input.setPassword("123456");
input.setTelephone(2111111111);
input.setUsername("test");
paymentTelOPR.setPaymentTelOPRRequest(input);
org.apache.axiom.om.OMFactory factory = org.apache.axiom.om.OMAbstractFactory.getOMFactory();
paymentTelOPRResponseE = stub.paymentTelOPR(paymentTelOPRE.setPaymentTelOPRRequest(paymentTelOPR.getOMElement(GetPayIDBillIDStub.PaymentTelOPR.MY_QNAME, factory)));
error is :
Exception in thread "main" java.lang.IllegalArgumentException: The MessageContext does not have an associated SOAPFault.
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:556)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:375)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:421)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at mypackage.GetPayIDBillIDStub.paymentTelOPR(GetPayIDBillIDStub.java:182)
at Run.main(Run.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
help for me.
We recently had this Problem because the response contained no SOAPFault (in fact was the expected answer to the service call) but the http status code of the response was 5xx (500 in our case).
Maybe something similar in your case.
You can verify this by using an generic Webservice client like SoapUI which can also display the raw hhtp response.
I know it is a late answer, but I can help the new engineers with my experience.
I got the same error where I was using SOAP UI with my API. The problem started when I replaced my mocked response by a fault response just for testing it. But once I retried to use the correct code, it didn't work and it gave me this error.
The solution was: that I have to delete the response because it is considered as a fault response and missing the fault code, When I created a new response and deleted the old one, it worked without getting this exception
I'm using WSO2 API Manager and I want access to details of the client's incoming API request (into API Manager, for example, the HTTP method) as well the response from my API endpoint. I've followed the approach in the following document to write a custom mediator class which gets invokes on both the "In" (for the request) and "Out" (for the response) flows:
https://docs.wso2.org/display/AM160/Adding+a+Mediation+Extension
It seems I can get various bits of data that I need from the MessageContext that is passed into my mediator, but I'm struggling with getting the response code from my API endpoint. Is there a way to get access to the HTTP response itself (and all it's headers and other elements) from the MessageContext? I stumbled across the PassThroughTransportUtils class which has a determineHttpStatusCode method which I could call but I'm not sure this is the best way of doing it.
"HTTP_SC" property is stored in Axis2MessageContext, which can be accessed as below:
org.apache.axis2.context.MessageContext msgContext = ((Axis2MessageContext) messageContext).getAxis2MessageContext();
String httpStatusCode = (String) msgContext.getProperty(NhttpConstants.HTTP_SC);
can be null, if not set.