Google Groups Home
Help | Sign in
SOAP server. Handle by controller.
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  1 message - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
wDevil  
View profile
 More options Mar 27, 11:21 am
From: wDevil <wwde...@gmail.com>
Date: Thu, 27 Mar 2008 08:21:23 -0700 (PDT)
Local: Thurs, Mar 27 2008 11:21 am
Subject: SOAP server. Handle by controller.
I want to make SOAP service with WSDL generation like this
http://bakery.cakephp.org/articles/view/a-component-to-help-creating-...,
but with handle by controller like this
http://bakery.cakephp.org/articles/view/implementing-soap-on-cakephp.
With authorization.

app/controllers/components/soap.php
<?php
vendor('wshelper/lib/soap/IPReflectionClass.class');
vendor('wshelper/lib/soap/IPReflectionCommentParser.class');
vendor('wshelper/lib/soap/IPXMLSchema.class');
vendor('wshelper/lib/soap/IPReflectionMethod.class');
vendor('wshelper/lib/soap/WSDLStruct.class');
vendor('wshelper/lib/soap/WSDLException.class');

/**
 * Class SoapComponent
 *
 * Generate WSDL and handle SOAP calls
 */
class SoapComponent extends Component
{
    var $params = array();

    function initialize(&$controller)
    {
        $this->params = $controller->params;
    }

    /**
     * Get WSDL for specified model.
     *
     * @param string $modelClass : model name in camel case
     * @param string $serviceMethod : method of the controller that
will handle SOAP calls
     */
    function getWSDL($modelId, $serviceMethod = 'call')
    {
        $modelClass = $this->__getModelClass($modelId);
        $expireTime = '+1 year';
        $cachePath = $modelClass . '.wsdl';

        // Check cache if exist
        $wsdl = cache($cachePath, null, $expireTime);

        // If DEBUG > 0, compare cache modified time to model file
modified time
        if ((Configure::read() > 0) && (! is_null($wsdl))) {

            $cacheFile = CACHE . $cachePath;
            if (is_file($cacheFile)) {
                $modelMtime = filemtime($this-

>__getModelFile($modelId));

                $cacheMtime = filemtime(CACHE . $cachePath);
                if ($modelMtime > $cacheMtime) {
                    $wsdl = null;
                }
            }

        }

        // Generate WSDL if not cached
        if (is_null($wsdl)) {
                App::import('Controller',array($modelClass));
            $refl = new IPReflectionClass($this-

>__getFullNameClass($modelId));

            $controllerName = $this->params['controller'];
            $serviceURL = Router::url("/$controllerName/
$serviceMethod", true);

            $wsdlStruct = new WSDLStruct('http://
schema.example.com',
                                         $serviceURL . '/' .
$modelId,
                                         SOAP_RPC,
                                         SOAP_LITERAL);
            $wsdlStruct->setService($refl);
            try {
                $wsdl = $wsdlStruct->generateDocument();
                // cache($cachePath, $wsdl, $expireTime);
            } catch (WSDLException $exception) {
                if (Configure::read() > 0) {
                    $exception->Display();
                    exit();
                } else {
                    return null;
                }
            }
        }

        return $wsdl;
    }

    /**
     * Handle SOAP service call
     *
     * @param string $modelId : underscore notation of the called
model
     *                          without _service ending
     * @param string $wsdlMethod : method of the controller that will
generate the WSDL
     */
    function handle($modelId, $wsdlMethod = 'wsdl')
    {
        $modelClass = $this->__getModelClass($modelId);
        $wsdlCacheFile = CACHE . $modelClass . '.wsdl';

        // Try to create cache file if not exists
        if (! is_file($wsdlCacheFile)) {
            $this->getWSDL($modelId);
        }

        if (is_file($wsdlCacheFile)) {
            $server = new SoapServer($wsdlCacheFile);
        } else {
            $controllerName = $this->params['controller'];
            $wsdlURL = Router::url("/$controllerName/$wsdlMethod",
true);
            $server = new SoapServer($wsdlURL . '/' . $modelId);
        }
        //$server->setClass($modelClass."Controller");
        $server->setClass($controllerName.'Controller');
        $server->handle();
    }

    /**
     * Get model class for specified model id
     *
     * @access private
     * @return string : the model id
     */
    function __getModelClass($modelId)
    {
        $inflector = new Inflector;
        return ($inflector->camelize($modelId) . 'service');
    }

    function __getFullNameClass($modelId)
    {
        $inflector = new Inflector;
        return ($inflector->camelize($modelId) .
'serviceController');
    }

    /**
     * Get model file for specified model id
     *
     * @access private
     * @return string : the filename
     */
    function __getModelFile($modelId)
    {
        $modelDir = dirname(dirname(dirname(__FILE__))) . DS .
'controllers';
        return $modelDir . DS . $modelId . '_controller.php';
    }

}

?>

app/controllers/service_controller.php
<?php
class ServiceController extends AppController
{
    public $name = 'Service';
    public $uses = array();
    public $helpers = array();
    public $components = array('Soap');

