Savon ignores namespace_identifier attribute - ruby-on-rails

Am trying to re-write written by savon body namespace - ins0
I have this client variable:
client = Savon.client(wsdl: "https://integcert.synxis.com/interface/Contracts/ChannelConnect2004.wsdl", log_level: :debug, log: true, pretty_print_xml: true, env_namespace: :soapenv, namespaces: {"xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:head": "http://htng.org/1.1/Header/","xmlns:ns": "http://www.opentravel.org/OTA/2003/05"}, convert_request_keys_to: :none, namespace_identifier: "ns", element_form_default: :qualified)
And when Am doing the request:
client.call(:ping, soap_header: { "head:HTNGHeader": { "head:From": { "head:Credential": { "head:userName": "******", "head:password":"*****" }}}}, message: {"ns:EchoData": "TestData"})
I've got this soap rq body:
<soapenv:Body>
<ins0:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ins0:OTA_PingRQ>
</soapenv:Body>
Where this ins0 is came from?
Also when I tried to define client with namespace_identifier: nil parameter and did this kind of request:
client.call(:ping, soap_header: { "head:HTNGHeader": { "head:From": { "head:Credential": { "head:userName": "******", "head:password":"*****" }}}}, message: {"ns:OTA_PingRQ": {"ns:EchoData": "TestData"}})
I've got this soap rq body:
<soapenv:Body>
<OTA_PingRQ>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</OTA_PingRQ>
And the correct body that I want to have is:
<soapenv:Body>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</soapenv:Body>
Any ideas how to remove additional nested OTA_PingRQnode or replace ins0 namespace by the custom ?

Your idea with additional namespaces was logically correct, but it doesn't look like Savon really wants to use them everywhere. It prefers to use namespaces found in WSDL. I tried element_form_default: :qualified and element_form_default: :unqualified, but it still puts ins0 as a namespace for OTA_PingRQ node everytime. I thought if it wants ins0 then let's use ins0 then.
I looked at the list of available namespaces and found appropriate one for the header as well. Have no idea why Savon doesn't want to specify namespace for header nodes automatically, so we have to specify it manually as ins1.
Here is working version of configuration:
client = Savon.client(
wsdl: "https://integcert.synxis.com/interface/Contracts/ChannelConnect2004.wsdl",
log_level: :debug,
log: true,
pretty_print_xml: true,
namespace_identifier: :ins0,
element_form_default: :qualified,
soap_header: {
"ins1:HTNGHeader": {
"ins1:From": {
"ins1:Credential": {
"ins1:userName": "******",
"ins1:password":"*****"
}
}
}
}
)
client.call(:ping, message: {"EchoData": "TestData"})
Request:
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ins0="http://www.opentravel.org/OTA/2003/05" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins1="http://htng.org/1.1/Header/">
<env:Header>
<ins1:HTNGHeader>
<ins1:From>
<ins1:Credential>
<ins1:userName>******</ins1:userName>
<ins1:password>*****</ins1:password>
</ins1:Credential>
</ins1:From>
</ins1:HTNGHeader>
</env:Header>
<env:Body>
<ins0:OTA_PingRQ>
<ins0:echoData>TestData</ins0:echoData>
</ins0:OTA_PingRQ>
</env:Body>
</env:Envelope>
Response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<OTA_PingRS xmlns="http://www.opentravel.org/OTA/2003/05" PrimaryLangID="en">
<Errors>
<Error Type="4" ShortText="Login failed"/>
</Errors>
<EchoData/>
</OTA_PingRS>
</soap:Body>
</soap:Envelope>
EDIT: Provided soap_header at the client configuration, because it's more efficient way.

There is another way to attach namespace_identifier also.
First set namespace_identifier: nil in Savon client.
basic_auth = [username, password]
client = Savon.client(
wsdl:"https://integcert.synxis.com/interface/ChannelConnect2004.wsdl",
namespace: {},
env_namespace: 'soapenv',
namespace_identifier: nil,
basic_auth: basic_auth,
logger: Rails.logger,
log: true,
soap_version: 2,
pretty_print_xml: true,
convert_request_keys_to: :camelcase,
namespaces: {
'xmlns:soap' => 'http://example.com/soap-envelope',
'xmlns:glob' => 'http://example.com/Global'
}
)
Now while calling the operation set message_tag
response = client.call(:operation_name, message_tag: 'glob:OTA_PingRQ', message: {"EchoData": "TestData"})
Output:
<soapenv:Body>
<glob:OTA_PingRQ>
<EchoData>TestData</ns:EchoData>
</glob:OTA_PingRQ>
</soapenv:Body>
For Outoput like:
<soapenv:Body>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</soapenv:Body>
client call will be same but in client config add **element_form_default: :qualified**

