Discussion:
SCA Webservice in WSDL mode
Dalibor Andzakovic
2008-01-25 00:28:51 UTC
Permalink
Hi All,

I Have a problem running consuming SCA exposed as a webservice. If i
create a SCA client based on a local file i get expected behaviour,
however if i create it based on generated WSDL i get
SDO_UnsupportedOperationException: createDocument - cannot find
element.

Any tips would be greatly appreciated.


Following code works:

$weather = SCA::getService('servicetest4.php');
var_dump($weather->sayHello('dali'));

Following doesn't :-(

$weather = SCA::getService('http://localhost/ihug/servicetest4.php?
wsdl', 'soap', array('location' => 'http://localhost/ihug'));
var_dump($weather->sayHello('dali'));

below is the complete servicetest.php
<?php
require_once 'SCA/SCA.php';

/**
* SCA SOAP test
*
* @service
* @binding.soap
*
* @types http://Weather Temperatures.xsd
*/
class servicetest4 {

/**
* Class constructor
*
*/
public function __construct()
{
// Some Constructor
}

/**
* Say Hello to Somebody
* @param string $who
* @return string
*/
public function sayHello($who)
{
return "Hello $who";
}

/**
* Something to return an object
*
* @param string $foo
* @return Temperatures http://Weather
*/
public function returnObject($foo)
{
$Temperatures = SCA::createDataObject('http://Weather',
'Temperatures');
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'CA';
$Pair->temperature = 65;
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'UT';
$Pair->temperature = 105;
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'ND';
$Pair->temperature = -20;
return $Temperatures;
}


private function doSomething()
{
// Some Private Method
}
}
?>
Matthew Peters
2008-01-25 09:23:37 UTC
Permalink
Hi Dan,
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.

Matthew
Post by Dalibor Andzakovic
Hi All,
I Have a problem running consuming SCA exposed as a webservice. If i
create a SCA client based on a local file i get expected behaviour,
however if i create it based on generated WSDL i get
SDO_UnsupportedOperationException: createDocument - cannot find
element.
Any tips would be greatly appreciated.
$weather = SCA::getService('servicetest4.php');
var_dump($weather->sayHello('dali'));
Following doesn't :-(
$weather = SCA::getService('http://localhost/ihug/servicetest4.php?
wsdl', 'soap', array('location' => 'http://localhost/ihug'));
var_dump($weather->sayHello('dali'));
below is the complete servicetest.php
<?php
require_once 'SCA/SCA.php';
/**
* SCA SOAP test
*
*
*/
class servicetest4 {
/**
* Class constructor
*
*/
public function __construct()
{
// Some Constructor
}
/**
* Say Hello to Somebody
*/
public function sayHello($who)
{
return "Hello $who";
}
/**
* Something to return an object
*
*/
public function returnObject($foo)
{
$Temperatures = SCA::createDataObject('http://Weather',
'Temperatures');
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'CA';
$Pair->temperature = 65;
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'UT';
$Pair->temperature = 105;
$Pair = $Temperatures->createDataObject('entry');
$Pair->state = 'ND';
$Pair->temperature = -20;
return $Temperatures;
}
private function doSomething()
{
// Some Private Method
}}
?>
Dalibor Andzakovic
2008-01-27 21:29:10 UTC
Permalink
Post by Matthew Peters
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.
Hi Matthew,

thanks for looking at this.

XSD below:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Weather"
elementFormDefault="qualified">

<xs:complexType name="PairType">
<xs:sequence>
<xs:element name="state" type="xs:string"/>
<xs:element name="temperature" type="xs:float"/>
</xs:sequence>
</xs:complexType>

<xs:element name="Temperatures">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns1:PairType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>
Matthew Peters
2008-01-29 14:31:32 UTC
Permalink
Hmmm. I tried this out, started putting in a few debug lines, saw
exactly the same message you did, and then it went away and won't come
back :-). Here is what is currently working for me:

<?
include "SCA/SCA.php";
$weather = SCA::getService('servicetest.php');
var_dump($weather->sayHello('dali'));

//$wsdl = file_get_contents('http://localhost/bugs/bug/servicetest.php?
wsdl');
//file_put_contents('./servicetest.wsdl',$wsdl);
//$weather = SCA::getService('./servicetest.wsdl');

$weather = SCA::getService('http://localhost/bugs/bug/servicetest.php?
wsdl','soap',array('location' => 'http://localhost/bugs/bug/
servicetest.php'));
var_dump($weather->sayHello('dali'));
?>

where I have renamed your servicetest4 to servicetest and as you can
see I have the files under htdocs at bugs/bug rather than ihug.

You'll see the three lines I have commented out where I get the wsdl
explicitly in one step, and write it into the directory where both the
test script and the server script are located. This is what I always
do and always works for me - write the wsdl out to a file. I suspect
there is something vulnerable about using http://... in the getService
call itself that we have never pinned down - it ought to work but
sometimes doesn't. The server end writes out wsdl itself if it finds
that there is none in the directory beside itself, and I think it's
possible for the wsdl at either end to get out of step if you don't
write it out explicitly.

Let me know how you get on.

Matthew
Post by Dalibor Andzakovic
Post by Matthew Peters
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.
Hi Matthew,
thanks for looking at this.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Weather"
elementFormDefault="qualified">
<xs:complexType name="PairType">
<xs:sequence>
<xs:element name="state" type="xs:string"/>
<xs:element name="temperature" type="xs:float"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Temperatures">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns1:PairType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Dalibor Andzakovic
2008-01-30 20:29:28 UTC
Permalink
I managed to get it going at my end too. It seemed to be the @types
annotation that was causing grief.

In the process we've had to change SCA/Bindings/soap/
ServiceDescriptionGenerator.php to output <wsdl:types> tags instead of
<types>, but that could just be interop issues.

dali
Post by Matthew Peters
Hmmm. I tried this out, started putting in a few debug lines, saw
exactly the same message you did, and then it went away and won't come
<?
include "SCA/SCA.php";
$weather = SCA::getService('servicetest.php');
var_dump($weather->sayHello('dali'));
//$wsdl = file_get_contents('http://localhost/bugs/bug/servicetest.php?
wsdl');
//file_put_contents('./servicetest.wsdl',$wsdl);
//$weather = SCA::getService('./servicetest.wsdl');
$weather = SCA::getService('http://localhost/bugs/bug/servicetest.php?
wsdl','soap',array('location' => 'http://localhost/bugs/bug/
servicetest.php'));
var_dump($weather->sayHello('dali'));
?>
where I have renamed your servicetest4 to servicetest and as you can
see I have the files under htdocs at bugs/bug rather than ihug.
You'll see the three lines I have commented out where I get the wsdl
explicitly in one step, and write it into the directory where both the
test script and the server script are located. This is what I always
do and always works for me - write the wsdl out to a file. I suspect
there is something vulnerable about using http://... in the getService
call itself that we have never pinned down - it ought to work but
sometimes doesn't. The server end writes out wsdl itself if it finds
that there is none in the directory beside itself, and I think it's
possible for the wsdl at either end to get out of step if you don't
write it out explicitly.
Let me know how you get on.
Matthew
Post by Dalibor Andzakovic
Post by Matthew Peters
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.
Hi Matthew,
thanks for looking at this.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Weather"
elementFormDefault="qualified">
<xs:complexType name="PairType">
<xs:sequence>
<xs:element name="state" type="xs:string"/>
<xs:element name="temperature" type="xs:float"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Temperatures">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns1:PairType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Matthew Peters
2008-01-31 18:21:04 UTC
Permalink
Dali, I am glad you told us about this in the first place as you had
uncovered a bad bug.

First of all, I made a silly mistake - I had forgotten that I too had
removed the @types annotation and that was why it had now started
working for me. As soon as I put the @types annotation back in it
started to fail again.

It is caused a rather brittle bit of code where we have to scan a bit
of human-readable output deep inside SCA. I am not sure how long it
has been broken for, nor exactly in which cases the error occurs - it
depends on the order in which something is printed.

Anyway, I have a fix for this which I have checked in to the FULMAR
branch. I include the two changes here in case you want to apply them;

1. Fix Bindings/soap/Mapper.php by replacing the last method,
getAllTypes with this:
public function getAllTypes()
{
$str = $this->xmldas->__toString();
$types = array();
$line = strtok($str, self::EOL);
$line = strtok(self::EOL); // skip line that says this is
an SDO
$line = strtok(self::EOL); // skip line that says nn types
have been defined

while ($line !== false && strpos($line,'commonj.sdo')) {
$line = strtok(self::EOL);
}
while ($line !== false && $line != '}') {
$trimmed_line = trim($line);
$words = explode(' ', $trimmed_line);
if ($words[0] == '-') {
$line = strtok(self::EOL);
continue;
}
$namespace_and_type = $words[1];
$pos_last_hash = strrpos($namespace_and_type,
'#');
$namespace = substr($namespace_and_type, 0,
$pos_last_hash);
$type = substr($namespace_and_type,
$pos_last_hash+1);
if ($type != 'RootType') {
$types[] = array($namespace, $type);
}
$line = strtok(self::EOL);
}
return $types;
}

2. In Bindings/soap/Wrapper.php
2.1 Add an instance variable
private $class_name = null;

2.2 Initalise it in the constructor
$this->class_name = $class_name;

2.3 Use it inside the __call method at the bottom...replace
$xdoc = $this->xmldas->createDocument($method_name .
"Response");
with
$namespace = 'http://' . $this->class_name;
$xdoc = $this->xmldas->createDocument($namespace,
$method_name . "Response");

We will make a release with FULMAR soon. I can just zip up the SCA
directory and send it to you if you like.

We also have the fix for <wsdl:types> that you saw.

Matthew
Post by Dalibor Andzakovic
annotation that was causing grief.
In the process we've had to change SCA/Bindings/soap/
ServiceDescriptionGenerator.php to output <wsdl:types> tags instead of
<types>, but that could just be interop issues.
dali
Post by Matthew Peters
Hmmm. I tried this out, started putting in a few debug lines, saw
exactly the same message you did, and then it went away and won't come
<?
include "SCA/SCA.php";
$weather = SCA::getService('servicetest.php');
var_dump($weather->sayHello('dali'));
//$wsdl = file_get_contents('http://localhost/bugs/bug/servicetest.php?
wsdl');
//file_put_contents('./servicetest.wsdl',$wsdl);
//$weather = SCA::getService('./servicetest.wsdl');
$weather = SCA::getService('http://localhost/bugs/bug/servicetest.php?
wsdl','soap',array('location' => 'http://localhost/bugs/bug/
servicetest.php'));
var_dump($weather->sayHello('dali'));
?>
where I have renamed your servicetest4 to servicetest and as you can
see I have the files under htdocs at bugs/bug rather than ihug.
You'll see the three lines I have commented out where I get the wsdl
explicitly in one step, and write it into the directory where both the
test script and the server script are located. This is what I always
do and always works for me - write the wsdl out to a file. I suspect
there is something vulnerable about using http://... in the getService
call itself that we have never pinned down - it ought to work but
sometimes doesn't. The server end writes out wsdl itself if it finds
that there is none in the directory beside itself, and I think it's
possible for the wsdl at either end to get out of step if you don't
write it out explicitly.
Let me know how you get on.
Matthew
Post by Dalibor Andzakovic
Post by Matthew Peters
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.
Hi Matthew,
thanks for looking at this.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Weather"
elementFormDefault="qualified">
<xs:complexType name="PairType">
<xs:sequence>
<xs:element name="state" type="xs:string"/>
<xs:element name="temperature" type="xs:float"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Temperatures">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns1:PairType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Dalibor Andzakovic
2008-02-04 03:41:42 UTC
Permalink
Glad to be of service :-)

I've applied the below fixes to my dev enviroment, but it sure would
be nice to get them into an official release. It would make app
maintenance a lot easier..

dali
Post by Matthew Peters
Dali, I am glad you told us about this in the first place as you had
uncovered a bad bug.
First of all, I made a silly mistake - I had forgotten that I too had
started to fail again.
It is caused a rather brittle bit of code where we have to scan a bit
of human-readable output deep inside SCA. I am not sure how long it
has been broken for, nor exactly in which cases the error occurs - it
depends on the order in which something is printed.
Anyway, I have a fix for this which I have checked in to the FULMAR
branch. I include the two changes here in case you want to apply them;
1. Fix Bindings/soap/Mapper.php by replacing the last method,
public function getAllTypes()
{
$str = $this->xmldas->__toString();
$types = array();
$line = strtok($str, self::EOL);
$line = strtok(self::EOL); // skip line that says this is
an SDO
$line = strtok(self::EOL); // skip line that says nn types
have been defined
while ($line !== false && strpos($line,'commonj.sdo')) {
$line = strtok(self::EOL);
}
while ($line !== false && $line != '}') {
$trimmed_line = trim($line);
$words = explode(' ', $trimmed_line);
if ($words[0] == '-') {
$line = strtok(self::EOL);
continue;
}
$namespace_and_type = $words[1];
$pos_last_hash = strrpos($namespace_and_type,
'#');
$namespace = substr($namespace_and_type, 0,
$pos_last_hash);
$type = substr($namespace_and_type,
$pos_last_hash+1);
if ($type != 'RootType') {
$types[] = array($namespace, $type);
}
$line = strtok(self::EOL);
}
return $types;
}
2. In Bindings/soap/Wrapper.php
2.1 Add an instance variable
private $class_name = null;
2.2 Initalise it in the constructor
$this->class_name = $class_name;
2.3 Use it inside the __call method at the bottom...replace
$xdoc = $this->xmldas->createDocument($method_name .
"Response");
with
$namespace = 'http://' . $this->class_name;
$xdoc = $this->xmldas->createDocument($namespace,
$method_name . "Response");
We will make a release with FULMAR soon. I can just zip up the SCA
directory and send it to you if you like.
We also have the fix for <wsdl:types> that you saw.
Matthew
Post by Dalibor Andzakovic
annotation that was causing grief.
In the process we've had to change SCA/Bindings/soap/
ServiceDescriptionGenerator.php to output <wsdl:types> tags instead of
<types>, but that could just be interop issues.
dali
Post by Matthew Peters
Hmmm. I tried this out, started putting in a few debug lines, saw
exactly the same message you did, and then it went away and won't come
<?
include "SCA/SCA.php";
$weather = SCA::getService('servicetest.php');
var_dump($weather->sayHello('dali'));
//$wsdl = file_get_contents('http://localhost/bugs/bug/servicetest.php?
wsdl');
//file_put_contents('./servicetest.wsdl',$wsdl);
//$weather = SCA::getService('./servicetest.wsdl');
$weather = SCA::getService('http://localhost/bugs/bug/servicetest.php?
wsdl','soap',array('location' => 'http://localhost/bugs/bug/
servicetest.php'));
var_dump($weather->sayHello('dali'));
?>
where I have renamed your servicetest4 to servicetest and as you can
see I have the files under htdocs at bugs/bug rather than ihug.
You'll see the three lines I have commented out where I get the wsdl
explicitly in one step, and write it into the directory where both the
test script and the server script are located. This is what I always
do and always works for me - write the wsdl out to a file. I suspect
there is something vulnerable about using http://... in the getService
call itself that we have never pinned down - it ought to work but
sometimes doesn't. The server end writes out wsdl itself if it finds
that there is none in the directory beside itself, and I think it's
possible for the wsdl at either end to get out of step if you don't
write it out explicitly.
Let me know how you get on.
Matthew
Post by Dalibor Andzakovic
Post by Matthew Peters
Thanks for trying SCA and for telling us about the problem. Please
would you put up the Temperatures.xsd as well? I'll look at it
straight away.
Hi Matthew,
thanks for looking at this.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Weather"
elementFormDefault="qualified">
<xs:complexType name="PairType">
<xs:sequence>
<xs:element name="state" type="xs:string"/>
<xs:element name="temperature" type="xs:float"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Temperatures">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns1:PairType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Loading...