    public function call()
    {
        CakeLog::write(LOG_DEBUG,'Begin worked with SOAP client
ServiceController::call');
        $this->autoRender = FALSE;
        $this->Soap->handle('order', 'wsdl');
    }

    public function wsdl()
    {
        CakeLog::write(LOG_DEBUG,'generate WSDL for SOAP client');
        $this->autoRender = FALSE;
        echo $this->Soap->getWSDL('order', 'call');
    }

     public function __call ( $func_name, $args ){
                CakeLog::write(LOG_DEBUG,'handle request in serviceController -  '.
$func_name);
        return $this->requestAction('/Orderservice'.'/'.
$func_name.'/', array('pass'=>$args) );
    }

}

?>

app/components/orderservice_controller.php
<?
class OrderserviceController extends AppController
{
        public $name = 'Orderservice';
        public $uses = array();
        public $components = array('Orderr');
        public $Orderr;

        /**
     *
     * @param string $xml
     * @return string
     */
        public function addOrder($xml)
        {
                CakeLog::write(LOG_DEBUG,'called addorder in class
orderserviceController ');
                $this->autoRender = false;

        }

        /**
     *
     * @param string $username
     * @param string $password
     * @return string
     */
        protected function UsernameToken( $username, $password ){
                CakeLog::write(LOG_DEBUG,'called UsernameToken in class
orderserviceController ');
    }

}

?>

Client.
Get from http://php.oregonstate.edu/manual/en/function.soap-soapserver-constru...

class SoapHeaderUsernameToken
{
    /** @var int Password */
    public $Password;
    /** @var int Username */
    public $Username;

    public function __construct($l, $p)
    {
        $this->Password = $p;
        $this->Username = $l;
    }

}

$client = new SoapClient('http://mm.ru/service/wsdl/', array('trace'
=> 1));
try {
            // Set the login headers
    $wsu = 'http://schemas.xmlsoap.org/ws/2002/07/utility';
    $usernameToken = new SoapHeaderUsernameToken('root', 'pass');
    $soapHeaders[] = new SoapHeader($wsu, 'UsernameToken',
$usernameToken);

        $client->__setSoapHeaders($soapHeaders);
        $result = $client->addOrder($xml);

} catch (SoapFault $fault) {
        var_dump($fault);
}

   echo "REQUEST:\n" . $client->__getLastRequest() . "\n";
  echo "RESPONSE:\n" . $client->__getLastResponse() . "\n";

Authorization method UsernameToken is not called and i don't know why.
Trace.

REQUEST:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:ns1="http://schema.example.com" xmlns:ns2="http://
schemas.xmlsoap.org/ws/2002/07/utility">
<SOAP-ENV:Header>
ns2:UsernameToken>
<Password>pass</Password>
<Username>root</Username>
</ns2:UsernameToken>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ns1:addOrder><xml>tra la la</xml>
</ns1:addOrder>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

RESPONSE:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:ns1="http://schema.example.com">
<SOAP-ENV:Body>
<ns1:addOrderResponse><addOrderReturn/>
</ns1:addOrderResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

In logs:
 Debug: generate WSDL for SOAP client
 Debug: Begin worked with SOAP client ServiceController::call
 Debug: handle request in serviceController -  addOrder
 Debug: called addorder in class orderserviceController

WSDL:
<?xml version="1.0"?>
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/
XMLSchema" xmlns:tns="http://schema.example.com"
targetNamespace="http://schema.example.com"><wsdl:types><xsd:schema
targetNamespace="http://schema.example.com"/></wsdl:types><message
name="addOrderRequest"><part name="xml" type="xsd:string"/></
message><message name="addOrderResponse"><part name="addOrderReturn"
type="xsd:string"/></message><wsdl:portType
name="OrderserviceControllerPortType"><wsdl:operation
name="addOrder"><wsdl:input message="tns:addOrderRequest"/

><wsdl:output message="tns:addOrderResponse"/></wsdl:operation></

wsdl:portType><binding name="OrderserviceControllerBinding"
type="tns:OrderserviceControllerPortType"><soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation
name="addOrder"><soap:operation soapAction="http://mm.ru/service/call/
order&amp;method=addOrder" style="rpc"/><wsdl:input><soap:body
use="literal" namespace="http://schema.example.com"/></
wsdl:input><wsdl:output><soap:body use="literal" namespace="http://
schema.example.com"/></wsdl:output></wsdl:operation></
binding><wsdl:service name="OrderserviceController"><wsdl:port
name="OrderserviceControllerPort"
binding="tns:OrderserviceControllerBinding"><soap:address
location="http://mm.ru/service/call/order"/></wsdl:port></
wsdl:service></wsdl:definitions>
<!-- 0.4944s -->

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google