Sending a PDF file in a REST Message - intersystems-iris

I am trying figure this out any help appreciated. Thanks in advance
The service is a file passthrough that picks up a PDF and then uses the BPL code below to create the rest wrapper and sends the stream data. I am not grabbing the stream from the inbound correctly, "request.Stream" or "request.StreamFC" always produces the following error.
Here is what is sent and returned in the message..
request:
*
<Stream>
15#%Library.FileCharacterStream
</Stream>
response:
<Stream>
Unable to load xml from message: Data at the root level is invalid. Line 1, position 1.
</Stream>
-I think my issue is I am not using the right class by using "%GlobalStreamCharacter", Or the raw PDF CDATA inbound I am not handling correctly
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
I have tried using different Stream types...File, Binary....but no luck
-The general BPL below
/// BPL Definition
X
Data BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='Ens.StreamContainer' response='Ens.Response'
height='2000' width='2000' >
<context>
.....
.....
....
<code name='Create REST Message' xpos='200' ypos='250' >
<![CDATA[
set context.RESTMessage=##class(EnsLib.HTTP.GenericMessage).%New()
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
set tSC=context.RESTMessage.Stream.Write(request.StreamFC)
set tSC=context.RESTMessage.HTTPHeaders.SetAt("application/xml","Content-Type")
set tSC=context.RESTMessage.HTTPHeaders.SetAt(context.RESTMessage.Stream.Size,"Content-
Length")
set tSC=context.RESTMessage.HTTPHeaders.SetAt("POST","HttpRequest")
]]>
</code>

You can try this code snippet. I got the answer in the community.
<call name='To application Rest' target='To application REST' async='0'>
<request type='EnsLib.REST.GenericMessage' >
<assign property="callrequest.Stream" value='##class(%Stream.GlobalCharacter).%New()'/>
<assign property="status" value='callrequest.Stream.CopyFrom(request.StreamFC)' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("application/xml", "Content-Type")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt(callrequest.Stream.Size, "Content-Length")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("POST", "HttpRequest")' action="set" />
</request>
</call>

Related

Azure Load test does not report data driven urls

I have a simple load test that basically executes a single webtest on a constant load. That webtest is hooked to an xml file data source that contains urls to my entire site.
When I execute the load test from my local environment, the test summary page reports the individual urls in the "Top 5 slowest pages" i.e. "https://mysite.or/page" . But when I execute the same test from Azure (i.e. changed Test run location to VSTS in .testsettings), the links are reported as "https://{{Enviroment}}{{Sitemap.url.loc}}". This seems to be just a reporting issue and I can validate that azure is correctly invoking the urls from the data source. Why would the tests from Azure not report the url constructed from the datasource?
Load Test Summary: Executed from Local
Same test executed on Azure
Webtest:
<?xml version="1.0" encoding="utf-8"?>
<WebTest Name="GenericSitemap" Id="02954e81-f3a7-4c9c-94f5-3a4304f88361" Owner="" Priority="2147483647" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale="">
<Items>
<Request Method="GET" Guid="01c37ffa-92db-42e8-9d25-a042dcd0123d" Version="1.1" Url="https://{{Enviroment}}{{Sitemap.url.loc}}" ThinkTime="0" Timeout="300" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="0" ExpectedResponseUrl="https://{{Enviroment}}{{Sitemap.url.loc}}" ReportingName="" IgnoreHttpStatusCode="False" />
</Items>
<DataSources>
<DataSource Name="Sitemap" Provider="Microsoft.VisualStudio.TestTools.DataSource.XML" Connection="|DataDirectory|\..\Data\sitemap.xml">
<Tables>
<DataSourceTable Name="url" SelectColumns="SelectOnlyBoundColumns" AccessMethod="Random" />
</Tables>
</DataSource>
</DataSources>
<ContextParameters>
<ContextParameter Name="Enviroment" Value="mysite.net" />
</ContextParameters>
</WebTest>
Thanks to #AdrianHHH. I got it working by creating a requestPlugin and setting it on the data driven requests.
Here's my plugin:
[DisplayName("Set Request Params")]
[Description("Fix request urls when run from Azure")]
public class SetRequestParams : WebTestRequestPlugin
{
public override void PreRequest(object sender, PreRequestEventArgs e)
{
e.Request.ReportingName = e.Request.Url;
}
}

WSO2 websocket + SockJS - Cross origin requests blocked

Since WSO2 5.0 supports WebSockets, I have written a simple app following by tutorials:
WebSocket Transport
Sending a Message from a WebSocket Client to an HTTP Endpoint
Here's my source view output from WSO2:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<sequence name="fault">
<!-- Log the message at the full log level with the ERROR_MESSAGE and the ERROR_CODE-->
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
<property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
</log>
<!-- Drops the messages by default if there is a fault -->
<drop/>
</sequence>
<sequence name="main">
<in>
<!-- Log all messages passing through -->
<log level="full"/>
<!-- ensure that the default configuration only sends if it is one of samples -->
<!-- Otherwise Synapse would be an open proxy by default (BAD!) -->
<filter regex="http://localhost:9000.*" source="get-property('To')">
<!-- Send the messages where they have been sent (i.e. implicit "To" EPR) -->
<send/>
</filter>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
<sequence name="outDispatchSeq">
<log level="full"/>
<respond/>
</sequence>
<sequence name="dispatchSeq">
<switch
source="get-property('websocket.source.handshake.present')" xmlns:ns="http://org.apache.synapse/xsd">
<case regex="true">
<drop/>
</case>
<default>
<call/>
<respond/>
</default>
</switch>
</sequence>
<!-- You can add any flat sequences, endpoints, etc.. to this synapse.xml file if you do
*not* want to keep the artifacts in several files -->
<inboundEndpoint name="test" onError="fault" protocol="ws"
sequence="dispatchSeq" suspend="false">
<parameters>
<parameter name="inbound.ws.port">9091</parameter>
<parameter name="ws.client.side.broadcast.level">0</parameter>
<parameter name="ws.outflow.dispatch.sequence">outDispatchSeq</parameter>
<parameter name="ws.outflow.dispatch.fault.sequence">fault</parameter>
</parameters>
</inboundEndpoint>
</definitions>
I was able to successfully test it with Nett client:
C:\work\servers\netty>java -Durl=ws://localhost:9091/websocket -DsubProtocol="synapse(contentType='application/xml')" -cp netty-example-4.1.4.Final.jar;lib/*;. io.netty.example.http.websocketx.client.WebSocketClient
WebSocket Client connected!
However if I try to test it from JavaScript code I am getting error like:
Do you know what is wrong in my code?
This issue occurs because SockJS internally trying to load the URL using XMLHttpRequest, but Chrome does not allow accessing cross origin content unless the protocol is one of the aforementioned protocols (In this case it is ws://). I have tried a similar scenario with Firefox and it works fine since it doesn't have this Chrome specific limitation.
In this scenario since WSO2 ESB exposes a WebSocket interface to invoke the HTTP Endpoint, you can use native HTML5 WebSocket implementation as follows.
var url = 'ws://localhost:9091/websocket';
var ws = new WebSocket(url);
ws.onopen = function() {
// todo
}
ws.onmessage = function(e) {
// todo
}

Conflict 409 error when creating a Google Shared Contact using API

I'm continually getting a HTTP 409 "Conflict" error when attempting to add a new Google Shared Contact using the API.
I've followed the documentation as closely as possible and have defined the new entry as so:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<gd:name>
<gd:givenName>Test</gd:givenName>
<gd:familyName>Testerson</gd:familyName>
<gd:fullName>Test Testerson</gd:fullName>
</gd:name>
<atom:content type='text'></atom:content>
<gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='test.testerson#sample.com.au' displayName='' />
<gd:email rel='http://schemas.google.com/g/2005#home' address='' />
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#fax'>(07) 33331122</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'></gd:phoneNumber>
<gd:im address='' protocol='http://schemas.google.com/g/2005#GOOGLE_TALK' primary='true' rel='http://schemas.google.com/g/2005#home' />
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
<gd:city>Abbey</gd:city>
<gd:street>PO Box 4561</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>PO Box 4561, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#other'>
<gd:city>Abbey</gd:city>
<gd:street>47 Example Avenue</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>47 Example Avenue, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:organization rel='http://schemas.google.com/g/2005#other'>
<gd:orgTitle>Guinea Pig</gd:orgTitle>
<gd:orgName>Test Org</gd:orgName>
</gd:organization>
</atom:entry>
I've set up my HTTP request as follows:
lsToken = GetAuthToken()
Set lobjHttp = CreateObject("MSXML2.XMLHTTP")
Call lobjHttp.Open("POST", CS_FEED_DEFAULT, False, "", "")
Call lobjHttp.setRequestHeader("Authorization", "GoogleLogin auth=" + lsToken)
Call lobjHttp.setRequestHeader("Content-type", "application/atom+xml")
Call lobjHttp.Send(lsOut)
In this example CS_FEED_DEFAULT is the shared contact URL and lsOut is my entry as defined above.
After sending this request I get the 409 response and the following response text:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
<id>http://www.google.com/m8/feeds/contacts/test.com.au/base/47e904e10dd27dd2</id>
<updated>2014-09-17T02:08:39.761Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
<title type='text'></title>
<content type='text'></content>
<link rel='http://schemas.google.com/contacts/2008/rel#edit-photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/test.com.au/47e904e10dd27dd2/1B2M2Y8AsgTpgAmY7PhCfg'/>
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2'/>
<link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2/1410919719761001'/>
<gd:email rel='http://schemas.google.com/g/2005#work' address='test.testerson#sample.com.au' primary='true'/>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work_fax'>(07) 33331122</gd:phoneNumber>
</entry>
Can anyone offer me any advice on this issue?
Thanks.
According to the contacts API documentation, "409 error can be returned when there is a different contact with the same email address. As for now, google contacts API does not allow two different contacts to share an email address".
Have you been trying to add the same email address twice?
I had the same error because I forgot to Start my previously stopped SQL instance on GCP.

WSO2 ESB xpath problems

I want to use the following xpath
/Users/User/UserID
This does not work because the ESB adds a soap envelope and body around my xml, what is the correct xpath to use or how can I remove the soap envelope and body?
The xml is:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<Users xmlns="http://ws.wso2.org/dataservice">
<User>
<UserID>a</UserID>
<Username>a</Username>
<Email>a</Email>
<Password>a</Password>
</User>
<User>
<UserID>a</UserID>
<Username>a</Username>
<Email>a</Email>
<Password>a</Password>
</User>
<User>
<UserID>a</UserID>
<Username>a</Username>
<Email>a</Email>
<Password>a</Password>
</User>
</Users>
</soapenv:Body>
</soapenv:Envelope>
EDIT:
This works when I try to log it outside of my iterate mediator
//*[local-name() = 'Users']/*[local-name() = 'User']/*[local-name() = 'UserID']
but when I try to log it inside the iterate mediator it returns nothing?
Got this working by using the following
<property xmlns:int="http://ws.wso2.org/dataservice" name="uri.var.ID" expression="$body/int:User/int:UserID/text()" scope="default" type="STRING"/>
To access your elements you should go through envelope and body.
Here is an example with switch mediator:
<switch xmlns:ns="http://org.apache.synapse/xsd"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:int="http://ws.wso2.org/dataservice"
source="boolean(/soap:Envelope/soap:Body/int:Users/int:User/int:UserID/text() = 'string_to_compare'">
<case regex="true">
....
</case>
<default/>
</switch>
UPD
corrected XPath expression
Try this:
<property name="yourParamName" expression="$body/Users/User/UserID" scope="default" type="STRING"/>
You can read more on the predefined Synapse XPath variables here.

OpenFire/XMPP 503 service-unavailable error (XEP-0065 using iOS XMPPFramework)

Problem : I am attempting a TURN Connection (XEP-0065) using the iOS XMPPFramework and an OpenFire Server. I want to be able to send and receive files. However, I am receiving a 503 service-unavailable error.
Note : The base of my code is from the following tutorial : http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/
XML Error :
I've debugged through TURNSocket.m. It goes into processRequestResponse and has the following XML. (If I am not mistaken, this has been sent from OpenFire to me, rather than vice versa?) ...
<iq xmlns="jabber:client"
type="error"
id="03CC977E-2645-4E87-AE78-536D985CA2B5"
from="friendsUsername#beta.myCompany.co.uk"
to="myUsername#beta.myCompany.co.uk/12f10b69">
<query xmlns="http://jabber.org/protocol/bytestreams"
sid="03CC977E-2645-4E87-AE78-536D985CA2B5"
mode="tcp">
<streamhost jid="proxy.beta.myCompany.co.uk"
host="127.0.1.1"
port="7777"/>
</query>
<error code="503"
type="cancel">
<service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
Why is there an error?
Update : XEP-0065 says the following. Even though this error looks a little different to mine, is it relevant? If so, what is the problem?
If the Proxy is unable to act as a StreamHost, the Proxy MUST return
an error to the Requester, which SHOULD be <not-allowed/>.
<iq from='requester#example.com/foo'
id='uj2c15z9'
to='streamer.example.com'
type='error'>
<error type='cancel'>
<not-allowed
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
Update : At the moment I'm looking into whether the inclusion or exclusion of a JID resource in the various sent and retrieved bits of XML is the problem. Or alternatively, I don't even have a 'from' in the following xml. the docs imply i need this. Is this the issue? I dont see a current way in the code to make a 'from' ...
<iq type="get"
to="beta.myCompany.co.uk"
id="215784CF-81A8-403E-89BF-455C926BEAE5">
<query xmlns="http://jabber.org/protocol/disco#items"/>
</iq>
Update 19/04/12 11:00 am : In response to Matt J's response, I am posting more XML. I'm not sure Matt requested the full XML log of what is sent and retrieved, but just in case, here it is. Note that these logs are not all from the same run-through (because when I debug it to get the XML logs, it causes timeouts so I have to start again)
Sent :
<iq type="get" to="beta.myCompany.co.uk"
id="082A1987-384F-43CD-9E7B-A2C0E31F2CA8">
<query xmlns="http://jabber.org/protocol/disco#items"/>
</iq>
Response :
<iq xmlns="jabber:client"
type="result"
id="18EED477-B0E4-492D-89CF-CA692FCF13AD"
from="beta.myCompany.co.uk"
to="myUsername#beta.myCompany.co.uk/72d23cd0">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="pubsub.beta.myCompany.co.uk"
name="Publish-Subscribe service"/>
<item jid="broadcast.beta.myCompany.co.uk"
name="Broadcast service"/>
<item jid="search.beta.myCompany.co.uk"
name="User Search"/>
<item jid="conference.beta.myCompany.co.uk"
name="Public Chatrooms"/>
<item jid="proxy.beta.myCompany.co.uk"
name="Socks 5 Bytestreams Proxy"/>
</query>
</iq>
Sent :
<iq type="get"
to="proxy.beta.myCompany.co.uk"
id="F1B5370C-234F-4F2D-93E7-D60D2C35D063">
<query xmlns="http://jabber.org/protocol/disco#info"/>
</iq>
Response :
<iq xmlns="jabber:client"
type="result"
id="F1B5370C-234F-4F2D-93E7-D60D2C35D063"
from="proxy.beta.myCompany.co.uk"
to="myUsername#beta.myCompany.co.uk/32276f6">
<query xmlns="http://jabber.org/protocol/disco#info">
<identity category="proxy"
name="SOCKS5 Bytestreams Service"
type="bytestreams"/>
<feature var="http://jabber.org/protocol/bytestreams"/>
<feature var="http://jabber.org/protocol/disco#info"/>
</query>
</iq>
Sent :
<iq type="get"
to="proxy.beta.myCompany.co.uk"
id="84904B7D-2BB2-4B8E-90BE-BE0F5A934764">
<query xmlns="http://jabber.org/protocol/bytestreams"/>
</iq>
Response :
<iq xmlns="jabber:client"
type="result"
id="B412512B-FA27-4531-88BE-2FC0A26E6ED2"
from="proxy.beta.myCompany.co.uk"
to="myUsername#beta.myCompany.co.uk/45ca808d">
<query xmlns="http://jabber.org/protocol/bytestreams"/>
</iq>
plus we also get a streamhost from the code from the query like this: NSXMLElement *streamhost = [query elementForName:#"streamhost"];
<streamhost xmlns="http://jabber.org/protocol/bytestreams"
jid="proxy.beta.myCompany.co.uk"
host="127.0.1.1"
port="7777"/>
Sent :
<iq type="set"
to="friendsUsername#beta.myCompany.co.uk/spark"
id="DD96A581-BFA3-47BC-A3C0-D26AD48D7442">
<query xmlns="http://jabber.org/protocol/bytestreams"
sid="DD96A581-BFA3-47BC-A3C0-D26AD48D7442"
mode="tcp">
<streamhost xmlns="http://jabber.org/protocol/bytestreams"
jid="proxy.beta.myCompany.co.uk"
host="127.0.1.1"
port="7777"/>
</query>
</iq>
This gives no response, but it looks ok to me when I compare to example 17 of XEP-0065. HOWEVER, if don't include a resource on the jID passed into TurnSocket.m (friendsUsername#beta.myCompany.co.uk rather than friendsUsername#beta.myCompany.co.uk/spark), then this send request changes appropriately
<iq type="set"
to="friendsUsername#beta.myCompany.co.uk" **LOOK! NO RESOURCE!**
id="5D08B85E-CA78-4AA8-A893-C1DC571A9808">
<query xmlns="http://jabber.org/protocol/bytestreams"
sid="5D08B85E-CA78-4AA8-A893-C1DC571A9808"
mode="tcp">
<streamhost xmlns="http://jabber.org/protocol/bytestreams"
jid="proxy.beta.myCompany.co.uk"
host="127.0.1.1"
port="7777"/>
</query>
</iq>
and the XML in my original question above is returned! (with the 503 error code). Furthermore, I notice that this xml contains 'streamhost', but at this stage should it actually contain 'streamhost-used'? Why is there an error? Should or shouldn't I include the resource in the 'to'?
Minor Update 19/04/2012 15:07 : I have added xmpp.proxy.transfer.required as false on OpenFire. This is due to these discussions: here and here. I didn't set up this server (my colleague did) and I don't understand what it means, but it doesn't seem to have made any difference to my problem.
Update 20/04/2012 10:00 : My 503 error I think is correctly there when I don't include the resource (according to this). Even if this is so though, I'm unsure why I get no response with a full jID.
The 503 error was due to the fact that I was not providing the full JID. e.g I was providing friendsUsername#domain rather than friendsUsername#domain/resource.
However, I still haven't made a successful connection, and have opened a new question here

Resources