5

I am trying to complete the example on page 19 of the SAS BI Web Services Developers Guide. I have followed the instructions verbatim but am unable to get the stored process (automatically a web service) to return the correct result when I make a post request. I am trying both SOAP and XML. The error is that the 'instream' data source is never found.

What I am asking for is for someone to replicate the example and give the exact XML and/or SOAP with the post request (in the form of curl).

Here is the SOAP (straight from the guide)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:sas="urn:schemas-microsoft-com:xml-analysis">
<soapenv:Header/>
<soapenv:Body>
<sas:Execute>
<sas:Command>
<StoredProcess name="/WebServicesExamples/sampMeans">
<Parameter name="tablename">InData</Parameter>
<Stream name="instream">
<Table>
<InData>
<Column1>1</Column1>
<Column2>20</Column2>
<Column3>99</Column3>
</InData>
<InData>
<Column1>50</Column1>
<Column2>200</Column2>
<Column3>9999</Column3>
</InData>
<InData>
<Column1>100</Column1>
<Column2>2000</Column2>
<Column3>1000000</Column3>
</InData>
</Table>
</Stream>
</StoredProcess>
</sas:Command>
<sas:Properties>
<PropertyList>
<DataSourceInfo>Provider=SASSPS;</DataSourceInfo>
</PropertyList>
</sas:Properties>
</sas:Execute>
</soapenv:Body>
</soapenv:Envelope>

I am posting via curl. Here is my curl command

curl -H "Content-Type: text/xml" -X POST https://mycompany.com:port/SASBIWS/services/WebServicesExamples/sampMeans --data "@sampmeanssoap.xml"

But this produces the error

A 'Client' type of exception occurred during execution of 'WebServicesExamples/sampMeans' service. The exception follows: Expected stream 'instream' was not specified.

XML produces a similar response

<StoredProcess name="/WebServicesExamples/sampMeans">
 <Parameter name="tablename">InData</Parameter>
 <Stream name="instream">
 <Table>
 <InData>
 <Column1>1</Column1>
 <Column2>20</Column2>
 <Column3>99</Column3>
 </InData>
 <InData>
 <Column1>50</Column1>
 <Column2>200</Column2>
 <Column3>9999</Column3>
 </InData>
 <InData>
 <Column1>100</Column1>
 <Column2>2000</Column2>
 <Column3>1000000</Column3>
 </InData>
 </Table>
 </Stream>
 </StoredProcess>

With curl

curl -H "Content-Type: text/xml" -X POST https://mycompany.com:port/SASBIWS/rest/storedProcesses/WebServicesExamples/sampMeans --data-binary "@sampmeanssoap.xml"

I can successfully get stored processes to complete when using only parameters but am unable to send data sources for whatever reason.

Pramod Gharu
  • 1,105
  • 3
  • 9
  • 18
Ted Petrou
  • 59,042
  • 19
  • 131
  • 136

1 Answers1

4

Finally found an answer and posted it to SAS communities as well (https://communities.sas.com/t5/SAS-Stored-Processes/Help-with-XML-Syntax-for-post-request-to-Stored-Process/m-p/239032/highlight/false#M3304)

Unfortunately the documentation is sorely lacking of concrete examples of sending streams of data through plain XML. I was initially trying to just insert the plain XML part of the lone example SOAP request in the XMLA part of the documentation but my stream 'instream' was unable to be located.

The key to the solution was to look at the wsdl file (just append ?wsdl to the endpoint. ex: https://mycompany.com:port/SASBIWS/services/path/to/process/process_name?wsdl) I had gotten a simple addint stored process to return successfully and noticed that in my new stored process that the wsdl did not match the example in the developers guide. Here is the pertinent part of the wsdl for the stored process that streamed data.

<xsd:complexType name="upload_stream5Streams">
<xsd:sequence>
<xsd:element name="instream">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Value">
<xsd:complexType>
<xsd:sequence>

I needed separate elements for streams, instream, and Value, which is absolutely nowhere across the internet as far as I know.

Here is the complete XML

<upload_stream5>
<streams>
<instream>
<Value>
<Table>
 <InData >
 <Column1>1</Column1>
 <Column2>20</Column2>
 <Column3>99</Column3>
 </InData>
 <InData>
 <Column1>50</Column1>
 <Column2>200</Column2>
 <Column3>9999</Column3>
 </InData>
 <InData>
 <Column1>100</Column1>
 <Column2>2000</Column2>
 <Column3>1000000</Column3>
 </InData>
 </Table>
 </Value>
 </instream>
</streams>
</upload_stream5>

And here is the actual stored process sas code. Its a bit different than the developer's example because there is no _XMLSCHEMA macro variable. (tablename is defaulted to InData but you can pass this with XML as well using <parameters> and <parameter_name> tags)

%put &tablename;
libname otstream xml xmlmeta = SchemaData;
libname instream xml;
proc means data=instream.&tablename;
 output out=otstream.mean;
run;
libname otstream clear;
libname instream clear;
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Ted Petrou
  • 59,042
  • 19
  • 131
  • 136
  • What is the value of the macro variable TABLENAME? How does its values relate to the XML content you displayed? For example does TABLENAME=VALUE and correspond to the `...` block in the XML? Or is it INDATA and correspond tot the `...` block in the XML? Or is it something else? – Tom Dec 15 '15 at 15:06
  • tablename is defaulted to InData in the metadata (when you setup the stored process in the SAS Management Console stored process wizard). To explicitly put it in the xml just use the following: InData. To be clear: streams are completely different than parameters (they are differnent tabs in the stored process wizard) and they are completely different elements in the xml. – Ted Petrou Dec 15 '15 at 15:52