Related

Pact verification: Failure/Error: expect(header_value).to match_header(name, expected_header_value)

Using pact to verify if the response header matches for the consumer and provider.
Running the pact verification on the provider side gives me the following error:
Failure/Error: expect(header_value).to match_header(name, expected_header_value)
Expected header "abc" to equal "xyz", but was nil
However, when I inspect if my response header, it gives me the expected value ("xyz").
Here is the sample pact file I'm trying to verify:
"interactions": [
{
"description": "a request to do something",
"request": {
"method": "get",
"path": "/example"
},
"response": {
"status": 200,
"headers": {
"abc": "xyz"
}
}
}]
I’m new to pact. Any help would be appreciated.
While this is an old post, I hope this will help anyone who views this.
I'm not familiar with ruby, however if your using a basic HTTP Rest request you need to add the accept headers on the 'withRequest' as well as the expected headers on the 'withRespondWith'. You can use Postman to view both request and response headers; JavaScript Example:
describe('When a request is made to get all <resources>', () => {
beforeAll(() =>
provider.setup().then(() => {
provider.addInteraction({
uponReceiving: 'a request to receive to receive all...',
withRequest: {
method: 'GET',
path: '/<resource>',
// Default headers from Axios documentation
headers: { Accept: "application/json, text/plain, */*" }
},
...
willRespondWith: {
// expected headers
headers: { "Content-Type": "application/json; charset=utf-8" },
...

EWS GetStreamingEvents. Response is received only by timeout

In my iOS app I'm trying to get streaming events from EWS following this manual. So first I subscribe for notifications, receive a subscription id and then perform GetStreamingEvents request. The subscription process is successful, however getting streaming events is not. I receive a response only by timeout. Yes, it does contain all the notifications, so no problems with that but I expect to receive a response once an event has occurred not when the request time is up.
So I launched Charles and examined the traffic of Mac Mail app. I can see that it receives one response right after making GetStreamingEvents request and then it successfully receives responses every time an event has occurred as expected. So I made my XML look exactly like Mac Mail app's but still no luck.
This is my Subscribe xml:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestedServerVersion Version="Exchange2010_SP2" />
</soap:Header>
<soap:Body>
<m:Subscribe xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:StreamingSubscriptionRequest SubscribeToAllFolders="true">
<t:EventTypes>
<t:EventType>CopiedEvent</t:EventType>
<t:EventType>CreatedEvent</t:EventType>
<t:EventType>DeletedEvent</t:EventType>
<t:EventType>ModifiedEvent</t:EventType>
<t:EventType>MovedEvent</t:EventType>
<t:EventType>NewMailEvent</t:EventType>
<t:EventType>FreeBusyChangedEvent</t:EventType>
</t:EventTypes>
</m:StreamingSubscriptionRequest>
</m:Subscribe>
</soap:Body>
</soap:Envelope>
and this is my GetStreamingEvents xml:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP2" />
</soap:Header>
<soap:Body>
<m:GetStreamingEvents xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:SubscriptionIds>
<t:SubscriptionId>JwBkYjVwcjA2bWIxNDY0LmV1cnByZDA2LnByb2Qub3V0bG9vay5jb20QAAAAF9r7tBXj+U+UapGUZ4XFytKbA+ad1dQIEAAAAMiCIP/mQqJOjzx9Aog45Fk=</t:SubscriptionId>
</m:SubscriptionIds>
<m:ConnectionTimeout>30</m:ConnectionTimeout>
</m:GetStreamingEvents>
</soap:Body>
</soap:Envelope>
Any ideas, guys?
UPDATE:
This is how I build my subscription:
bcstring SubscribeRequestMessage::buildSoapRequest() const
{
xml_document<> doc;
xml_node<>* decl = doc.allocate_node(node_declaration);
decl->append_attribute(doc.allocate_attribute("version", "1.0"));
decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
doc.append_node(decl);
// Envelope
xml_node<>* envelope = doc.allocate_node(node_element, "soap:Envelope");
envelope->append_attribute(doc.allocate_attribute("xmlns:soap", "http://schemas.xmlsoap.org/soap/envelope/"));
envelope->append_attribute(doc.allocate_attribute("xmlns:t", "http://schemas.microsoft.com/exchange/services/2006/types"));
doc.append_node(envelope);
{
// Header
xml_node<>* header = doc.allocate_node(node_element, "soap:Header");
{
xml_node<>* reqServerVersion = doc.allocate_node(node_element, "t:RequestedServerVersion");
xml_attribute<>* serverVersionAttribute = doc.allocate_attribute("Version", m_requestedServerVersion.c_str());
reqServerVersion->append_attribute(serverVersionAttribute);
header->append_node(reqServerVersion);
}
envelope->append_node(header);
// Body
xml_node<>* body = doc.allocate_node(node_element, "soap:Body");
{
xml_node<>* subscribe = doc.allocate_node(node_element, "m:Subscribe");
{
subscribe->append_attribute(doc.allocate_attribute("xmlns:m", "http://schemas.microsoft.com/exchange/services/2006/messages"));
xml_node<>* streamingSubscriptionRequest = doc.allocate_node(node_element, "m:StreamingSubscriptionRequest");
{
if (m_folderIds.size() > 0)
{
xml_node<>* folderIds = doc.allocate_node(node_element, "t:FolderIds");
{
for (const bcstring& folderId : m_folderIds)
{
xml_node<>* folderIdNode = doc.allocate_node(node_element, "t:FolderId");
folderIdNode->append_attribute(doc.allocate_attribute("Id", folderId.c_str()));
folderIds->append_node(folderIdNode);
}
}
streamingSubscriptionRequest->append_node(folderIds);
}
else
{
xml_attribute<>* subscribeToAll = doc.allocate_attribute("SubscribeToAllFolders", "true");
streamingSubscriptionRequest->append_attribute(subscribeToAll);
}
xml_node<>* eventTypes = doc.allocate_node(node_element, "t:EventTypes");
{
for (const bcstring& eventType : m_eventTypes)
{
xml_node<>* eventTypeNode = doc.allocate_node(node_element, "t:EventType");
xml_node<>* eventTypeValueNode = doc.allocate_node(node_data, "", eventType.c_str());
eventTypeNode->append_node(eventTypeValueNode);
eventTypes->append_node(eventTypeNode);
}
}
streamingSubscriptionRequest->append_node(eventTypes);
}
subscribe->append_node(streamingSubscriptionRequest);
}
body->append_node(subscribe);
}
envelope->append_node(body);
}
bcstring retVal;
print(std::back_inserter(retVal), doc, print_no_indenting);
return retVal;
}
and this is how I build get streaming xml:
bcstring GetStreamingEventsRequest::buildSoapRequest() const
{
xml_document<> doc;
xml_node<>* decl = doc.allocate_node(node_declaration);
decl->append_attribute(doc.allocate_attribute("version", "1.0"));
decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
doc.append_node(decl);
// Envelope
xml_node<>* envelope = doc.allocate_node(node_element, "soap:Envelope");
envelope->append_attribute(doc.allocate_attribute("xmlns:soap", "http://schemas.xmlsoap.org/soap/envelope/"));
envelope->append_attribute(doc.allocate_attribute("xmlns:t", "http://schemas.microsoft.com/exchange/services/2006/types"));
doc.append_node(envelope);
{
// Header
xml_node<>* header = doc.allocate_node(node_element, "soap:Header");
{
xml_node<>* reqServerVersion = doc.allocate_node(node_element, "t:RequestServerVersion");
xml_attribute<>* serverVersionAttribute = doc.allocate_attribute("Version", m_requestedServerVersion.c_str());
reqServerVersion->append_attribute(serverVersionAttribute);
header->append_node(reqServerVersion);
}
envelope->append_node(header);
// Body
xml_node<>* body = doc.allocate_node(node_element, "soap:Body");
{
xml_node<>* getStreamingEvents = doc.allocate_node(node_element, "m:GetStreamingEvents");
{
getStreamingEvents->append_attribute(doc.allocate_attribute("xmlns:m", "http://schemas.microsoft.com/exchange/services/2006/messages"));
xml_node<>* subscriptionIds = doc.allocate_node(node_element, "m:SubscriptionIds");
{
for (const bcstring& subscriptionId : m_subscriptionIds)
{
xml_node<>* subscriptionIdNode = doc.allocate_node(node_element, "t:SubscriptionId");
xml_node<>* subscriptionIdValue = doc.allocate_node(node_data, "", subscriptionId.c_str());
subscriptionIdNode->append_node(subscriptionIdValue);
subscriptionIds->append_node(subscriptionIdNode);
}
}
getStreamingEvents->append_node(subscriptionIds);
xml_node<>* connectionTimeout = doc.allocate_node(node_element, "m:ConnectionTimeout");
bcstring connectionTimeoutString = std::to_string(m_connectionTimeout);
xml_node<>* connectionTimeoutValue = doc.allocate_node(node_data, "", connectionTimeoutString.c_str());
connectionTimeout->append_node(connectionTimeoutValue);
getStreamingEvents->append_node(connectionTimeout);
}
body->append_node(getStreamingEvents);
}
envelope->append_node(body);
}
bcstring retVal;
print(std::back_inserter(retVal), doc, print_no_indenting);
return retVal;
}
UPDATE:
This is the XML of Mac Mail app that I see via Charles:
Subscription:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP2" />
</soap:Header>
<soap:Body>
<m:Subscribe xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:StreamingSubscriptionRequest SubscribeToAllFolders="true">
<t:EventTypes>
<t:EventType>CopiedEvent</t:EventType>
<t:EventType>CreatedEvent</t:EventType>
<t:EventType>DeletedEvent</t:EventType>
<t:EventType>ModifiedEvent</t:EventType>
<t:EventType>MovedEvent</t:EventType>
<t:EventType>NewMailEvent</t:EventType>
<t:EventType>FreeBusyChangedEvent</t:EventType>
</t:EventTypes>
</m:StreamingSubscriptionRequest>
</m:Subscribe>
</soap:Body>
</soap:Envelope>
and streaming:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP2" />
</soap:Header>
<soap:Body>
<m:GetStreamingEvents xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:SubscriptionIds>
<t:SubscriptionId>JwBkYjVwcjA2bWIxNDY0LmV1cnByZDA2LnByb2Qub3V0bG9vay5jb20QAAAADv7qpS0xbU6V0mCxt2SvFHYOYoCq1dQIEAAAAMiCIP/mQqJOjzx9Aog45Fk=</t:SubscriptionId>
</m:SubscriptionIds>
<m:ConnectionTimeout>30</m:ConnectionTimeout>
</m:GetStreamingEvents>
</soap:Body>
</soap:Envelope>
and this is the response from EWS arriving upon timeout and containing a notification about a new mail:
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ConnectionStatus>OK</m:ConnectionStatus>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Notifications>
<m:Notification>
<t:SubscriptionId>JwBkYjVwcjA2bWIxNDY0LmV1cnByZDA2LnByb2Qub3V0bG9vay5jb20QAAAA4mbQZqHZf0aA35Z5r1UEvPZtJfmw1dQIEAAAAMiCIP/mQqJOjzx9Aog45Fk=</t:SubscriptionId>
<t:CreatedEvent>
<t:TimeStamp>2017-07-28T12:06:04Z</t:TimeStamp>
<t:ItemId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQBGAAAAAADKa2Su6/EXRrsmOefDSCL3BwBEITO0krAyRbRmLsC3JNeGAAAAAAEMAABEITO0krAyRbRmLsC3JNeGAAAdPAOsAAA=" ChangeKey="CQAAAA==" />
<t:ParentFolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEMAAA=" ChangeKey="AQAAAA==" />
</t:CreatedEvent>
<t:NewMailEvent>
<t:TimeStamp>2017-07-28T12:06:04Z</t:TimeStamp>
<t:ItemId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQBGAAAAAADKa2Su6/EXRrsmOefDSCL3BwBEITO0krAyRbRmLsC3JNeGAAAAAAEMAABEITO0krAyRbRmLsC3JNeGAAAdPAOsAAA=" ChangeKey="CQAAAA==" />
<t:ParentFolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEMAAA=" ChangeKey="AQAAAA==" />
</t:NewMailEvent>
<t:ModifiedEvent>
<t:TimeStamp>2017-07-28T12:06:04Z</t:TimeStamp>
<t:FolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEMAAA=" ChangeKey="AQAAAA==" />
<t:ParentFolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEIAAA=" ChangeKey="AQAAAA==" />
<t:UnreadCount>1</t:UnreadCount>
</t:ModifiedEvent>
</m:Notification>
</m:Notifications>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ConnectionStatus>OK</m:ConnectionStatus>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ConnectionStatus>OK</m:ConnectionStatus>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Notifications>
<m:Notification>
<t:SubscriptionId>JwBkYjVwcjA2bWIxNDY0LmV1cnByZDA2LnByb2Qub3V0bG9vay5jb20QAAAA4mbQZqHZf0aA35Z5r1UEvPZtJfmw1dQIEAAAAMiCIP/mQqJOjzx9Aog45Fk=</t:SubscriptionId>
<t:ModifiedEvent>
<t:TimeStamp>2017-07-28T12:07:39Z</t:TimeStamp>
<t:ItemId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQBGAAAAAADKa2Su6/EXRrsmOefDSCL3BwBEITO0krAyRbRmLsC3JNeGAAAAAAEMAABEITO0krAyRbRmLsC3JNeGAAAdPAOsAAA=" ChangeKey="CQAAAA==" />
<t:ParentFolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEMAAA=" ChangeKey="AQAAAA==" />
</t:ModifiedEvent>
<t:ModifiedEvent>
<t:TimeStamp>2017-07-28T12:07:39Z</t:TimeStamp>
<t:FolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEMAAA=" ChangeKey="AQAAAA==" />
<t:ParentFolderId Id="AAMkAGZmMjA4MmM4LTQyZTYtNGVhMi04ZjNjLTdkMDI4ODM4ZTQ1OQAuAAAAAADKa2Su6/EXRrsmOefDSCL3AQBEITO0krAyRbRmLsC3JNeGAAAAAAEIAAA=" ChangeKey="AQAAAA==" />
<t:UnreadCount>0</t:UnreadCount>
</t:ModifiedEvent>
</m:Notification>
</m:Notifications>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
<Envelope
xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="1282" MinorBuildNumber="22" Version="V2017_04_14"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ConnectionStatus>Closed</m:ConnectionStatus>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
"GetStreamingEvents" responses really are streamed.
This means that the http connection stays open, and the notifications are sent through it in more of a continuous flow than a standard request/response mechanism. This is similar to the way streaming a video works. You don't do a single request for the entire video. Instead, you would read the streamed data from the video as it is being sent, and process it accordingly.
You need to handle responses to "GetStreamingEvents" in a similar fashion.
The details provided in the question don't show how you are handling the responses, but I'm guessing that you are using an API that simply fetches a URL and returns a response. That works great for standard requests like the "StreamingSubscriptionRequest", but it won't work for streamed responses.
APIs that simply fetch a url won't return until a complete response is received and/or the connection is closed. That's why it seems like you're not receiving the streamed events until the timeout expires.
In fact, you are receiving those events, you're just not reading them and processing them as they come in.
To do that, you'll need to use an API that allows to you connect to an http server and read from that connection as the data arrives. For iOS, this is as simple as implementing the [connection didReceiveData:] delegate method on NSURLConnection. Presumably, there is some similar higher-level mechanism that can be used in your environment.
I also ran into this problem once, but I don't know if it is the same for you. I was using EWS over HTTP with chunked transfer encoding and also received responses only at timeout. It turned out that a terminating 0 chunk was only sent at timeout, not after each response, therefore I was always waiting for more data until the timeout.
Note that it is not too bad to have a low timeout since you might want to use multiple subscriptions in a single GetEvents request and you can't add or remove subscriptions from a running GetEvents request.

Unable to send xml response with serverless framework

I'm working with twilio in which when call comes to my twilio number it invokes webhook, I'm using lambda function as webhook,
twilio expects xml(formerly called twiml) response from webhook and i'm unable to send xml response from lambda function
I'm using serverless framework
here is my code
function:
module.exports.voice = (event, context, callback) => {
console.log("event", JSON.stringify(event))
var twiml = new VoiceResponse();
twiml.say({ voice: 'alice' }, 'Hello, What type of podcast would you like to listen? ');
twiml.say({ voice: 'alice' }, 'Please record your response after the beep. Press any key to finish.');
twiml.record({
transcribe: true,
transcribeCallback: '/voice/transcribe',
maxLength: 10
});
console.log("xml: ", twiml.toString())
context.succeed({
body: twiml.toString()
});
};
yml:
service: aws-nodejs
provider:
name: aws
runtime: nodejs6.10
timeout: 10
iamRoleStatements:
- Effect: "Allow"
Action: "*"
Resource: "*"
functions:
voice:
handler: handler.voice
events:
- http:
path: voice
method: post
integration: lambda
response:
headers:
Content-Type: "'application/xml'"
template: $input.path("$")
statusCodes:
200:
pattern: '.*' # JSON response
template:
application/xml: $input.path("$.body") # XML return object
headers:
Content-Type: "'application/xml'"
Response:
please let me know if I'm making some mistake in code
also created an issue on github
Thanks,
Inzamam Malik
You don't need to mess with serverless.yml so much. Here is the simple way:
In serverless.yml...
functions:
voice:
handler: handler.voice
events:
- http:
path: voice
method: post
(response, headers, Content-Type, template, and statusCodes are not necessary)
Then you can just set the statusCode and Content-Type in your function.
So delete this part...
context.succeed({
body: twiml.toString()
});
... and replace it with:
const response = {
statusCode: 200,
headers: {
'Content-Type': 'text/xml',
},
body: twiml.toString(),
};
callback(null, response);
Lambda proxy integration (which is the default) assembles it into a proper response.
Personally I find this way simpler and more readable.
you need your lambda to be a "proxy" type, so you set the body property.
but just try to do
context.succeed(twiml.toString());
that will send the "string" as result directly
or use the callback param:
function(event, context, callback) {
callback(null, twiml.toString())
}
As mentioned by #UXDart, you'll not be able to do this using the standard integration. You should setup a proxy integration with Lambda like here -http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html#api-gateway-proxy-integration-lambda-function-nodejs
This will work better with what you are trying to do, return xml through api gateway.
Change your serverless.yml to this:
service: aws-nodejs
provider:
name: aws
runtime: nodejs6.10
timeout: 10
iamRoleStatements:
- Effect: "Allow"
Action: "*"
Resource: "*"
functions:
voice:
handler: handler.voice
events:
- http:
path: voice
method: post
integration: lambda
response:
headers:
Content-Type: "'application/xml'"
template: $input.path("$")
statusCodes:
200:
pattern: '' # Default response method
template:
# Your script returns json, so match it here
application/json: $input.path("$.body")
headers:
Content-Type: "'application/xml'"
Got mine to work with this.
events:
- http:
path: call/receive
method: post
integration: lambda
response:
headers:
Content-Type: "'application/xml'"
template: $input.path("$")
statusCodes:
200:
pattern: ''
template:
application/json: $input.path("$")
headers:
Content-Type: "'application/xml'"
and
callback(null, twiml.toString());
It works for me.
webhook:
handler: webhook.webhook
events:
- http:
path: webhook
method: get
cors: true
integration: lambda
response:
headers:
Content-Type: "'application/xml'"
template: $input.path("$")
statusCodes:
200:
pattern: '' # Default response method
template:
# Your script returns json, so match it here
application/json: $input.path("$.body")
headers:
Content-Type: "'application/xml'"
Checkout the twilio serverless example here: https://github.com/serverless/examples/tree/master/aws-node-twilio-send-text-message

Oauth Bigcommerce

I'm getting error "Invalid client id" while authorization my rails app with bigcommerce api.
omniauth.rb file is
Rails.application.config.middleware.use OmniAuth::Builder do
provider :bigcommerce,
'CLIENT_ID',
'CLIENT_SECRET',
{
scope: "users_basic_information store_v2_products store_v2_information store_v2_content",
client_options: {
site: 'https://login.bigcommerce.com'
}
}
end
and in the second api call which is post request like
response = HTTParty.post(
'https://login.bigcommerce.com/oauth2/token',
{body: {
client_secret: auth['credentials']['token'].client.secret,
client_id: auth['credentials']['token'].client.id,
code: params[:code],
scope: params[:scope],
grant_type: :authorization_code,
redirect_uri: "http://localhost:3001/auth/bigcommerce/callback",
context: 'params[:Store_hash]'
},
headers: {
'Content-Type'=> 'application/x-wwww-form-urlencoded'
}
}
)
getting "Invalid client id" in the response of post request.
Thanks in advance.

Rendering a view with custom mime type in Grails

I am attempting to render text for reponse in Grails with a custom contentType. My desired contentType is: application/vnd.api+json
I am testing with the following
render(contentType: "application/vnd.api+json") {
message = 'some text'
foo = 'bar'
}
which does not render throwing an exception that message is a missing property.
While the following works fine:
render(contentType: "text/json") {
message = 'some text'
foo = 'bar'
}
My Config.groovy has the following under json mime.type:
grails.mime.types = [
...
json: [
'application/json',
'text/json',
'application/vnd.api+json'
],
...
]
My question, how to render with a custom mime-type in Grails?
Do you have the accept header in the request set the custom content-type?
The accept header is one way for client to inform server which content-type would be acceptable for itself.
In config.groovy the below setting has to be set as well to use accept headers
grails.mime.use.accept.header = true
I would also try rendering the response in the conventional way:
render(contentType: "application/vnd.api+json", text: [message: 'some text', foo: 'bar'])

Resources